linux 設備模型

2.6內核的設備模型支持以下特性:

1. 電源管理

2. 與用戶空間通信

3. 熱插拔設備

4. 設備類型管理

5. 對象生命週期

 

§1. 底層組件kobject, kset, kobj_type, ksubsystem(merge to kset after 2.6.31)

kobject對象有名字和引用計數。每個kobject對應一個kobj_type(由kobject結構自己提供,或者kobject所屬的kset指定)。

kset對應kobject的聚合,每個kset都在sysfs中以目錄的形式出現;kobject不必在sysfs虛擬文件系統中出現,但kset中的kobject成員都在sysfs中出現。kset在內核鏈表中保存了它的子節點。

|---------------Kset(內部有自己的kobject)-------------|

|                                                                                                                                                          |

|--------list node-----list node 。。。。。。。--list node-------- |  // 每個list node指向一個kobject對象

 

§2. bus, device and driver

bus的結構爲bus_type,在內核中所有的bus都在bus_kset鏈表上,註冊函數爲bus_register(此函數中也會創建並初始化bus的兩個成員:devices_kset,drivers_kset,並且調用bus_create_file在bus目錄下創建屬性文件)。bus_type的主要成員有name,match,probe,hotplug,uevent,remove,resume,suspend等。

device爲系統的各個設備(注意:不是一類)。如PCI總線,在pci_legacy_init或pci_numaq_init的時候就遍歷各總線,形成pci_bus或pci_dev的樹,同時將各個device添加到pci_bus_type的klist_devices。pci_bus可以有多個,但是pci_bus_type只有一個。每個pci設備對應一個devicename爲[domain:bus:slot:fn]各不相同。在此後調用driver_register的時候,會依次遍歷bus->klist_devices,如果匹配的話,將dev添加到driver->klist_devices

driver的結構爲device_driver,主要成員包括name,*bus_type,probe,match,shutdown,remove,supend,resume,*dev_pm_ops,*klist_devices,knode_bus(鏈接到bus上)等。driver_register依次查找各bus_type的klist_devices,如果匹配的話將設備添加到driver->klist_devices。

 注:

一般而言,只要是採用PCI總線的機器,BIOS提供對PCI總線操作的支持,因而稱爲PCI BIOS。最早Linux內核也是通過這種BIOS調用的方式來獲取系統中的PCI設備信息的;但有的平臺沒有BIOS(如某些嵌入式系統),或者有些PCI BIOS存在問題,所以後來Linux內核自己動手了。Linux內核在make menuconfig選項PCI access mode裏面提供BIOS、MMconfig、Direct和Any,其中Direct就是拋開BIOS由內核自己完成初始化。 

 §3.字符設備(塊設備一般用於磁盤等,不做研究)

 下圖爲字符設備的組織圖:

點擊查看原始尺寸

 

字符設備:字符設備的內核結構爲cdev:

struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
這裏面一個重要的成員是kobj,在cdev_add的時候添加到系統中;ops用於對字符設備的操作。

字符設備模型目的是對用戶暴露出/dev下的設備,用戶可以把設備當作文件進行open,read,write等操作。 在open系統調用中,內核將inode->i_cdev設置爲cdev對象,然後在用戶註冊的fops->open中可以將此cdev(或包含cdev的用戶自定義結構)賦值給filp->private_data,這樣以後的文件操作都可以對cdev操作。

cdev_add 函數將cdev結構添加進系統中的cdev_map[255]數組。

2.6以後的platform_device 專門用於對無總線的設備的處理(最初用於統一管理嵌入式系統上的設備)。相對於cdev來說,電源管理、sysfs節點都可以配套實現;但因爲platform無自動探測功能,需要用戶手工添加設備(這跟cdev一樣)。

§4 sysfs 文件系統,用於描述內核空間的設備。bus,driver,device在這裏都有對應的目錄。在未知一個設備用哪一個驅動的情況下可以先從/sys/module/ 查找相應模塊的情況,再從 drivers找對應的驅動程序;或者反過來利用這些信息,先用找到/sys/devices/下的設備節點,再從其設備的driver 鏈接找到/sys/bus/*/drivers/下的device_driver, 再從device_driver下的module鏈接找到/sys/module/*/,這樣就知道是哪一個模塊給設備提供驅動程序。

發佈了22 篇原創文章 · 獲贊 7 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章