1 kobject
1.1 kobject数据结构
kobject是sysfs文件系统的基础数据结构,它定义在include/linux/kobjec.h中
struct kobject {
/*名称*/
const char *name;
/*与与所属的kset(list成员)组成链表*/
struct list_head entry;
/*父kobject;此成员未指定时,默认指向所属kset的kobject成员;在/sys文件系统中表示目录的上一层*/
struct kobject *parent;
/*指向所属的kset,可为NULL*/
struct kset *kset;
/*提供操作kobject属性特征(attribute)的接口*/
struct kobj_type *ktype;
/*sys文件信息*/
struct sysfs_dirent *sd;
/*kobject的引用计数*/
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;
};
kset的定义如下:
struct kset {
/*与子kobject的entry成员组成链表*/
struct list_head list;
/*自旋锁*/
spinlock_t list_lock;
/*kobject*/
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
};
kobj_type的定义如下:
struct kobj_type {
/*释放函数*/
void (*release)(struct kobject *kobj);
/*sys文件操作函数*/
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);
};
sysfs_direct被定义在fs/sysfs/sysfs.h,它的定义如下:
struct sysfs_dirent {
atomic_t s_count;
atomic_t s_active;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
/*上级目录*/
struct sysfs_dirent *s_parent;
struct sysfs_dirent *s_sibling;
/*名称*/
const char *s_name;
const void *s_ns; /* namespace tag */
union {
struct sysfs_elem_dir s_dir;
struct sysfs_elem_symlink s_symlink;
struct sysfs_elem_attr s_attr;
struct sysfs_elem_bin_attr s_bin_attr;
};
unsigned int s_flags;
unsigned short s_mode;
ino_t s_ino;
struct sysfs_inode_attrs *s_iattr;
};
1.2 Kobject创建流程
我们看一下kobject的初始化过程。
初始化kobject有两种方式,分别是用kobject_init_and_add和kobject_create_and_add函数,他们的区别是:
1)kobject_init_and_add传入一个kobject指针和kobj_type指针,然后进行初始化
2)kobject_create_and_add创建一个kobject变量,并返回其指针,它不用传入kobj_type指针
1.2.1 kobject_init_and_add
下面看kobject_init_and_add函数的实现:
/**
* kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy
* @kobj: pointer to the kobject to initialize
* @ktype: pointer to the ktype for this kobject.
* @parent: pointer to the parent of this kobject.
* @fmt: the name of the kobject.
*
* This function combines the call to kobject_init() and
* kobject_add(). The same type of error handling after a call to
* kobject_add() and kobject lifetime rules are the same here.
*/
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...)
{
va_list args;
int retval;
kobject_init(kobj, ktype);
va_start(args, fmt);
retval = kobject_add_varg(kobj, parent, fmt, args);
va_end(args);
return retval;
}
它首先调用了kobject_init函数,再调用kobject_add_varg函数。先看kobject_init函数的实现:
/**
* kobject_init - initialize a kobject structure
* @kobj: pointer to the kobject to initialize
* @ktype: pointer to the ktype for this kobject.
*
* This function will properly initialize a kobject such that it can then
* be passed to the kobject_add() call.
*
* After this function is called, the kobject MUST be cleaned up by a call
* to kobject_put(), not by a call to kfree directly to ensure that all of
* the memory is cleaned up properly.
*/
void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
{
char *err_str;
if (!kobj) {
err_str = "invalid kobject pointer!";
goto error;
}
/*ktype不能为NULL*/
if (!ktype) {
err_str = "must have a ktype to be initialized properly!\n";
goto error;
}
if (kobj->state_initialized) {
/* do not error out as sometimes we can recover */
printk(KERN_ERR "kobject (%p): tried to init an init