linux设备模型介绍
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第一节基本概念
在设备模型里面,所有的东西都是kobject,这也是linux建立设备设计模型的目的(对比2.4之前),实现了统一的实体;我们理解上,却可以分为两个层次,一个是kobject,一个是管理kobject的kobject(可以把它叫做kset虽然有点绕,但是没有办法了,毕竟就像那个“世界上先有鸡还是先有蛋的哲学问题一下”);
kobject结构
1)前面两个顾名思义,就是name了,为什么会有两个呢?k_name就是指向name的,如何知道呢,呵呵,看一下代码
2)kref就是一个内核的原子计数结构,因为涉及内核的操作基本都需要是原子性的,为了大家的方便,kobject就把它包括进来了,所以大家就不必要各自定义自己的计数了(一般情况下:),poll也是类似,把等待队列包括进来;
3)entry 这个名字比较让人误解,其实看它的类型知道是list成员,它就是加入到kset的list 的那个零部件;
4)ktpye 要理解这个成员就稍微麻烦些了,先看一下定义
Default_attrs就是一种比较简单的设置属性文件的方法,它其实跟我们自己调用sysfs_create_file没有什么区别,呵呵,看一下代码就知道了,所以大家基本上可以把它忽略掉:),调用关系为kobject_add->create_dir->populate_dir
把一个忽略掉,剩下的两个就比较重要了;每个对象一般都有多个属性,用面向对象的角度来看,我们可以把对属性的操作抽象为show和store这一对方法,那么多个属性就会有多对show和store的方法;那么,为了实现对这些方法的统一调用,就利用ktype中的sysfs_ops 实现了多态;这样一来,对于sysfs中的普通文件读写操作都是由kobject->ktype->sysfs_ops
来完成的;release也是类似,大部分的设备在退出的时候也是需要清理资源的,这里也实现多态(不过和上面的那个多态实现上有所区别:),在kobject释放的时候,会调用一下这个release(如果不为NULL的话),如下:
所以我们基本上可以这样理解,ktpye就是把kobject的一些方法给拿了出来,实现了这些方法的多态的统一接口;其实看名字ktpye大概也理解得到:),看一下get_ktpye函数的实现,一个kobject的ktype是优先选择kset->ktpye,如果它为NULL的话,才会去用kobject自己的ktpye,所以说,kset是管理kobject的kobject,就像一个小孩首先要有父母管,父母不管的话,那就自己管,但是自己都不管自己的话,那就麻烦了;这种情况是存在的,kobject 是可以没有ktpye的,这样的话相当于没有对外的属性接口和release方法了;
5)parent 这个就好理解了,就是形成sys的树形结构,在sysfs中每一个目录都对应一个kobject.这些kobject都有自己的parent。在没有指定parent的情况下,都会指向它所属的kset->object,要是这个也没有的话,那就会向组织靠拢,直接挂到/sys目录下;注意,这里的优先级顺序跟前面的那个ktpye是相反的;
6)Dentry 我们可以先不用太关心,大概知道dentry是跟文件系统目录有关的就可以了管理kobject的kojbect(即是kset)
1)subsys这个概念基本上就是kset的概念,在比较新的内核版本里面已经去掉了,所以忽
略它
2)Ktype 这个在介绍kobject的时候已经讲过了,这里只说一点,kset里面也有一个kobject,那么这个kobject里面也会有一个ktype,表明这个kset(其实也是kobject)的ktype是什么,大家不要把这两个概念混淆;
3)List 就是用来管理kobject的链表头
4)Uevent_ops 又是一个麻烦的东西,看一下定义
里面无非就是些函数指针,作用是什么呢?要讲清楚的话,就得费一番功夫了,且容我一一道来:)
前面说过,现在的内核驱动模型里面,所有的东西都是kobject,以前的/dev目录是由内核维护的(现在时代不同了,什么东西都得热插拔,甚至包括cpu),今天/dev的维护工作交给了一个叫做/sbin/udevd的用户进程(udev文件系统是针对2.6 内核,提供一个基于用户空间的动态设备节点管理和命名的解决方案),但是任何东西都是从底下向上面传递的,内核需要一个机制向用户态发送消息,确切的说是kobject需要一个途径向用户态传递,那么这个途径便是uevent ops了;但是为什么它不放到kobject或者ktpye里面呢?其实我也说不太上来,套用我前面说的那个概念就是这个kset是一个管理kobject的kobject吧:)
当一个kobject的事件发生时(比如创建或者删除等等),就会调用到一个叫做kobject_uevent 的接口,如下
这个接口里面有一个比较关键的地方或许能够进一步帮助我们理解kset的功能,
可以看出来,代码里面会尽力(不断向上循环,找parent的parent等等)找到管理这个kobject 的kset或者是kobject的parent的kset或者是parent的parent的等等,,然后得到它的uevent ops(它有可能为NULL),所以从这里大概能够感觉到这个kset(管理kobject的kobject)的重要性了,其实也可以没有,但是什么都没有的话,那我们就什么功能都没有实现了:)
最后,会通过netlink发送到用户态,代码如下
讲到这里,终于可以告一段落了,总结一下,就是开始讲的那一句话:
所有的东西都是kobject,理解上可以分为两个层次,一个是kobject,一个是管理kobject 的kobject
有了这些基本概念后,下一节给大家讲讲具体实践(字符设备和块设备)