不记得以前是否搞清楚过,看了一些书,和网上的一些文章,每个人理解的方法和方式不一样,不是那么明白,好了,写一个适合自己的文档理清相关概念与技术点。
设备模型最初的动机是PM电源管理,这需要一棵树来描述系统设备拓扑结构。出来调试方便,将这棵设备树导出到FS文件系统,也就是sysfs,最初被称为driverfs[2].
sysfs出现是早于kobject。一个以kobject为基础的设备模型应用而生。对外是sysfs,对内是kobject拓扑树。
具体到实现上:
1.kobject是核心。纯粹的kobject有两个首要功能,kref引用计数 ,parent构造树拓扑。
然而kobj没有容器的功能,在电源管理上会遇到问题:如何遍历所有子结点?sysfs上的确会看到子结点,但是那是sysfs的。
纯kobj构造的树,是不能从root根遍历所有子结点。只能向上找parent.
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct kernfs_node *sd; /* sysfs directory entry */
struct kref kref;
};
2. kset就是kobject的一个子类(从oop角度),也就是增强扩展版的kobject。扩展了2个功能:容器,uevent。
In many ways, a kset looks like an extension of the kobj_type structure; [3]
struct kset {
struct list_head list;
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
} ;
从接口API上看,
kobject_add(struct kobject *kobj)对应 int kset_add(struct kset *kset)。
struct kobject *kobject_get(struct kobject *kobj)对应struct kset *kset_get(struct kset *kset);
理论上所有的kobject_xx()都有对应kset_xx().事实上只是大部分有对应。这是C语言实现oop造成的,但是透过语言本身来说本质:kset就是kobj,只是有额外功能。
网上有些图像模像样的画了kset/kobj/ktype的关系图,本来只有一物,整出多的概念是容易误导的。
于是,sysfs或者kobj/kset的树是一个多态树。kobj是骨干,其上附着了多态功能。
3.ktype是类的操作
4. sysfs的属性attr,这个完全不在kobj中,可见kobj的干净。通过sysfs_create_file()来加attr。也就是说attr是附属扩展的东西,是可选项。
ref:
1] linux-4.19.138\Documentation\kobject.txt
2] <Linux内核设计与实现>
3] The zen of kobjects https://lwn.net/Articles/51437/