第十四章--Linux设备模型
本章将对设备模型从下向上进行讲述。
一、Kobject、kset和子系统
kobject是组成设备模型的基本结构。现在kobject结构所能处理的任务以及它所支持的代码包括:
1、对象的引用计数
通常,一个内核对象被创建时,不可能知道该对象存活的时间。跟踪此对象申明周期的一个方法是使用引用计数。当内核中没有代码持有该对象的引用时,该对象将结束自己的有效生命周期,并且可以被删除。
2、sysfs表述
在sysfs中显示的每一个对象,都对应一个kobject,它被用来与内核交互并创建它的可见表述。
数据结构关联:
从整体上看,设备模型是一个友好而复杂的数据结构,通过在其间的大量连接而构成一个多层次的体系结构。kobject实现了该结构并把它们聚合在一起。
3、热插拔事件处理
当系统中的硬件被热插拔时,在Kobject子系统控制下,将产生事件以通知用户空间。
1.1、Kobject基础知识
Kobject是一种数据结构。一个Kobject对自身并不感兴趣,它存在的意义在于把高级对象连接到设备模型上。
void kobject_init(struct kobject *kobj):设置Kobject的引用计数为1。
只要对象的引用计数窜在,对象(以及支持它的代码)就必须继续存在。
kobject_init()设置引用计数为1,所以当常见Kobject时,如果不再需要初始的引用,就要调用相应的kobject_put函数。
一个被Kobject所保护的结构,不能在驱动程序生命周期的任何可预知的、单独的时间点上被释放掉。但是当Kobject的引用计数为0时,上述代码又要随时准备运行。引用计数不为创建Kobject的代码所控制。因此当Kobject的最后一个引用计数不再存在时,必须异步的通知。
每一个Kobject都必须有一个release方法,并且Kobject在该方法被调用前必须保持不变(处于稳定状态)。
每个Kobject都需要有一个相应的kobj_type结构。
1.2、Kobject层次结构、kset和子系统
通常,内核用Kobject结构将各个对象连接起来组成一个分层的结构体系,从而与模型化的子系统相匹配。有两种独立的机制用于连接:parent指针和kset。
kset是嵌入相同类型结构的Kobject集合。
kset总是在sysfs中出现;一旦设置了kset并把它添加到系统中,将在sysfs中创建一个目录。
一个子系统其实是对kset和一个信号量的封装。每一个kset都必须属于一个子系统。
Kobject在sysfs中的入口始终是一个目录,因此,对Kobject_add的调用将在sysfs中创建一个目录,通常这个目录包含一个或多个属性。
分配给Kobject(使用Kobject_set_name函数)的名字是sysfs中的目录名。这样,处于sysfs分层结构相同部分中的kobject必须有唯一的名字,分配给Kobject的名字必须是合法的文件名,不能包含反斜杠,并且强烈将以不要使用空格。
1.3 属性
1.4、热插拔时间的产生
一个热插拔事件是从内核空间发送到用户空间的通知,它表明系统配置出现了变化。无论Kobject被创建还是被删除,
都会产生这种事件。
二、总线、设备和驱动程序
2.1、总线
总线是处理器与一个或者多个设备之间的通道。在设备模型中,所有的设备都通过总线相连。
2.2、设备
所有向核心注册的device结构都必须有一个release方法。
2.3、驱动
三、类
类是一个设备的高层视图,它抽象出了底层的实现细节。
类存在的真正目的是,给作为类成员的各个设备提供一个容器。
四、各环节的整合
4.1、kobject、kset、subsystem之间的关系
kobject是一个基类,kset是容器。关于kobject结构,首先每个目录代表一个kobject对象,每个文件代表kobject的属性。kobject是组成设备模型的基本结构。
对于每一个目录,它们都有一些共同的特点,比如都有名字,父子目录等。而对于“方法”来说,它们都有用来实现引用计数的方法。我们将这些有共同点的封装起来形成了基类。但是这个基类并不能真正的代表一个目录,加上了其它的特征之后才能成为一个真正的目录,所以我们需要将kobject这个结构嵌入所有sysfs下的目录中以获得kobject提供的一些特征,再加上每个目录自己所独有特征从而形成一个sysfs中的目录。因为每一次调用kobject_add函数,都会在这个函数中调用create_dir来创建一个目录,所以kobject结构对应一个目录。
kset是嵌入相同类型结构的kobject的集合,kset是用来将所有有着共同特点的目录联系在一起的东西。比如设备树下的spi总线目录/sys/bus/spi下挂接着很多设备和驱动,它们就是通过kset结构联系在一起的,kset
是/sys/bus/spi/drivers目录。linux操作系统每一条总线都有drives和devices两个目录。它们两个都是嵌入了kset结构。/sys/bus/spi/drivers目录中的某个具体驱动就是嵌入了kobject结构的目录。/sys/bus/spi目录就是subsystem结构的嵌入。现在subsystem已经被取消了,取代它的就是kset结构。这样也就是说一系列的kset就组成了subsystem。list_head能够只用kobject结构将挂接在同一条总线上的驱动或者设备都链接在一起。kset并不是必要存在的。示意图如下:
粉红色的箭头表明,kset children list用来将同类型的kobject连接起来以达到容器的效果。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。