kobject设备模型分析.pdf
《kobject设备模型分析.pdf》由会员分享,可在线阅读,更多相关《kobject设备模型分析.pdf(6页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、sysfs 是 kobject 的表达,所以这里翻译了 Documention 下的 kobjct.txt,并加上了一些自己的注释,这样基本就对 kobject和 sysfs 有了一个比较深刻的理解,我们可以简单的将 sysfs 看成最 bottom 的操作,然后 kobject 的想关操作是架构在 sysfs之上,再然后 kobject 和 attribute 所嵌入的结构体再构成上一层结构来操作 kobject,最后就实现了 kernel 内部各个 portion通过 sysfs 与 userspace 进行交互。要想了解 linux 驱动模型,以及驱动模型之上的 kobject 抽象,有
2、一个难点就是我们没有一个明确的入手点。要想了解 kobject我们必须了解很多不同的类型,而这些类型之间又会交叉引用,所以为了让理解更容易我们从多方面入手,首先看一些可能模糊不清的概念,然后随着深入我们会加入细节,在最后我们会定义一些我们工作上需要使用的术语。kobject 是一个结构体,它包含 name,reference count 以及指向一个 parent 的指针(这个指针等于就是将 kobject 加入了一个体系结构中),一个特定的类型,以及在 sysfs 文件系统中的一个相关表达。kobject 一般不会单独使用,大部分的时候它会被嵌入其他的结构体,而这些结构体才是我们代码中真正需
3、要的。一个结构体最多只能嵌入一个 kobject,不然 reference count 就会乱掉,出错。(PS:实际上我们可以理解这个 kobject 实际上是我们与 sysfs 进行交互的一个接口,我们在设备驱动以及总线相关的结构体中嵌入这个 kobject,那么我们的设备驱动就可以通过 sysfs 与 userspace 进行交互了。虽然 sysfs 是 kobject 的表达,但我们可以近似的将 kobject 看成是架在 sysfs 上面的,在 kobject 上面封装的一系列操作实际上到底层都是调用的 sysfs 的公共接口)struct kobject const char *na
4、me;struct list_head entry;struct kobejct*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;unsigend int state_remove_uevent_sent:1;ktype 定义了嵌入了 kobject 的结构体的类型,每一
5、个嵌入了 kobject 的结构体都必须有一个想对应的 ktype,ktype 定义了这个 kobject 创建和销毁时候需要做的事情。struct kobj_type void(*release)(struct kobject*kobj);struct sysfs_ops*sysfs_ops;struct attribute*default_attrs;(PS:看过代码以后感觉这个定义了 kobject 创建和销毁时候应该做的事情实际上并没有,kobj_type 结构体有 3 个成员,release 函数指针由自己定义来实现,定义了引用计数为 0 的时候对 kobject 的处理;sysfs
6、_ops 里面有两个成员变量分别是show 和 store 函数指针,分别是对 attribute 文件进行读写时候的处理,也需要我们来实现;attribute_attrs 是一个 attribute数组,是这个 kobject 被创建的时候会自动创建的 attributes)kset 说穿了就是一个 kobjects 的集合,这些 kobjects 可以有相同的 ktype 也可以不同 ktype。kset 应该来说是一个容器类型,用来存放 kobjects。struct kset struct list_head list;spinlock_t list_lock;struct kobje
7、ct kobj;struct kset_uevent_ops*uevent_ops;(PS:kset 我们看 kernel 的注释,它定义了 attribute callback 以及一个 kobject 可能发生的 event,从结构提本身来说我们可以看到它本身有一个链表来记载它所包含的 kobject,而且它本身包含一个 kobject,对于事件的处理应该是这个uevent_ops 了,从官方的解释来看(kset 的一组 uevent 的相关操作)它就是涉及对 uevent 的处理,这里还不知道它具体是如何处理的)我们知道单独使用的 kobject 在 kernel 里面是极少的,kobj
8、ect 主要通过嵌套的方式用来控制对一个大的,某个领域的结构体的访问。如果有面向对象的思想的话,我们可以将 kobject 理解为一个最顶端的抽象类,其他结构体都继承它的基础特性,并加入自己的特性。c 语言没有继承的技术,但是可以通过结构体嵌套的方式实现类似的逻辑。举个例子,比如一个 UIO 设备拥有一块内存区域,这个内存区域的结构体的定义如下:struct uio_mem struct kobject kobj;unsigned long addr;unsigned long size;int memtype;void _iomem*internal_addr;(PS:在实际编程中我们经常需
9、要完成从 kobject,及其所嵌入的结构体之间的转换,比如说知道 kobject 实体,我们要找到它所嵌入的结构体实体,从上面的例子就是我们知道 kobj 的时候,我们要找到它所在的 uio_mem 实体。这里就涉及一个很有用的宏container_of(pointer,type,member),这个宏定义在linux/kernel.h里面,第一个参数就是指向kobject的指针,type是指嵌入 kobject 的结构体类型,member 就是在结构体类型里面 kobject 的成员名,以上面的 uio_mem 为例就是:sturct uio_mem*u_mem=container_of(
10、kp,struct uio_mem,kobj)我们使用下面的函数来初始化一个 kobject,其中 ktype 是必须的:void kobject_init(struct kobject*kobj,struct kobj_type*ktype);(PS:我们可以简单看看这个 init 干了什么事情,首先将 kobj-kref 置为 1,也就是初始化的 kobject 的引用计数为 1;然后kobj-entry 这个双向链表都指向自身;然后就是对标志位的一系列初始化,主要是初始化为真,在 sysfs 为假,相关的 event也全为 0)初始化以后我们就可以通过 kobject_add 将我们的
11、kobject 加入 sysfs 文件系统了:int kobject_add(struct kobject*kobj,struct kobject*parent,const char*fmt,);(PS:这个函数第一个参数是要加入 sysfs 的 kobject;第二个参数是 kobject 的 parent,可以为空,如果为空的话首先判断kset 是否为空,如果不为空则 parent 设置为 kset,如果都为空则默认这个 kobject 会被建立在 sysfs 的顶层目录下;fmt 是定义了 kobject 的 name。同样我们可以看看这个 add 的具体过程,首先根据 fmt 设置 k
12、object 的 name 成员,然后 kset存在的话会将这个 kobject 加入 kset,加入 kset 的过程就是将 kobject 的 entry 放入 kobj-kset-list 这个双向循环链表中,由此我们可以看到 kobject 的 entry 的功能就是放入 kset 的 list 链表中。这里还会设置 kobject 的 parent,然后就会调用 sysfs_create_dir 来创建目录,创建目录的过程会 allocate 一个 sysfs_dirent 的结构体,从 kernel 对这个结构体的描述来看,sysfs 上面每一个结点都是使用这个结构体来描述的,由此
13、我们可以理解 kobject 里面的 sd 成员这里的 sd 个人猜测应该是 sysfs directory 吧变量作用了,他是在注册到 sysfs 的时候由 sysfs 来创建的,创建完目录以后如果 ktype 里面有attribute 数组的话,还会创建默认的 attribute 文件。)kobject 的目录名不能粗暴的直接去改 kobject 的 name 成员,应该使用相应的 API 去改:int kobject_rename(struct kobject*kobj,const char*new_name);(PS:我们看过这个函数的实现后就清楚,它会先调用 sysfs_rename
14、_dir 来修改目录名以后再才会修改 kobject 的 name 成员,最后它还会将发生改变的目录加上目录改变的事件以环境变量的方式通过 kobjec_uevent_env()发送出去。)这个函数没有锁操作,也不会检查 name 的有效性,所以调用这个函数的时候我们要进行相应的合法性检测,并加入自己的互斥操作。另外我们也可以通过下面的函数来取得 kobject 的 name 成员:const char*kobject_name(const struct kobject*kobj);另外这里还一个对 kobject 的 init 和 add 合二为一的操作:int kobject_init_a
15、nd_add(sturct kobject*kobj,struct kobj_type*ktype,struct kobjcet*parent,const char*fmt,)当我们将一个 kobject注册到 kobject core以后,我们可能需要告诉其他模块或者 userspace我们已经注册了一个 kobject,这里有一个函数可以帮我们实现这一点:int kobject_uevent(struct kobject*kobj,enum kobject_action action);当我们第一次 add 一个 kobject 的时候可以用 KOBJ_ADD 事件,但是这个事件的通知必须
16、是在这个 kobject 所有的 attibure或者它的子目录都创建以后才行,因为一旦调用这个函数用户空间就知道了,就可能会去操作这个 kobject 下面的 attribute文件。当这个 kobject 被删除的时候,KOBJ_REMOVE 事件会自动产生。(PS:把这个函数基本过了一遍,大致是这样的,首先找到 kobj 属于哪个 kset 的,如果当前 kobj 没有 kset 就会寻找他父 kobje的 kset,直到找到 kset 为止,没有找到就会报错;找到 kset 以后会看它的 uevent_ops 里面的 filter 指针是否为空,不为空的就话就会调用这个函数,如果这个函
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- kobject 设备 模型 分析
限制150内