设为首页 加入收藏

TOP

Linux设备管理_kobject_kset_kobj_type
2016-12-28 08:16:18 】 浏览:525
Tags:Linux 设备管理 _kobject_kset_kobj_type

Linux内核大量使用面向对象的设计思想,通过追踪源码,我们甚至可以使用面向对象语言常用的UML类图来分析Linux设备管理的"类"之间的关系。这里以4.8.5内核为例从kobject,kset,kobj_type的分析入手,进而一探内核对于设备的管理方式


这个宏几乎是linux数据结构的基础,Linux中的链表与传统的链表不同,其链表的节点本身并不包含任何数据,任何想要插入到链表的数据只需要包含一个事先写好的节点



但是,使用这种通用的链表的第一个问题就是如何根据一个list_head成员来找到相应的数据,Linux社区的大神们早就找到了相应的方法,就是利用下面这个container_of宏,只需要输入成员指针ptr包含该成员的结构体类型type,以及该成员在结构体中名字name就可以返回包含ptr的type类型的结构首地址,这个宏充分利用了C语言直接操作内存的特性。需要注意的是,如果单纯为了得到地址只需要ptr-&((type* 0)->member),内核的写法其实还利用了编译器的类型检查机制做了一份校验工作,即如果传入的ptr类型和type->member的类型不匹配,会报错,


Linux内核中有大量的驱动,而这些驱动往往具有类似的结构,根据面向对象的思想,我们就可以将这些共同的部分提取为父类,这个父类就是kobject,也就是驱动编程中使用的.ko文件的由来,下面这张图是我根据内核源码的kobject绘制的简单的UML图,从中可以看出,kobject包含了大量的设备必须的信息,而三大类设备驱动都需要包含这个kobject结构,也就是"继承"自kobject。一个kobject对象就对应sys目录中的一个设备。
内核源码中的kobject结构定义如下


这个结构中,name(64)表示kobject对象的名字,对应sysfs下的一个目录。entry(65)是kobject中插入的head_list结构,parent(66)是指向当前kobject父对象的指针,体现在sys结构中就是包含当前kobject对象的目录对象,kset(67)表示当前kobject对象所属的集合,ktype(68)表示当前kobject的类型。sd(69)用于表示VFS文件系统的目录项,是设备与文件之间的桥梁。kref(70)是对kobject的引用计数,当引用计数为0是,就回调之前注册的release方法释放该对象。state_initialized:1(74)初始化标志位,在对象初始化时被置位,表示对象是否已经被初始化。state_in_sysfs:1(75)表示kobject对象在sysfs中的状态,在对应目录中被创建则置1,否则为0。state_add_uevent_sent:1(76)是添加设备的uevent事件是否发送标志,添加设备时会向用户空间发送uevent事件,请求新增设备。state_remove_uevent_sent:1(76)是删除设备的uevent事件是否发送标志,删除设备时会向用户空间发送uevent事件,请求卸载设备


4.8.5的内核在lib/koject.c等源码中定义了一系列对kobject操作的函数,这里只列出最简单的几个


kset表示一组kobject的集合,这些kobject可以是不同或相同的类型(ktype)。sysfs中的设备组织结构很大程度上都是根据kset进行组织的,比如在平台设备模型中,当我们注册一个设备或驱动到平台总线,其实是将对应的kobject挂接到platform总线的kset上,每种总线都是维护两条链表(两个kset),一条用于链接挂接在上面的驱动(驱动kset),一条用于链接挂接在上面的设备(设备kset)。


list_head(169)还是那个用来挂在链表上的结构。kobj(171)是归属于该kset的所有的kobject的共有parent,这个parent就是体现内核设备组织结构的关键


这个结构主要是表征kobject的类型,其中,release(117)是一个释放kobject对象的接口,有点像面向对象中的析构。sysfs_ops(118)是操作kobject的方法集。由此可见,对同一类型的kobject操作会回调同一个kobj_type的方法


从这个函数中可以看出,4.8.5提取kobject的ktype的时候直接提取kobject的,我还测试过3.14版本的,也是这种写法,不过网上还有下面的这种get_ktype的实现,还没找到具体是哪个版本,显然,这个版本中kset中的ktype这个类型优先于 kobject 自身中的 ktype 。因此在典型的应用中, 在 struct kobject 中的 ktype 成员被设为 NULL, 而 kset 中的ktype是实际被使用的。


kobject,kset是Linux设备管理中的基本结构体,但在实际操作中我们几乎不会实际操作这些结构,因为他们本身并不具有针对某一个具体设备或驱动的信息,在Linux内核中,两个结构都是被包含具体的设备结构中,比如cdev,gendisk等,从面向对象的角度考虑,就是每一类设备都可以看作这两个结构的子类。
通过上面的分析,我们可以看出这三者之间的关系,并画出下面的结构框图,sysfs中的上目录结构就是根据kset之间的数据组织方式进行呈现的。



】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Quartz实现任务调度 下一篇Linux网络驱动--snull

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目