1. 程式人生 > >Linux裝置驅動模型框架分析(三)——LDDM的實體bus_type、device和device_driver

Linux裝置驅動模型框架分析(三)——LDDM的實體bus_type、device和device_driver

Linux裝置模型中,Bus(匯流排)是一類特殊的裝置,它是連線處理器和其它裝置之間的通道(channel)。為了方便裝置模型的實現,核心規定,系統中的每個裝置都要連線在一個Bus上,這個Bus可以是一個內部Bus、虛擬Bus或者Platform Bus

devicedevice driverLinux驅動開發的基本概念。Linux kernel的思路很簡單:驅動開發,就是要開發指定的軟體(driver)以驅動指定的裝置,所以kernel就為裝置和驅動它的driver定義了兩個資料結構,分別是devicedevice_driver(本文以http://www.wowotech.net/device_model/device_and_driver.html,http://www.wowotech.net/device_model/bus.html為基礎,結合自己的理解和4.1核心的修改)。

bus_type

核心通過struct bus_type結構,抽象Bus

 

name,該bus的名稱,會在sysfs中以目錄的形式存在,如platform bussysfs中表現為"/sys/bus/platform”。

dev_name,該名稱和下面講到的struct device結構中的init_name有關。對有些裝置而言,允許將裝置的名字留空。這樣當設備註冊到核心後,裝置模型的核心邏輯就會用"bus->dev_name+device ID”的形式,為這樣的裝置生成一個名稱。

dev_attrs,被下邊的groups取代

bus_groupsdev_groupsdrv_groups

,一些預設的attribute,可以在busdevice或者device_driver新增到核心時,自動為它們新增相應的attribute

dev_rootdev_root裝置為bus的預設父裝置(Default device to use as the parent),但在核心實際實現中,和一個叫sub system的功能有關。

match,一個由具體的bus driver實現的回撥函式。當任何屬於該Busdevice或者device_driver新增到核心時,核心都會呼叫該介面,如果新加的devicedevice_driver匹配上了彼此的話,該介面要返回非零值,此時Bus模組的核心邏輯就會執行後續的處理。

uevent,一個由具體的bus driver實現的回撥函式。當任何屬於該Busdevice,發生新增、移除或者其它動作時,Bus模組的核心邏輯就會呼叫該介面,以便bus driver能夠修改環境變數。

proberemove,這兩個回撥函式,和device_driver中的非常類似,但它們的存在是非常有意義的。可以想象一下,如果需要probe(其實就是初始化)指定的device話,需要保證該device所在的bus是被初始化過、確保能正確工作的。這就要就在執行device_driverprobe前,先執行它的busproberemove的過程相反。

並不是所有的bus都需要proberemove介面的,因為對有些bus來說(例如platform bus),它本身就是一個虛擬的匯流排,無所謂初始化,直接就能使用,因此這些busdriver就可以將這兩個回撥函式留空。

shutdownsuspendresume,和proberemove的原理類似,電源管理相關的實現。

onlineoffline,和屬於這個匯流排裝置的online屬性相關。

pm,電源管理相關的邏輯。

iommu_ops,匯流排的IOMMU相關操作,IOMMUMMU功能類似,可以給裝置一個核心空間的地址(或叫匯流排地址),而不限於可以直接訪問的常規記憶體區域。

p,一個struct subsys_private型別的指標,kobject隱藏在這個結構後面。這個結構也很重要。

device

 

device結構很複雜,這裡將會選一些對理解裝置模型非常關鍵的欄位進行說明。

parent,該裝置的父裝置,一般是該裝置所從屬的buscontroller等裝置。

p,一個用於裝置的私有資料結構指標,儲存子裝置連結串列,新增父節點,鄰居節點和匯流排連結串列等。

kobj,該資料結構對應的struct kobject

init_name,該裝置的名稱。

在裝置模型中,名稱是一個非常重要的變數,任何註冊到核心中的裝置,都必須有一個合法的名稱,可以在初始化時給出,也可以由核心根據bus name + device ID”的方式創造。見bus_type.dev_name的說明。

typestruct device_type結構是新版本核心新引入的一個結構,它和struct device關係,非常類似stuct kobj_typestruct kobject之間的關係。

bus,該device屬於哪個匯流排。

driver,該device對應的device driver

platform_data,一個指標,用於儲存具體的平臺相關的資料。linux經常用來儲存一些單板相關的資料,來描述包含哪些裝置,以及它們如何互聯。以便大幅減少BSP的程式碼量和驅動中ifdef的使用。

powerpm_domain,電源管理相關的邏輯,後續會由電源管理專題講解。

pins"PINCTRL”功能。

numa_node"NUMA”功能。

devt,裝置號。在這裡,該變數主要用於在sys檔案系統中,為每個具有裝置號的device,建立/sys/dev/*下的對應目錄,如下:



class,該裝置屬於哪個class。這從側面說明了classdevice的集合。

groups,該裝置的預設attribute集合。將會在設備註冊時自動在sysfs中建立對應的檔案。

device_driver

 

name,該driver的名稱。和device結構一樣,該名稱非常重要,和devicedriver的匹配有關。

bus,該driver所驅動裝置的匯流排裝置。核心要保證在driver執行前,裝置所依賴的匯流排能夠正確初始化。

ownermod_name,核心module相關的變數。

suppress_bind_attrs,通過sysfs啟用bindunbindattribute,如下:

# ls /sys/bus/platform/drivers/switch-gpio/                                                  

    bind   uevent    unbind

kernel中,bind/unbind是從使用者空間手動的為driver繫結/解繫結指定的裝置的機制。

proberemove,這兩個介面函式用於實現driver邏輯的開始和結束。在裝置模型的結構下,只有driverdevice同時存在時,才需要開始執行driver的程式碼邏輯。這也是proberemove兩個介面名稱的由來:檢測到了裝置和移除了裝置(就是為熱拔插起的!)。

shutdownsuspendresumepm,電源管理相關的內容。

groups,和struct device結構中的同名變數類似,driver也可以定義一些預設attribute,這樣在將driver註冊到核心中時,核心裝置模型部分的程式碼會自動將這些attribute新增到sysfs中。

p,私有資料的指標。

subsys_private

舊的linux存在獨立的子系統資料結構subsystem2.6.35拋棄了這個資料結構。轉而用subsys_private表示。

什麼是子系統?無論是bus,還是class,還是一些虛擬的子系統,它都構成了一個“子系統(sub-system)”,該子系統會包含形形色色的devicedevice_driver,就像一個獨立的王國一樣,存在於核心中。而這些子系統的表現形式,就是/sys/bus(或/sys/class,或其它)目錄下面的子目錄,每一個子目錄,都是一個子系統(如/sys/bus/spi/)。從子系統的角度看bus和後面的class很類似,它們都用subsys_private表示子系統。

 

subsysdevices_ksetdrivers_kset是三個kset。其中subsys,代表了本bus(如/sys/bus/spi),它下面可以包含其它的kset或者其它的kobjectdevices_ksetdrivers_kset則是bus下面的兩個kset(如/sys/bus/spi/devices/sys/bus/spi/drivers),分別包括本bus下所有的devicedevice_driverbus_typekobject的關係通過subsys成員體現。通過巨集to_subsys_private(obj)可以看出。

interface用於儲存該bus下所有的interfaceinterface抽象了此類子系統的專有功能。

klist_devicesklist_drivers,分別儲存了本bus下所有的devicedevice_driver的指標,以方便查詢。

drivers_autoprobe,用於控制該bus下的drivers或者device是否自動probe

busclass,分別儲存上層的bus或者class指標。

device_private

 

klist_childre,包含此裝置所有的子裝置。

knode_parent,連入父裝置的klist_children時所用的節點。

knode_driver,連入驅動的裝置連結串列所用的節點,driver_privateklist_devices節點。

knode_bus,連入匯流排的裝置連結串列時所用的節點,subsys_privateklist_devices的節點。

deferred_probedeferred_probe_list的入口,deferred_probe_list用來重新繫結那些暫時不能獲得device全部資源的驅動,這種情況常常是因為某一個驅動需要另一個驅動首先probe

device,指向包含device_privatedevice

driver_private

 

kboj,結構對應的kobject

klist_devices,包含此驅動可以驅動的裝置。

knode_bus,連入bus的驅動連結串列的節點,代表subsys_privateklist_drivers的節點。

mkobj,核心module相關變數。

driver,指向包含driver_privatedriver

device_type

 

name,表示該型別的名稱,當該型別的裝置新增到核心時,核心會發出"DEVTYPE=name’”型別的uevent,告知使用者空間某個型別的裝置available了。

groups,該型別裝置的公共attribute集合。設備註冊時,會同時註冊這些attribute。這就是面向物件中“繼承”的概念。

uevent,所有相同型別的裝置,會有一些共有的uevent需要傳送,由該介面實現。

release,如果device結構沒有提供release介面,就要查詢它所屬的type是否提供,用於釋放device變數所佔的空間。

bus_typedevicedevice_driverkobject的關係

devicedevice_driver的角度看

 

devicedevice_driver直接繼承kobjectbus_type通過subsys_privatekobject發生聯絡。圖中ksetkobject的關係是從kset與包含在它裡邊的kobject的角度看的,與前面ksetkobjcet的關係角度不同。由此可見,匯流排、裝置和驅動是建立在kobject基礎上的,藉由kobjectkset建立層次關係。

bus_typedevicedevice_driver的關係

 

一個device_driver可以支援多個devicebus_type通過subsys_privatedevice_driverdevice發生關聯。

bus_typedevicedevice_driversysfs的關係

匯流排,裝置和裝置驅動與sysfs的對應關係相對簡單直觀。

核心資料結構或成員

sysfs對應表現形式

bus_type.name

/sys/bus下的目錄名

bus_type.dev_name

裝置委託給匯流排給其一個名字,如果裝置沒有起名,與device_id一起作為/sys/devices下的目錄名

device.name

/sys/devices下的目錄名

driver.name

/sys/devices下的目錄名


相關推薦

Linux裝置驅動模型框架分析——LDDM實體bus_typedevicedevice_driver

在Linux裝置模型中,Bus(匯流排)是一類特殊的裝置,它是連線處理器和其它裝置之間的通道(channel)。為了方便裝置模型的實現,核心規定,系統中的每個裝置都要連線在一個Bus上,這個Bus可以是一個內部Bus、虛擬Bus或者Platform Bus。 device

Linux裝置驅動模型框架分析——LDDM的展現:sysfs

sysfs是一個基於RAM的檔案系統,它和kobject一起,可以將Kernel的資料結構匯出到使用者空間,以檔案目錄結構的形式,提供對這些資料結構(以及資料結構的屬性)的訪問支援。 sysfs目錄 所包含內容 /sys/devices 這是核心對系統中所有

linux裝置驅動模型架構分析——概述

概述 LDD3中說:“Linux核心需要一個對系統結構的一般性描述。”這個描述就是linux裝置驅動模型(下面簡稱為LDDM)。LDDM不是獨立存在,其體系如下圖所示: LDDM體系結構 對架構的每一部分本文都會開闢獨立的章節進行描述。暫且拋開這個架構,首先從總體上了

【原創】Linux PCI驅動框架分析

# 背 景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器 3. 使用工具:Source Insight

linux裝置驅動模型架構分析

概述LDD3中說:“Linux核心需要一個對系統結構的一般性描述。”這個描述就是linux裝置驅動模型(下面簡稱為LDDM)。LDDM不是獨立存在,其體系如下圖所示:對架構的每一部分本文都會開闢獨立的章節進行描述。暫且拋開這個架構,首先從總體上了解一下LDDM。LDDM與驅動

Linux驅動》iTop4412開發板LCD驅動 詳細分析

接下來我們來詳解介紹probe中的函式: 第一個函式: s3cfb_set_lcd_info(fbdev[i]); 1.該函式原始碼如下: /*該函式在s3cfb_wa101s.c 中*/ /* name should be fixed as

字元裝置驅動核心框架小結

最近一直在學習驅動相關知識,但是如果說會用或者簡單的會寫的話我還不是很滿足,我還是想知道它底層是如何實現的。那閒話少說,最近也看了很多大牛的經驗總結,然後也就談談自己的看法吧~ 首先還是先列個大綱: 1、VFS如何實現; 2、字元裝置驅動框架; 一、VFS(

flume:常見sourcechannelsink總結

一、核心關注點 因為flume版本不同,source、channel和sink的介面都是不一樣的,所以需要使用對應版本的介面。 本文以flume1.6.0為例,參考http://archive.cloudera.com/cdh5/cdh/5/flume-ng-1.6.0-c

MySQL優化系列--索引的使用原理設計優化

之前的文章一直在規避索引的建立去優化資料庫,不是不想講,而是這個太重要,必須抽出來講。今天我們就來研究下資料庫索引的設計與優化(MySQL為例)。 文章結構:(1)索引的概述和使用;(2)索引的基本原理;(3)索引分類;(4)索引設計優化

javascript 面向物件學習——this,bindapply call

this 是 js 裡繞不開的話題,也是非常容易混淆的概念,今天試著把它理一理。 this 在非嚴格模式下,總是指向一個物件,在嚴格模式下可以是任意值,本文僅考慮非嚴格模式。記住它總是指向一個物件對於理解它的意義很重要。this 在實際使用中,大致分為以下幾種情況: 1. 函式作為物件的方法呼叫時,this

linux裝置驅動模型 - 驅動框架

linux驅動模型框架如圖所示: 1. kernfs 驅動最終是提供給使用者層使用,那麼其中的介面就是通過kernfs檔案系統來註冊,kernfs是一個通用的核心虛擬檔案系統 2. sysfs/kobject sysfs是裝置驅動檔案系統,裝置之間的各種關係會在在/

Linux裝置驅動程式架構分析之I2C架構基於3.10.1核心

作者:劉昊昱  核心版本:3.10.1 I2C體系架構的硬體實體包括兩部分: 硬體I2C Adapter:硬體I2C Adapter表示一個硬體I2C介面卡,也就是I2C控制器。一般是SOC中的一個介面,也可以用GPIO模擬。硬體I2C Adapter主要用來在I2

Linux裝置驅動程式架構分析之MMC/SD

作者:劉昊昱  核心版本:3.10.1 一、s3cmci_ops分析 在上一篇文章中我們分析了Mini2440 MMC/SD驅動的probe函式s3cmci_probe。在該函式中初始化了struct mmc_host指標變數mmc,其中,設定mmc->ops為s

Linux裝置驅動程式架構分析之platform基於3.10.1核心

作者:劉昊昱  核心版本:3.10.1 一、platform bus的註冊 platform bus註冊是通過platform_bus_init函式完成的,該函式定義在drivers/base/platform.c檔案中,其內容如下: 904int __init pl

Linux裝置驅動模型簡述原始碼剖析

 1. Linux裝置驅動模型和sysfs檔案系統 Linux核心在2.6版本中引入裝置驅動模型,簡化了驅動程式的編寫。Linux裝置驅動模型包含裝置(device)、匯流排(bus)、類(class)和驅動(driver),它們之間相互關聯。其中裝置(device)和驅動(driver)通過匯流排

【原創】Linux PCI驅動框架分析

# 背 景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器 3. 使用工具:Source Insight

linux驅動開發之蜂鳴器驅動源碼分析

linux 蜂鳴器 驅動 蜂鳴器的驅動源碼在/driver/char/buzzer/x210-buzzer.c文件中,源碼如下#include <linux/module.h> #include <linux/kernel.h> #include <linux

Linux入侵分析清理木馬問題用戶

入侵分析 雲安全 清除木馬 安全加固 Linux 1.查看哪些用戶擁有/bin/bash權限 cat /etc/passwd 2.檢查常用命令是否被篡改 (1)找到命令文件的路徑(whereis和which) whereis netstat which netstat which net

linux裝置驅動模型 - regmap

1. regmap介紹 regmap主要是為了方便操作暫存器而設計的,它將所有模組的暫存器(包括soc上模組的暫存器和外圍裝置的暫存器等) 抽象出來,用一套統一介面來操作暫存器 比如,如果要操作i2c裝置的暫存器,那麼就要呼叫i2c_transfer介面,要操作spi裝置的暫存

linux裝置驅動模型 - device/bus/driver

在linux驅動模型中,為了便於管理各種裝置,我們把不同裝置分別掛在他們對應的總線上,裝置對應的驅動程式也在總線上找,這樣就提出了deivce-bus-driver的模型,硬體上有許多裝置匯流排,那麼我們就在裝置模型上抽象出bus概念,相應的device就代表裝置,driver表示驅動,