1 底層機制
linux 的裝置驅動模型的底層機制主要包括:kobject,kobj_type,kset 等幾個結構。這幾個
結構的定義在include/linux/kobject.h 中。
1.1 kobject 代表裝置驅動模型中乙個基本物件,類似於mfc 中最頂層的基類cobject。每個kobject 都對應於sysfs 中的乙個目錄。上層結構例如device,device_driver,bus_type 都嵌入了乙個kobject,這相當於物件導向程式設計語言中的繼承機制
1.2 kobj_type是kobject 所屬的型別,定義了某種型別的kobejct 的公共的屬性和操作
1.3 kset 是乙個kobject 集合(或容器),包含了一系列的kobject。需要注意的是,kset 內部也嵌入了kobject,這表明kset 本身也是乙個kobject
2 高層資料結構
高層主要包括三個結構:device,device_driver,bus_type 。這幾個結構的定義在
include/linux/device.h 中。
2.1 device代表乙個裝置,對應於/sys/devices/下的乙個目錄
2.2 device_driver代表乙個裝置驅動程式,對應於/sys/bus/***/drivers/下的乙個目錄
2.3 bus_type代表乙個匯流排,對應於/sys/bus/下的乙個目錄。
2.4 match()方法用於判斷掛在匯流排下的某個device 和某個device_driver 是否匹配,在乙個
device 或乙個device_driver 註冊到匯流排上時呼叫。uevnet()方法用於為uevent 機制新增環境變數,在處理uevent 時被呼叫。其它方法都是操作匯流排上掛接的device 的
2.5 probe(),remove(),shutdown(),suspend(),resume()這幾個方法在device_driver 中也定
義了。核心在呼叫這些方法時,會優先呼叫bus_type 中定義的方法。如果相應的方法在
bus_type 中未定義,才會去呼叫device_driver 中定義的方法。
3 bus_type、device 和device_driver 之間的關係
3.1 bus_type 相當於乙個容器,是device 和device_driver 的管理機構,它包含了乙個device 集合(kset)和乙個device_driver 集合(kset),分別表示掛在這個匯流排下的所有裝置和所有裝置驅動程式。
3.2 device_driver 掛在某個bus_type 下面,包含了乙個device 集合(kset),表示這個驅動程式操作(或控制)的所有裝置。device_driver 還包含乙個bus_type 指標,表示驅動程式所在的匯流排。
3.3 device 掛在某個bus_type 下面,包含了乙個device_driver 指標,表示這個裝置對應的裝置驅動程式。device 還包含乙個bus_type 指標,表示裝置所在的匯流排。需要說明的是,乙個實際的匯流排在裝置驅動模型中是用兩個結構表示的:bus_type 和device。bus_type 代表匯流排型別,出現在/sys/bus/目錄下;device 代表匯流排裝置,出現在/sys/devices/
目錄下,這表明實際的匯流排本質上是一種裝置。
4在匯流排中新增和刪除裝置的過程:
(1) 裝置新增
device_register(dev)->device_add(dev)-> kobject_uevent(kobj_add)
device_add(dev)->bus_attach_device(dev)->device_attach(dev)
->__device_attach(drv,dev)->bus_type():match(dev,drv)
then ->driver_probe_device()->really_probe()
->bus_type:probe()或device_driver:probe()
(2) 裝置刪除
device_unregister(dev)->device_del(dev)->bus_remove_device(dev)
->device_release_driver(dev)
->__ device_release_driver(dev)
->bus_type:remove()或device_driver:remove()
device_del(dev)->kobject_uevent(kobj_remove)
(3) 當在匯流排上新增(或刪除)裝置時,會依次遍歷匯流排上的所有驅動程式,呼叫匯流排定義的
match()方法檢查要加入(或刪除)的裝置是否和驅動程式「匹配」,如果匹配成功,則對裝置
呼叫匯流排或驅動程式中定義的probe(或remove)方法。新增裝置時產生kobj_add uevent,
刪除裝置時產生kobj_remove uevent
5 總結一下在匯流排中新增和刪除驅動程式的過程:
(1) 驅動程式新增
driver_register(drv)-> bus_add_driver (drv)-> driver_attach(drv)
->__driver_attach(dev,drv)
->bus_type():match(dev,drv) then
->driver_probe_device()->really_probe()
->bus_type:probe() 或device_driver:probe()
driver_register(drv)-> kobject_uevent(kobj_add)
(2) 驅動程式刪除
driver_unregister(dev)->bus_remove_driver(drv)-> driver_detach(drv)
->__ device_release_driver(dev) [dev-drv 管理的所有裝置]
->bus_type:remove() 或device_driver:remove()
(3) 當在匯流排上新增(或刪除)驅動程式時,會依次遍歷匯流排上的所有裝置,呼叫匯流排定義的
match()方法檢查要加入(或刪除)的驅動程式是否和裝置「匹配」,如果匹配成功,則對裝置
呼叫匯流排或驅動程式中定義的probe(或remove)方法。新增驅動程式時產生kobj_add
uevent,刪除驅動程式時產生kobj_remove uevent。[注:kobj_remove uevent 在
kobject_put(&drv->p->kobj)中產生]
作業系統 再識 linux 等待佇列
linux 核心的等待佇列是以雙迴圈鍊錶為基礎資料結構,與程序排程機制緊密結合,能夠用於實現核心的非同步事件通知機制。在這個鍊錶中,有兩種資料結構 等待佇列頭 wait queue head t 和等待佇列項 wait queue t 等待佇列頭和等待佇列項中都包含乙個list head型別的域作為...
作業系統 再識 Linux從檔案到字元裝置
在 dev下面有很多裝置,其中也有大家廣為使用的字元裝置,呢裡面的檔案是如何與字元裝置掛鉤的呢 平時我們使用的open函式是如何動態載入字元裝置的操作集的呢 下面就讓我們慢慢剖析 以核心2.6.26為參考 一.首先是檔案系統 需要動態解析檔案路徑名 像 dev ts0 在檔案系統裡分為3個部分 1....
作業系統 再識 字元裝置驅動編寫步驟
1.標準字元裝置驅動 a.註冊裝置號如 if key major 靜態註冊 err register chrdev region devno,1,device name else b.記憶體申請給 cdev 當cdev 定義為指標時 然後呼叫以下函式進行裝置初始化並新增該裝置 void cdev i...