歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux的kobject和Windows的GUID

Linux的kobject和Windows的GUID

日期:2017/2/28 16:16:25   编辑:Linux教程

一.數據結構設計
0. 需要被管理的實體實際上很雜,包括設備,驅動,總線,類型,塊設備,電源等等...迫切需要統一管理。
1. kobject代表每一個被管理實體,很顯然的,這些實體可以帶有一個或者多個屬性。
2. 這些屬性由attribute表示,由於被管理的實體不同,可能還會互相嵌套,因此很難給出一個明確的attribute的定義,因此使用了list_head的設計方式,將它僅僅作為一個錨點,真實的數據存在於它附近的內存區域,通過container_of宏來得到。(之所以可以這麼做,得益於馮諾依曼機器的連續存儲)
3. 另外,由於kobject也是一個錨點,並不攜帶真實數據,因此kobject和attribute之間也不便直接建立關系,而是通過kobj_type結構體解除耦合的。
4. 為了將被管理實體歸類,設計了kset數據結構,管理一類kobject
5. kset同時也是一個kobject,這就實現了一個組合模式。kobject的精化最終在這裡體現。

二.用什麼方式表現
1. 由於kobject將所有被管理實體組織成一個樹型結構,因此任意可以表示樹型結構的方式都可以采用。
2. linux並不像windows導出很多操作接口(比如注冊表,文件等),它基本只導出文件接口,也就是一個vfs接口,同時linux的文件系統組織是樹型的,且實現了mount擴展機制,將不同類型的文件系統子樹嫁接在根的任意子節點(需要是目錄)上。
3. 很方便為kobject實現一個文件系統,然後mount到某一處。
4. 這個文件系統類型就是sysfs,一般處於/目錄下的/sysfs目錄中。

三.實現
1. kobject的定義:
struct kobject {
const char *name; //名稱
struct list_head entry; //
struct kobject *parent; //kobject組成鏈表,便於查找
struct kset *kset; //此kobj所屬的kset
struct kobj_type *ktype; //kobj_type解耦了kobj和attr
struct sysfs_dirent *sd; //sysfs中的組織結構
struct kref kref; //引用計數
...
};
2. kobj_type的定義:
struct kobj_type {
void (*release)(struct kobject *kobj);
struct sysfs_ops *sysfs_ops; //該kobj_type所屬的kobject的所有attribute的總的store和show方法
struct attribute **default_attrs; //此type的屬性們
};
3. kset的定義:
struct kset {
struct list_head list; //屬於此kset的kobj們
...
struct kobject kobj; //kset本身也是一個kobject,實現一個類別
struct kset_uevent_ops *uevent_ops; //實現向用戶態的通知機制
};
4. 真實attribute的定義:
struct edac_pci_dev_attribute {
struct attribute attr; //所屬的attribute結構錨點
void *value; //真實的,單獨的attribute的值
ssize_t(*show) (void *, char *); //真實的,單獨的attribute的show
ssize_t(*store) (void *, const char *, size_t);//真實的,單獨的attribute的store
};
5. 每一個kobject在sysfs中都實現為一個目錄,kobject是樹型的,該樹和sysfs中的目錄樹真切地對應。
6. 一個kobject的每一個attribute在sysfs中都實現為該kobject對應目錄下的一個文件,所有的attribute統一由該kobject的kobj_type管理。
7. sysfs文件系統中每一個文件代表它所屬目錄的kobject的一個屬性,擁有讀/寫方法,即show/store。
8. 所有處於同一目錄下的attribute的show/store統一由該目錄所屬kobject的kobj_type的show/store來分發,比如對於/sys/devices目錄:
8.1.在注冊一個頂層設備(比如總線等)時,均會將該device結構體的kobj的ktype初始化為device_ktype:
static struct kobj_type device_ktype = {
.release = device_release,
.sysfs_ops = &dev_sysfs_ops,
};
8.2.所有的8.1中注冊的device的屬性讀寫操作(show/store)全部通過以下的dev_sysfs_ops代理:
static struct sysfs_ops dev_sysfs_ops = {
.show = dev_attr_show,
.store = dev_attr_store,
};
static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct device_attribute *dev_attr = to_dev_attr(attr);
struct device *dev = to_dev(kobj);
ret = dev_attr->show(dev, dev_attr, buf);
}
8.3.對於每一個單獨的屬性,要單獨定義,比如對於devt屬性:
static struct device_attribute devt_attr =
__ATTR(dev, S_IRUGO, show_dev, NULL);
定義完之後,通過device_create_file加入sysfs文件系統:
device_create_file(dev, &devt_attr);
8.4.當dev_attr_show中調用dev_attr->show時,執行流被路由到show_dev函數:
static ssize_t show_dev(struct device *dev, struct device_attribute *attr, char *buf)
{
return print_dev_t(buf, dev->devt);
}
每一個kobject代表一個目錄,其sd字段將kobject樹轉換成了sysfs文件系統的文件目錄樹。注意,sysfs使用dentry中的d_fsdata字段和kobject解除了耦合,所有的操作只有在接口層面上操作dentry和inode,進入後就會通過dentry的d_fsdata字段和inode的i_private字段轉換為kobject機制的結構,比如sysfs_dirent結構。

Copyright © Linux教程網 All Rights Reserved