Linux设备模型(3)基本组件Kobject、ksets、ktypes

前言

“Everything you never wanted to know about kobjects, ksets, and ktypes”。-Greg Kroah-Hartman

kobject、ksets、ktype是整个设备模型的基础组件,类似钢筋水泥之于高楼大厦,所以我们首先需要对其基本结构和功能有所了解。

kobject.txt文档中对三者的描述如下:

  • A kobject is an object of type struct kobject. Kobjects have a name and a reference count. A kobject also has a parent pointer (allowing objects to be arranged into hierarchies), a specific type, and,
    usually, a representation in the sysfs virtual filesystem.
    Kobjects are generally not interesting on their own; instead, they are usually embedded within some other structure which contains the stuff the code is really interested in.
    No structure should EVER have more than one kobject embedded within it. If it does, the reference counting for the object is sure to be messed up and incorrect, and your code will be buggy. So do not do this.
  • A ktype is the type of object that embeds a kobject. Every structure that embeds a kobject needs a corresponding ktype. The ktype controls what happens to the kobject when it is created and destroyed.
  • A kset is a group of kobjects. These kobjects can be of the same ktype or belong to different ktypes. The kset is the basic container type for collections of kobjects. Ksets contain their own kobjects, but you can safely ignore that implementation detail as the kset core code handles this kobject automatically.

上述解释可能看起来比较让人迷惑,这里形象的解释一下。以猫咪为例,一个kobject表示一个猫咪(喵喵);ktype就表示喵喵的能力,如跑、跳、打滚;kset表示猫这个物种。
在这里插入图片描述

数据结构分析

kobject、kset、kobj_type三个结构体关系如下:
在这里插入图片描述

kset

  • struct list_head list; 用于保存该kset下所有的kobject的链表
  • spinlock_t list_lock; 操作kobject链表的自旋锁
  • struct kobject kobj; 当前kset对应kobject,kset是一个特殊的kobject,也会在sysfs中以目录的形式体现
  • struct kset_uevent_ops *uevent_ops; 该kset的uevent操作函数集。当任何Kobject需要上报uevent时,都要调用它所从属的kset的uevent_ops,添加环境变量,或者过滤event(kset可以决定哪些event可以上报)。因此,如果一个kobject不属于任何kset时,是不允许发送uevent的。

kobject

  • name,该Kobject的名称,同时也是sysfs中的目录名称。由于Kobject添加到Kernel时,需要根据名字注册到sysfs中,之后就不能再直接修改该字段。如果需要修改Kobject的名字,需要调用kobject_rename接口,该接口会主动处理sysfs的相关事宜。
  • entry,用于将Kobject加入到Kset中的list_head。
  • parent,指向parent kobject,以此形成层次结构(在sysfs就表现为目录结构)。
  • kset,该kobject属于的Kset。可以为NULL。如果存在,且没有指定parent,则会把Kset作为parent(别忘了Kset是一个特殊的Kobject)。
  • ktype,该Kobject属于的kobj_type。每个Kobject必须有一个ktype。
  • sd,该Kobject在sysfs中的表示。
  • kref,"struct kref”类型(在include/linux/kref.h中定义)的变量,为一个可用于原子操作的引用计数。
  • state_initialized,指示该Kobject是否已经初始化,以在Kobject的Init,Put,Add等操作时进行异常校验。
  • state_in_sysfs,指示该Kobject是否已在sysfs中呈现,以便在自动注销时从sysfs中移除。
  • state_add_uevent_sent/state_remove_uevent_sent,记录是否已经向用户空间发送ADD uevent,如果有,且没有发送remove uevent,则在自动注销时,补发REMOVE uevent,以便让用户空间正确处理。
  • uevent_suppress,如果该字段为1,则表示忽略所有上报的uevent事件。

ktype

  • release,将包含该种类型kobject的数据结构的内存空间释放掉。
  • sysfs_ops,该种类型的Kobject的sysfs文件系统接口。
  • default_attrs,该种类型的Kobject的atrribute列表(所谓attribute,就是sysfs文件系统中的一个文件)。将会在Kobject添加到内核时,一并注册到sysfs中。
  • child_ns_type/namespace,和文件系统(sysfs)的命名空间有关。

使用与实验

实验1:创建一个kset

流程如下:

  1. 定义一个kset类型的指针变量;
  2. 调用``struct kset *kset_create_and_add(const char *name, const struct kset_uevent_ops *uevent_ops, struct kobject *parent_kobj)```,创建一个kset并返回结构体指针;
	struct kset *k_set = NULL;
	k_set = kset_create_and_add("i_kset", NULL, NULL);

实验效果如下:

在这里插入图片描述

实验2:注销一个kset

在实验1的基础上,注销掉i_kset。

	kset_unregister(k_set);

实验效果如下:

实验1中注册的i_kset已经被注销。
在这里插入图片描述

实验3:创建一个kobject

在实验1的基础上,创建一个i_kset的子节点i_kobject。

	struct kobject *k_object = NULL;
	k_object = kobject_create_and_add("i_kobject", &k_set->kobj);

实验效果如下:

在这里插入图片描述

实验4:注销一个kobject

在实验3的基础上,注销i_kobject。

	kobject_put(k_object);

实验效果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值