裝置驅動模型之: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屬性;