概述
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属性;