Linux的kobject和Windows的GUID

一.数据结构设计 0. 需要被管理的实体实际上很杂,包括设备,驱动,总线,类型,块设备,电源等等…迫切需要统一管理。1. kobject代表每一个被管理实体,很显然的,这些实体可以带有一个或者多个属性。2. 这些属性由attribute表示,由于被管理的实体不同,可能还会互相嵌套,因此很难给出一个明确的attribute的定义,因此使用了list_head的设计方式,将它仅仅作为一个锚点,真实的数据存在于它附近的内存区域,,通过container_of宏来得到。(之所以可以这么做,得益于冯诺依曼机器的连续存储)3. 另外,由于kobject也是一个锚点,并不携带真实数据,因此kobject和attribute之间也不便直接建立关系,而是通过kobj_type结构体解除耦合的。4. 为了将被管理实体归类,设计了kset数据结构,管理一类kobject5. 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结构。

有的旅行是为了体验生活,感悟人生。

Linux的kobject和Windows的GUID

相关文章:

你感兴趣的文章:

标签云: