设备驱动模型之:kobject,kset,ktype(一)

概述
kobject结构是linux驱动程序的基础,也是设备模型中抽象的一部分。如果想要了解驱动程序必须了解kobject结构的具体数据组成以及kobject结构的作用。内核为了兼容各种形形色色的设备,必须对各种设备的共同特性进行抽象。这种抽象在C++中称之为基础类,但是C语言没有继承特性,所以需要把此结构体嵌入到要抽象的结构体之中。
例如:字符设备驱动的cdev结构,使用的就是kobject的计数功能,他是把kobject结构体嵌入到struct cdev结构中,如下:

struct cdev {
	/**把kobject结构体嵌入到struct cdev结构体中**/
        struct kobject kobj;
        struct module *owner;
        const struct file_operations *ops;
        struct list_head list;
        dev_t dev;
        unsigned int count;
};

struct cdev结构体怎么使用struct kobject结构体的计数功能呢?具体如下:

 	1.在cdev_init中调用kobject_init初始化kobj的kref
 	2.在cdev_get和cdev_put中分别对于kobj的kref引用计数进行操作; 

那么kobject的作用有哪些呢?除了上面提到的对于对象的引用计数还有什么功能呢?
1、sysfs 表述:在 sysfs 中出现的每个对象都对应一个 kobject, 它和内核交互来创建它的可见表述。
2、数据结构关联:整体来看, 设备模型是一个极端复杂的数据结构,通过其间的大量链接而构成一个多层次的体系结构。kobject 实现了该结构并将其聚合在一起。
3、热插拔事件处理 :kobject 子系统将产生的热插拔事件通知用户空间。
4.对象的引用计数;
以下是kobject结构体的具体表述:

struct kobject {
	/*name:   用来表示内核对象的名称,如果该内核对象加入到系统,那么它的name
	就会出现在sys目录下。***/
        const char              *name;
        /***entry:用来将一系列的内核对象kobject连接成链表**/
        struct list_head        entry;
        /**parent:用来指向该内核对象的上层节点,从而可以实现内核对象的层次化结构*/
        struct kobject          *parent;
        /*用来执行内核对象所属的kset。kset对象用来容纳一系列同类型的kobject*/
        struct kset             *kset;
        /***ktype:    用来定义该内核对象的sys文件系统的相关操作函数和属性。*/
        struct kobj_type        *ktype;
        /**sd:用来表示该内核对象在sys文件系统中的目录项实例*/
        struct sysfs_dirent     *sd;
        /***kref:其核心是原子操作变量,用来表示该内核对象的引用计数。*/
        struct kref             kref;
        
        unsigned int state_initialized:1;
        unsigned int state_in_sysfs:1;
        unsigned int state_add_uevent_sent:1;
        unsigned int state_remove_uevent_sent:1;
        unsigned int uevent_suppress:1;
};
	/*****
	state_initialized: 用来表示该内核对象的初始化状态,1表示已经初始化,0
	表示未初始化。
	state_in_sysfs:   用来表示该内核对象是否在sys中已经存在。
	state_add_uevent_sent: 用来表示该内核对象是否向用户空间发送了		ADD uevent事件
	state_remove_uevent_sent:用来表示该内核对象是否向用户空间发送了Remove 	uevent事件
	uevent_suppress: 用来表示该内核对象状态发生改变时,时候向用户空间发送	uevent事件,1表示不发送。

以上信息还不能全部描述出来全部的kobject的作用,需要结合struct kset 和struct kobj_type来进行描述,如下:

struct kset {
	/**对于每一个kset下对应的kobject链表描述,链接的是实体的kobject**/
        struct list_head list;
    	/**锁操作***/
        spinlock_t list_lock;
        /**每一个kset下都有一个kobject描述**/
        struct kobject kobj;
        /**kset的操作;***/
        const struct kset_uevent_ops *uevent_ops;
};
	/**以下是对于kobj_type描述**/
struct kobj_type {
        void (*release)(struct kobject *kobj);
        const struct sysfs_ops *sysfs_ops;
        struct attribute **default_attrs;
        const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
        const void *(*namespace)(struct kobject *kobj);
};

kobject和kset还有ktype对应的关系:

在这里插入图片描述
对于以上对应的关系可以简单理解为:
1.kset和kobject在内核中存在相当于是在/sys/目录下创建了文件夹;
2.kobj_type操作就比较复杂一点:可以操作文件的读取写入,还有控制kobject/kset模块的释放;
3.对于kobj_type的attribute属性来说是创建了一系列的文件,可供读写,它的表示是一个数组,每一个数组元素代表创建文件以及文件的读写权限,但是文件的操作不使用attribute属性,而是使用sysfs_ops属性;

猜你喜欢

转载自blog.csdn.net/weixin_37867857/article/details/84722837