在linux內(nèi)核版本2.5新出現(xiàn)了/sys 目錄,此目錄結(jié)構(gòu)向用戶展現(xiàn)了設備驅(qū)動模型的層次結(jié)構(gòu)。/sys 提供了一個設備驅(qū)動與用戶之間的交互接口,對應于sysfs 虛擬文件系統(tǒng)。其中的每一個目錄都對應一個內(nèi)核對象kobject。目錄中存在的文件對應一個屬性。目錄為用戶展現(xiàn)了總線,設備,驅(qū)動之間的層次關系,屬性文件為用戶提供了操控設備驅(qū)動的友好接口。 接下來討論設備模型 主角 struct kobject 路徑 /include/linux/kobject.h (tapas:在內(nèi)核中要想使用struct kobject 必須#include <linux/kobject.h> 可以發(fā)現(xiàn)include linux 正好就是源碼的路徑名)
先來介紹一下其中的成員變量:
const char *name: (tapas:const char *類型表示該指針指向的內(nèi)容不可以被更改)。在內(nèi)核中它指向的內(nèi)容經(jīng)常是使用kmalloc申請得到內(nèi)存空間。所以在釋放該對象時,必須kfree。前面提到kobject對應/sys的一個目錄,那么可以猜出來,name表示對應目錄的名稱。
struct list_head entry: 內(nèi)核鏈表,常用于把屬于同一目錄下目錄鏈接起來。目錄層次關系的體現(xiàn)。
strutc kobject *parent:同樣表示一個目錄,該成員指向它的父目錄。偽代碼解釋:struct object *c,*p; c為目錄,p也為目錄。 如果c->parent = p; 那么 p為c的父目錄。
struct kset *kset: 是設備模型中的一個重要結(jié)構(gòu)。以后闡述。
struct kobj_type *ktype: 用于實現(xiàn)/sys 中的屬相文件,其中包含了讀寫對應文件的操作函數(shù)。
struct sysfs_dirent *sd:設備模型中/sys虛擬文件系統(tǒng)與設備驅(qū)動借口的關聯(lián)。當使用readwrite系統(tǒng)調(diào)用讀寫/sys中的文件是,就會通過該它調(diào)用到 ktype對用的操作函數(shù)。具體實現(xiàn)方法需要學習/sys虛擬文件系統(tǒng)。
struct kref: 是reference count的縮寫(引用次數(shù))。每次使用該對象會將該值++,取消引用該變量都會--。如果--后該變量為0,就會release(釋放)該對象該對象也就隨之消失。
對成員的介紹到此為止。寫下來寫幾個內(nèi)核模塊,加以討論。
上述代碼加入內(nèi)核后會在/sys/目錄下產(chǎn)生 ./my_kobj 目錄。
kobject_create_and_add終會調(diào)用到這里。kobject_add_varg做三件事情1.設置kobject->name.2.設置kobject->parent標志層次關系; 3.將kobject加入到系統(tǒng)中。
kobject_add_internal 主要做
主要做兩件事情,1.根據(jù)kobject根據(jù)情況判定parent的設置。在后面的kset章加以講解。2.根據(jù)
設置好的kobject為其在/sys創(chuàng)建目錄項。
在此處提一下kobject_get() 和 kobject_put() 次兩個函數(shù) 用于操作kobject->kref應用數(shù) 前者對kref
進行atomic_inc加1操作。后者進行atomic_dec減1操作。如果減到0就會執(zhí)行 void (*release)(struct kref *kref)
函數(shù)。 在此函數(shù)中會根據(jù)kref得到他所在的kobject然后調(diào)用kobject_cleanup(struct kobject *kobj)對其進行釋放。只要調(diào)用這個函數(shù) 那么該內(nèi)核對象就在內(nèi)核中徹底銷聲匿跡了。kobject_cleanup的實現(xiàn)在后面章節(jié)解釋。