参考文章:http://www.wowotech.net/device_model/kobject.html
目录
1. 前言
Kobject是组成设备模型的基本结构。最初Kobject只是被用于简单的引用计数,但是随着时间的推移,它的任务越来越多,因此也有了很多的数据成员。现在Kobject结构所能处理的任务如下:
对象的引用计数
通常,一个内核对象被创建时,不可能知道该对象存活的时间。跟踪此对象生命周期的一个方法是使用引用计数。当内核中没有代码持有该对象的引用时,该对象将结束自己的有效生命周期,而且可以被删除。
sysfs表述
和sysfs文件系统配合,将每一个Kobject及其特性,以文件的形式,开放到用户空间。
数据结构关联
从整体上看,设备模型是一个友好而复杂的数据结构,通过在其间的大量连接而构造成一个多层次的体系结构。Kobject实现了该结构并把它们聚合在一起。
热插拔事件处理
当系统中的硬件被热插拔时,在Kobject子系统的控制下,将产生事件以通知用户空间。
2. Kobject 相关基础知识
先简单说一下Kobject,Kobj_type,Kset的作用:
Kobject是基本数据类型,每个kobject都会在"/sys/“文件系统中以目录的形式出现。
Kobj_type代表Kobject(严格地讲,是包含了Kobject的数据结构)的属性操作集合(由于通用性,多个Kobject可能共用同一个属性操作集,因此把Ktype独立出来了)。
Kset是一个特殊的Kobject(因此它也会在"/sys/“文件系统中以目录的形式出现),它用来集合相似的Kobject(这些Kobject可以是相同属性的,也可以不同属性的)。
注1:在Linux中,Kobject几乎不会单独存在。它的主要功能,就是内嵌在一个大型的数据结构中,为这个数据结构提供一些底层的功能实现。
注2:Linux driver开发者,很少会直接使用Kobject以及它提供的接口,而是使用构建在Kobject之上的设备模型接口。
3. Kobject 相关数据结构源码分析
源码版本:Kernel 3.10
源码路径:
include/linux/kobject.h
lib/kobject.c
3.1. Kobject 结构体
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct sysfs_dirent *sd;
struct kref kref;
unsigned 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;
};
name,该Kobject的名称,同时也是sysfs中的目录名称。由于Kobject添加到Kernel时,需要根据名字注册到sysfs中,之后就不能再直接修改该字段。如果需要修改Kobject的名字,需要调用kobject_rename接口,该接口会主动处理sysfs的相关事宜。
entry,用于将Kobject加入到Kset中的list_head。
parent,指向parent kobject,以此形成层次结构(在sysfs就表现为目录结构)。
kset,该kobject属于的Kset。可以为NULL。如果存在,且没有指定parent,则会把Kset作为parent(别忘了Kset是一个特殊的Kobject)。
ktype,该Kobject属于的kobj_type。每个Kobject必须有一个ktype,或者Kernel会提示错误。
sd,该Kobject在sysfs中的表示。
kref,"struct kref”类型(在include/linux/kref.h中定义)的变量,为一个可用于原子操作的引用计数。
state_initialized,指示该Kobject是否已经初始化,以在Kobject的Init,Put,Add等操作时进行异常校验。
state_in_sysfs,指示该Kobject是否已在sysfs中呈现,以便在自动注销时从sysfs中移除。
state_add_uevent_sent/state_remove_uevent_sent,记录是否已经向用户空间发送ADD uevent,如果有,且没有发送remove uevent,则在自动注销时,补发REMOVE uevent,以便让用户空间正确处理。
uevent_suppress,如果该字段为1,则表示忽略所有上报的uevent事件。
注1:Uevent提供了“用户空间