1. 程式人生 > >linux 裝置模型

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/*/,這樣就知道是哪一個模組給裝置提供驅動程式。