在linux内核版本2.5新出现了/sys 目录,此目录结构向用户展现了设备驱动模型的层次结构。/sys 提供了一个设备驱动与用户之间的交互接口,对应于sysfs 虚拟文件系统。其中的每一个目录都对应一个内核对象kobject。目录中存在的文件对应一个属性。目录为用户展现了总线,设备,驱动之间的层次关系,属性文件为用户提供了操控设备驱动的友好接口。 接下来讨论设备模型 主角 struct kobject 路径 /include/linux/kobject.h (tapas:在内核中要想使用struct kobject 必须#include <linux/kobject.h> 可以发现include linux 正好就是源码的路径名)
先来介绍一下其中的成员变量:
const char *name: (tapas:const char *类型表示该指针指向的内容不可以被更改)。在内核中它指向的内容经常是使用kmalloc申请得到内存空间。所以在释放该对象时,必须kfree。前面提到kobject对应/sys的一个目录,那么可以猜出来,name表示对应目录的名称。
struct list_head entry: 内核链表,常用于把属于同一目录下目录链接起来。目录层次关系的体现。
strutc kobject *parent:同样表示一个目录,该成员指向它的父目录。伪代码解释:struct object *c,*p; c为目录,p也为目录。 如果c->parent = p; 那么 p为c的父目录。
struct kset *kset: 是设备模型中的一个重要结构。以后阐述。
struct kobj_type *ktype: 用于实现/sys 中的属相文件,其中包含了读写对应文件的操作函数。
struct sysfs_dirent *sd:设备模型中/sys虚拟文件系统与设备驱动借口的关联。当使用readwrite系统调用读写/sys中的文件是,就会通过该它调用到 ktype对用的操作函数。具体实现方法需要学习/sys虚拟文件系统。
struct kref: 是reference count的缩写(引用次数)。每次使用该对象会将该值++,取消引用该变量都会--。如果--后该变量为0,就会release(释放)该对象该对象也就随之消失。
对成员的介绍到此为止。写下来写几个内核模块,加以讨论。
上述代码加入内核后会在/sys/目录下产生 ./my_kobj 目录。
kobject_create_and_add终会调用到这里。kobject_add_varg做三件事情1.设置kobject->name.2.设置kobject->parent标志层次关系; 3.将kobject加入到系统中。
kobject_add_internal 主要做
主要做两件事情,1.根据kobject根据情况判定parent的设置。在后面的kset章加以讲解。2.根据
设置好的kobject为其在/sys创建目录项。
在此处提一下kobject_get() 和 kobject_put() 次两个函数 用于操作kobject->kref应用数 前者对kref
进行atomic_inc加1操作。后者进行atomic_dec减1操作。如果减到0就会执行 void (*release)(struct kref *kref)
函数。 在此函数中会根据kref得到他所在的kobject然后调用kobject_cleanup(struct kobject *kobj)对其进行释放。只要调用这个函数 那么该内核对象就在内核中彻底销声匿迹了。kobject_cleanup的实现在后面章节解释。