Linux那些事兒之我是Sysfs(2)linux裝置底層模型

來源:互聯網
上載者:User

關於linux裝置模型網上有一些論述,有些東西我就用了拿來主義,進行了修改和整理。

§1 Kobject
Kobject 是Linux 2.6引入的新的裝置管理機制,在核心中由struct kobject表示。通過這個資料結構使所有裝置在底層都具有統一的介面,kobject提供基本的對象管理,是構成Linux2.6裝置模型的核心結構,它與sysfs檔案系統緊密關聯,每個在核心中註冊的kobject對象都對應於sysfs檔案系統中的一個目錄。Kobject是組成裝置模型的基本結構。類似於C++中的基類,它嵌入於更大的對象的對象中--所謂的容器--用來描述裝置模型的組件。如bus,devices, drivers 都是典型的容器。這些容器就是通過kobject串連起來了,形成了一個樹狀結構。這個樹狀結構就與/sys向對應。
kobject 結構為一些大的資料結構和子系統提供了基本的對象管理,避免了類似機能的重複實現。這些機能包括
- 對象引用計數.
- 維護對象鏈表(集合).
- 對象上鎖.
- 在使用者空間的表示.

Kobject結構定義為:
struct kobject {
char * k name; 指向裝置名稱的指標
char name[KOBJ NAME LEN]; 裝置名稱
struct kref kref; 對象引用計數
struct list head entry; 掛接到所在kset中去的單元
struct kobject * parent; 指向父物件的指標
struct kset * kset; 所屬kset的指標
struct kobj type * ktype; 指向其物件類型描述符的指標
struct dentry * dentry; sysfs檔案系統中與該對象對應的檔案節點路徑指標
};
其中的kref域表示該對象引用的計數,核心通過kref實現對象引用計數管理,核心提供兩個函數kobject_get()、kobject_put()分別用於增加和減少引用計數,當引用計數為0時,所有該對象使用的資源釋放。Ktype 域是一個指向kobj type結構的指標,表示該對象的類型。

相關函數
void kobject_init(struct kobject * kobj);kobject初始化函數。
int kobject_set_name(struct kobject *kobj, const char *format, ...);設定指定kobject的名稱。
struct kobject *kobject_get(struct kobject *kobj);將kobj 對象的引用計數加1,同時返回該對象的指標。
void kobject_put(struct kobject * kobj); 將kobj對象的引用計數減1,如果引用計數降為0,則調用kobject release()釋放該kobject對象。
int kobject_add(struct kobject * kobj);將kobj對象加入Linux裝置層次。掛接該kobject對象到kset的list鏈中,增加父目錄各級kobject的引用計數,在其parent指向的目錄下建立檔案節點,並啟動該類型核心對象的hotplug函數。
int kobject_register(struct kobject * kobj);kobject註冊函數。通過調用kobject init()初始化kobj,再調用kobject_add()完成該核心對象的註冊。
void kobject_del(struct kobject * kobj);從Linux裝置層次(hierarchy)中刪除kobj對象。
void kobject_unregister(struct kobject * kobj);kobject登出函數。與kobject register()相反,它首先調用kobject del從裝置層次中刪除該對象,再調用kobject put()減少該對象的引用計數,如果引用計數降為0,則釋放kobject對象。

§2 Kobj type
struct kobj_type {
void (*release)(struct kobject *);
struct sysfs_ops * sysfs_ops;
struct attribute ** default_attrs;
};
Kobj type資料結構包含三個域:一個release方法用於釋放kobject佔用的資源;一個sysfs ops指標指向sysfs動作表和一個sysfs檔案系統預設屬性列表。Sysfs動作表包括兩個函數store()和show()。當使用者態讀取屬性時,show()函數被調用,該函數編碼指定屬性值存入buffer中返回給使用者態;而store()函數用於儲存使用者態傳入的屬性值。
attribute
struct attribute {
char * name;
struct module * owner;
mode_t mode;
};
attribute, 屬性。它以檔案的形式輸出到sysfs的目錄當中。在kobject對應的目錄下面。檔案
名就是name。檔案讀寫的方法對應於kobj type中的sysfs ops。

§3. kset
kset最重要的是建立上層(sub-system)和下層的(kobject)的關聯性。kobject 也會利用它了分辨自已是屬於那一個類型,然後在/sys 下建立正確的目錄位置。而kset 的優先權比較高,kobject會利用自已的*kset 找到自已所屬的kset,並把*ktype 指定成該kset下的ktype,除非沒有定義kset,才會用ktype來建立關係。Kobject通過kset組織成層次化的結構,kset是具有相同類型的kobject的集合,在核心中用kset資料結構表示,定義為:
struct kset {
struct subsystem * subsys; 所在的subsystem的指標
struct kobj type * ktype; 指向該kset物件類型描述符的指標
struct list head list; 用於串連該kset中所有kobject的鏈表頭
struct kobject kobj; 嵌入的kobject
struct kset hotplug ops * hotplug ops; 指向熱插拔動作表的指標
};
包含在kset中的所有kobject被組織成一個雙向迴圈鏈表,list域正是該鏈表的頭。Ktype域指向一個kobj type結構,被該kset中的所有kobject共用,表示這些對象的類型。Kset資料結構還內嵌了一個kobject對象(由kobj域表示),所有屬於這個kset 的kobject對象的parent域均指向這個內嵌的對象。此外,kset還依賴於kobj維護引用計數:kset的引用計數實際上就是內嵌的kobject對象的引用計數。
見圖1,kset與kobject的關係圖

 

這幅圖很經典,她反映了整個kobject的串連情況。

相關函數
與kobject 相似,kset_init()完成指定kset的初始化,kset_get()和kset_put()分別增加和減少kset對象的引用計數。Kset_add()和kset_del()函數分別實現將指定keset對象加入裝置層次和從其中刪除;kset_register()函數完成kset的註冊而kset_unregister()函數則完成kset的登出。

§4 subsystem
如果說kset 是管理kobject 的集合,同理,subsystem 就是管理kset 的集合。它描述系統中某一類裝置子系統,如block subsys表示所有的塊裝置,對應於sysfs檔案系統中的block目錄。類似的,devices subsys對應於sysfs中的devices目錄,描述系統中所有的裝置。Subsystem由struct subsystem資料結構描述,定義為:
struct subsystem {
struct kset kset; 內嵌的kset對象
struct rw semaphore rwsem; 互斥訪問訊號量
};

可以看出,subsystem與kset的區別就是多了一個訊號量,所以在後來的代碼中,subsystem已經完全被kset取締了。

每個kset屬於某個subsystem,通過設定kset結構中的subsys域指向指定的subsystem可以將一個kset加入到該subsystem。所有掛接到同一subsystem的kset共用同一個rwsem訊號量,用於同步訪問kset中的鏈表。
相關函數
subsystem有一組類似的函數,分別是:
void subsystem_init(struct subsystem *subsys);
int subsystem_register(struct subsystem *subsys);
void subsystem_unregister(struct subsystem *subsys);
struct subsystem *subsys_get(struct subsystem *subsys)
void subsys_put(struct subsystem *subsys);

關於那些函數的用法,會在後面的舉例中詳細講。這裡僅僅是一個介紹。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.