Linux那些事儿之我是Sysfs(2)linux设备底层模型
關于linux設備模型網上有一些論述,有些東西我就用了拿來主義,進行了修改和整理。
?
§1 Kobject
Kobject 是Linux 2.6引入的新的設備管理機制,在內核中由struct kobject表示。通過這個數據結構使所有設備在底層都具有統(tǒng)一的接口,kobject提供基本的對象管理,是構成Linux2.6設備模型的核心結構,它與sysfs文件系統(tǒng)緊密關聯(lián),每個在內核中注冊的kobject對象都對應于sysfs文件系統(tǒng)中的一個目錄。Kobject是組成設備模型的基本結構。類似于C++中的基類,它嵌入于更大的對象的對象中--所謂的容器--用來描述設備模型的組件。如bus,devices, drivers 都是典型的容器。這些容器就是通過kobject連接起來了,形成了一個樹狀結構。這個樹狀結構就與/sys相對應。
kobject 結構為一些大的數據結構和子系統(tǒng)提供了基本的對象管理,避免了類似機能的重復實現(xiàn)。這些機能包括
- 對象引用計數.
- 維護對象鏈表(集合).
- 對象上鎖.
- 在用戶空間的表示.
?
Kobject結構定義為:
文件:include/linux/kobject.h
struct kobject {const char *name;指向設備名稱的指針struct list_head entry;掛接到所在kset中去的單元struct kobject *parent;指向父對象的指針struct kset *kset;所屬kset的指針struct kobj_type *ktype;指向其對象類型描述符的指針struct kernfs_node *sd; sysfs文件系統(tǒng)中與該對象對應的文件節(jié)點路徑指針struct kref kref;對象引用計數
#ifdef CONFIG_DEBUG_KOBJECT_RELEASEstruct delayed_work release;
#endifunsigned 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;
};
其中的kref域表示該對象引用的計數,內核通過kref實現(xiàn)對象引用計數管理,內核提供兩個函數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指向的目錄下創(chuàng)建文件節(jié)點,并啟動該類型內核對象的hotplug函數。
int kobject_init_and_add(struct kobject * kobj);kobject注冊函數。通過調用kobject_init ()初始化kobj,再調用kobject_add()完成該內核對象的注冊。
void kobject_del(struct kobject * kobj);從Linux設備層次(hierarchy)中刪除kobj對象。
void kset_unregister(struct kobject * kobj);kobject注銷函數。與kobject_register()相反,它首先調用kobject_del從設備層次中刪除該對象,再調用kobject_put()減少該對象的引用計數,如果引用計數降為0,則釋放kobject對象。
?
§2 Kobj type
include/linux/kobject.h
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);
};
Kobj_type數據結構包含五個域:一個release方法用于釋放kobject占用的資源;一個sysfs_ops指針指向sysfs操作表和一個sysfs文件系統(tǒng)缺省屬性列表。Sysfs操作表包括兩個函數store()和show()。當用戶態(tài)讀取屬性時,show()函數被調用,該函數編碼指定屬性值存入buffer中返回給用戶態(tài);而store()函數用于存儲用戶態(tài)傳入的屬性值。
include/linux/sysfs.h
struct attribute {const char *name;umode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOCbool ignore_lockdep:1;struct lock_class_key *key;struct lock_class_key skey;
#endif
};
?
attribute, 屬性。它以文件的形式輸出到sysfs的目錄當中。在kobject對應的目錄下面。文件名就是name。文件讀寫的方法對應于kobj_type中的sysfs_ops。
??
§3. kset
kset最重要的是建立上層(sub-system)和下層的(kobject)的關聯(lián)性。kobject也會利用它來分辨自已是屬于哪一個類型,然后在/sys下建立正確的目錄位置。而kset的優(yōu)先權比較高,kobject會利用自已的*kset找到自已所屬的kset,並把*ktype指定成該kset下的ktype,除非沒有定義kset,才會用ktype來建立關系。Kobject通過kset組織成層次化的結構,kset是具有相同類型的kobject的集合,在內核中用kset數據結構表示,定義為:
include/linux/kobject.h
struct kset {struct list_head list;用于連接該kset中所有kobject的鏈表頭spinlock_t list_lock;struct kobject kobj;嵌入的kobjectconst struct kset_uevent_ops *uevent_ops;
};
?
包含在kset中的所有kobject被組織成一個雙向循環(huán)鏈表,list域正是該鏈表的頭。Kset數據結構內嵌了一個kobject對象(由kobj域表示),所有屬于這個kset的kobject對象的parent域均指向這個內嵌的對象。此外,kset還依賴于kobj維護引用計數:kset的引用計數實際上就是內嵌的kobject對象的引用計數。
見圖1,kset與kobject的關系圖
?
?
這幅圖很經典,她反映了整個kobject的連接情況。
?
相關函數
與kobject 相似,kset_init()完成指定kset的初始化,kset_get()和kset_put()分別增加和減少kset對象的引用計數。kset_register()函數完成kset的注冊而kset_unregister()函數則完成kset的注銷。
?
總結
以上是生活随笔為你收集整理的Linux那些事儿之我是Sysfs(2)linux设备底层模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上海物价已经荒谬到天上了,为什么还是没有
- 下一篇: 2024年春假方案骂声一片,放不起别放,