1. 程式人生 > >裝置驅動模型之:kobject,kset,ktype(一)

裝置驅動模型之:kobject,kset,ktype(一)

概述
kobject結構是linux驅動程式的基礎,也是裝置模型中抽象的一部分。如果想要了解驅動程式必須瞭解kobject結構的具體資料組成以及kobject結構的作用。核心為了相容各種形形色色的裝置,必須對各種裝置的共同特性進行抽象。這種抽象在C++中稱之為基礎類,但是C語言沒有繼承特性,所以需要把此結構體嵌入到要抽象的結構體之中。
例如:字元裝置驅動的cdev結構,使用的就是kobject的計數功能,他是把kobject結構體嵌入到struct cdev結構中,如下:

struct cdev {
	/**把kobject結構體嵌入到struct cdev結構體中**/
        struct
kobject kobj; struct module *owner; const struct file_operations *ops; struct list_head list; dev_t dev; unsigned int count; };

struct cdev結構體怎麼使用struct kobject結構體的計數功能呢?具體如下:

 	1.在cdev_init中呼叫kobject_init初始化kobj的kref
 	2.在cdev_get和cdev_put中分別對於kobj的kref引用計數進行操作; 

那麼kobject的作用有哪些呢?除了上面提到的對於物件的引用計數還有什麼功能呢?
1、sysfs 表述:在 sysfs 中出現的每個物件都對應一個 kobject, 它和核心互動來建立它的可見表述。
2、資料結構關聯:整體來看, 裝置模型是一個極端複雜的資料結構,通過其間的大量連結而構成一個多層次的體系結構。kobject 實現了該結構並將其聚合在一起。
3、熱插拔事件處理 :kobject 子系統將產生的熱插拔事件通知使用者空間。
4.物件的引用計數;
以下是kobject結構體的具體表述:

struct kobject {
	/*name:   用來表示核心物件的名稱,如果該核心物件加入到系統,那麼它的name
	就會出現在sys目錄下。***/
const char *name; /***entry:用來將一系列的核心物件kobject連線成連結串列**/ struct list_head entry; /**parent:用來指向該核心物件的上層節點,從而可以實現核心物件的層次化結構*/ struct kobject *parent; /*用來執行核心物件所屬的kset。kset物件用來容納一系列同類型的kobject*/ struct kset *kset; /***ktype: 用來定義該核心物件的sys檔案系統的相關操作函式和屬性。*/ struct kobj_type *ktype; /**sd:用來表示該核心物件在sys檔案系統中的目錄項例項*/ struct sysfs_dirent *sd; /***kref:其核心是原子操作變數,用來表示該核心物件的引用計數。*/ struct kref kref; unsigned int state_initialized:1; unsigned int state_in_sysfs:1; unsigned int state_add_uevent_sent:1; unsigned int state_remove_uevent_sent:1; unsigned int uevent_suppress:1; }; /***** state_initialized: 用來表示該核心物件的初始化狀態,1表示已經初始化,0 表示未初始化。 state_in_sysfs: 用來表示該核心物件是否在sys中已經存在。 state_add_uevent_sent: 用來表示該核心物件是否向用戶空間傳送了 ADD uevent事件 state_remove_uevent_sent:用來表示該核心物件是否向用戶空間傳送了Remove uevent事件 uevent_suppress: 用來表示該核心物件狀態發生改變時,時候向用戶空間傳送 uevent事件,1表示不傳送。

以上資訊還不能全部描述出來全部的kobject的作用,需要結合struct kset 和struct kobj_type來進行描述,如下:

struct kset {
	/**對於每一個kset下對應的kobject連結串列描述,連結的是實體的kobject**/
        struct list_head list;
    	/**鎖操作***/
        spinlock_t list_lock;
        /**每一個kset下都有一個kobject描述**/
        struct kobject kobj;
        /**kset的操作;***/
        const struct kset_uevent_ops *uevent_ops;
};
	/**以下是對於kobj_type描述**/
struct kobj_type {
        void (*release)(struct kobject *kobj);
        const struct sysfs_ops *sysfs_ops;
        struct attribute **default_attrs;
        const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
        const void *(*namespace)(struct kobject *kobj);
};

kobject和kset還有ktype對應的關係:

在這裡插入圖片描述
對於以上對應的關係可以簡單理解為:
1.kset和kobject在核心中存在相當於是在/sys/目錄下建立了資料夾;
2.kobj_type操作就比較複雜一點:可以操作檔案的讀取寫入,還有控制kobject/kset模組的釋放;
3.對於kobj_type的attribute屬性來說是建立了一系列的檔案,可供讀寫,它的表示是一個數組,每一個數組元素代表建立檔案以及檔案的讀寫許可權,但是檔案的操作不使用attribute屬性,而是使用sysfs_ops屬性;