之前几章将sysfs的结构体关联、sysfs文件系统注册及挂载、sysfs目录创建接口、sysfs文件创建接口,基本上也算把一个文件系统相关的操作简略的梳理了一遍。下面我们就主要分析一下kobject相关接口,kobject相关的接口被设备驱动模块调用,用以实现设备驱动模型(如bus、device、driver、class),因此本章将介绍kobject相关的结构体关联以及kobject相关的接口。
kobject及其关联的结构体介绍
下面是一个kobject和该kobject的属性之间的关联图(该图在上一章已经介绍过),通过该图我们可以得到如下几个方面的信息:
一、kobject本身包含了引用计数、对象本身的type方法(包括对象的release、对象属性的通用读写接口等),kobject与sysfs_dirent的关联;
二、kobject与其属性之间的关联,一个kobject对应sysfs中的一个目录,而kobject的各属性参数则对应sysfs中的文件;而针对kobejct属性的访问操作通过对象提供的type方法中的接口实现读写操作。
三、kobject属性文件与vfs、进程描述符的关联等。
四、kset是一类kobject的组合,这些kobject通过链表链接到kset的list链表中。
在linux的设备模型中,kset、kobject是bus、driver、device、class等实现的基础。
kobject相关接口分析
下面我们分析kobject相关的接口,主要包括kobject创建、ktype的设置、kobject相关的属性文件创建等接口。
kobject_create
该接口主要是创建一个kobject,并对其进行初始化操作,该接口的具体功能如下:
- 调用kzalloc创建一个kobject
- 调用kobject_init对该kobject进行初始化(初始化引用计数、初始化链表、初始化状态信息),将该kobject的ktype成员设置为默认变量dynamic_kobj_ktype。
针对一个kobject,若没有指定ktype,则使用dynamic_kobj_ktype作为其ktype,dynamic_kobj_ktype的定义如下:
static struct kobj_type dynamic_kobj_ktype = {
.release = dynamic_kobj_release,
.sysfs_ops = &kobj_sysfs_ops,
};
const struct sysfs_ops kobj_sysfs_ops = {
.show = kobj_attr_show,
.store = kobj_attr_store,
};
其中dynamic_kobj_release则主要是调用kfree释放kobject对象,而kobj_attr_show、kobj_attr_store这两个接口,则主要是在打开kobject属性文件时,根据传递的attribute类型变量获取kobj_attribute类型的变量,从而调用kobj_attribute->show/store接口,实现调用具体属性文件的读写接口。
kobject_create_and_add
该接口通过调用kobject_create创建一个对象,然后调用kobject_add为该kobject创建目录,并设置该kobject的父对象已经将该kobject链接至kset链表中(kset存在的话),该接口的流程图如下
- 创建一个kobject并初始化;
- 调用kobject进行添加操作:
- 若kset存在,则将该kobject链接至kset链表中
- 调用sysfs_create_dir,为该kobject创建目录;
- 调用sysfs_create_file,为该kobject的默认属性参数创建文件。
以下流程图未做错误处理,该流程图基本上说明了该接口的具体实现流程。
kobject_init_and_add
该接口主要实现是对一个已创建的kobject进行初始化,并为该kobject创建目录及属性文件等功能,该接口具体实现的功能如下:
1.该接口主要调用kobject_init对kobject进行初始化;
2.调用kobject_add_varg执行kobject的添加操作,关于kobject_add_varg在上一个接口中已经介绍,此处不再细说。
kobject_put
该接口主要是释放对一个kobject的引用,若引用计数为0,则将该kobject的内存进行释放,下面我们分析下这个接口。
该接口实现的功能,根据我们创建时的定义也可以知道个大概,即删除创建的sysfs目录、文件等信息、删除与父目录、kset的关联、释放kobject相关的内存等。
kset_create
该接口主要用于创建一个kset变量,并对其进行初始化操作。该接口的实现相对比较简单,即创建kset并初始化kset以及其kobject变量等内容。
kset_create_and_add
该接口主要调用kset_create创建一个kset,并调用kset_register注册一个kset(包括对kset创建sysfs 目录以及相应的默认属性文件等内容)
kset_unregister
该接口主要是释放一个kset,其通过调用kobject_put实现kset、kset对应kobject的释放操作,而kobject_put我们在前面已经分析过,此处不再细说。
void kset_unregister(struct kset *k)
{
if (!k)
return;
kobject_put(&k->kobj);
}
以上即为kobject、kset相关的接口分析,包括了kobject、kset创建与删除等操作接口。其实这些添加与删除接口也就是建立或删除kobject、kset、sysfs_dirent、kobj_type、kref等结构体变量的关联罢了。只要我们对这些结构体变量之间关联理清了,对这些接口的实现也基本上了然于胸了。本次基本上完成了sysfs的介绍,下面开始介绍linux设备模型相关的内容。