由kobject_create_and_add全面了解kobject
一、引言
从v2.6开始linux引入了统一的设备模型,用kobject数据结构来描述设备。有了kobject,设备间的拓扑关系就一目了然了,它为设备管理带来了很大的便利。最近学习到kobject_create_and_add(),通过对这个函数的学习,可以全面细致地了解到kobject。p.s.本文相关代码基于linux 5.4.74。内容有点多,读不下去请跳转至文章末尾。
二、kobject相关数据结构
首先,简单了解下kobject相关的数据结构。
kobject结构体如下所示:
//代码路径kernel5.4/include/linux/kobject.h
struct kobject {
const char *name; //name指针指向kobject的名称
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct kernfs_node *sd; /* sysfs directory entry */
struct kref kref; //kobject refcount 引用计数,为1引用,为0释放
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
struct delayed_work release;
#endif
//下面是一些标志变量,用位域的方式声明
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;
};
在这些成员变量中,ktype、kset、kref值得注意。它们是对一个kobject的描述、分类和引用标识。
2.1 ktype
ktype指针指向了一个kobj_type的数据结构,该数据结构如下代码段所示:
struct kobj_type {
void (*release)(struct kobject *kobj);//析构函数指针,指向析构函数,该函数在refcount为0时,清理所有”同类“的kobject并释放内存。
const struct sysfs_ops *sysfs_ops;//指针指向”sysfs读写操作函数结构体“
struct attribute **default_attrs;//指针指向attribute结构体数组,描述了属于该ktype的kobject的默认属性
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
const void *(*namespace)(struct kobject *kobj);
void (*get_ownership)(struct kobject *kobj, kuid_t *uid, kgid_t *gid);
};
kobj_type是对kobject的特性描述。ktype数据结构初始化将会在随后的kobject_init流程中看到。
2.2 kset
kset指针指向一个kset的数据结构,该数据结构如下代码段所示:
struct kset {
struct list_head list;//kset链表
spinlock_t list_lock;
struct kobject kobj;//该kset的基类(就是说该kset中的kobject都长这样)
const struct kset_uevent_ops *uevent_ops;//指针指向kset_uevent_ops结构体,用于处理kset中的kobject对象的热插拔操作。
} __randomize_layout;
kset是很多kobject的集合。一般来说,如果一个kobject属于某个kset,即kset->kobj是存在的,那么这个kset->kobj将作为该kobject的父对象。这一点在随后的kobject_add流程中体现。
2.3 kref
kref指针指向一个kref的数据结构,该数据结构如下代码段所示:
//路径/kernel5.4/linux/kref.h
struct kref {
refcount_t refcount;
};
kref引用计数来标示kobject的生命周期,在对象初始化时,调用kref_init()来使kref->refcount被原子置1(这一步将会在随后的kobject_init流程中看到)。引用了该kobject的代码都要进行引用计数加一。只要这个refcount不为0,该kobject就会继续被保留在内存中,否则对象将被撤销、内存被释放。
refcount的初始化、增加和减少分别用下面函数来实现:
//路径/kernel5.4/linux/kref.h
static inline void kref_init(struct kref *kref)
{
refcount_set(&kref->refcount, 1);

本文深入剖析Linux内核中kobject的概念及其实现原理,包括kobject相关的数据结构ktype、kset、kref,并详细介绍了kobject_create_and_add函数的工作流程。
最低0.47元/天 解锁文章
1742

被折叠的 条评论
为什么被折叠?



