日期:2014-05-16 浏览次数:20859 次
作者:刘昊昱
博客:http://blog.csdn.net/liuhaoyutz
内核版本:3.10.1
一、kobject结构定义
kobject是Linux设备模型的最底层数据结构,它代表一个内核对象。
kobject结构体定义在include/linux/kobject.h文件中:
60struct kobject {
61 const char *name;
62 struct list_head entry;
63 struct kobject *parent;
64 struct kset *kset;
65 struct kobj_type *ktype;
66 struct sysfs_dirent *sd;
67 struct kref kref;
68 unsigned int state_initialized:1;
69 unsigned int state_in_sysfs:1;
70 unsigned int state_add_uevent_sent:1;
71 unsigned int state_remove_uevent_sent:1;
72 unsigned int uevent_suppress:1;
73};
name是这个内核对象的名字,在sysfs文件系统中,name将以一个目录的形式出现。
entry用于将该内核对象链接进其所属的kset的内核对象链表。
parent代表该内核对象的父对象,用于构建内核对象的层次结构。
kset是该内核对象所属的“内核对象集合”。
ktype是该内核对象的sysfs文件系统相关的操作函数和属性。
sd表示该内核对象对应的sysfs目录项。
kref的核心数据是一个原子型变量,用于表示该内核对象的引用计数。
state_initialized表示该内核对象是否已经进行过了初始化,1表示已经初始化过了。
state_in_sysfs表示该内核对象是否已经在sysfs文件系统中建立一个入口点。
state_add_uevent_sent表示加入内核对象时是否发送uevent事件。
state_remove_uevent_sent表示删除内核对象时是否发送uevent事件。
uevent_suppress表示内核对象状态发生变化时,是否发送uevent事件。
二、kobject初始化分析
分析kobject,我们从kobject_init_and_add函数开始看,该函数完成对kobject的初始化,建立kobject的层次结构,并将kobject添加到sysfs文件系统中,该函数定义在lib/kobject.c文件中,其内容如下:
360/** 361 * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy 362 * @kobj: pointer to the kobject to initialize 363 * @ktype: pointer to the ktype for this kobject. 364 * @parent: pointer to the parent of this kobject. 365 * @fmt: the name of the kobject. 366 * 367 * This function combines the call to kobject_init() and 368 * kobject_add(). The same type of error handling after a call to 369 * kobject_add() and kobject lifetime rules are the same here. 370 */ 371int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, 372 struct kobject *parent, const char *fmt, ...) 373{ 374 va_list args; 375 int retval; 376 377 kobject_init(kobj, ktype); 378 379 va_start(args, fmt); 380 retval = kobject_add_varg(kobj, parent, fmt, args); 381 va_end(args); 382 383 return retval; 384}
从注释中可以看出,kobject_init_and_add函数可以分为两部分,一个是kobject_init函数,对kobject进行初始化,另一个是kobject_add_varg函数,将kobject添加到kobject层次结构中。
先来看kobject_init函数,其定义如下:
256/**
257 * kobject_init - initialize a kobject structure
258 * @kobj: pointer to the kobject to initialize
259 * @ktype: pointer to the ktype for this kobject.
260 *
261 * This function will properly initialize a kobject such that it can then
262 * be passed to the kobject_add() call.
263 *
264 * After this function is called, the kobject MUST be cleaned up by a call
265 * to kobject_put(), not by a call to kfree directly to ensure that all of
266 * the memory is cleaned up properly.
267 */
268void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
269{
270 char *err_str;
271
272 if (!kobj) {
273 err_str = "invalid kobject pointer!";
274 goto error;
275 }
276 if (!ktype) {
277 err_str = "must have a ktype to be initialized properly!\n";
278 goto error;
279 }
280 if (kobj->state_initialized) {
281 /* do not error out as sometimes we can recover */
282 printk(KERN_ERR "kobject (%p): tried to init an initialized "
283 "object, something is seriously wrong.\n", kobj);
284 dump_stack();
285 }
286
287 kobject_init_internal(kobj);
288 kobj->ktype = ktype;
289 return;
290
291error:
292 printk(KERN_ERR "kobject (%p): %s\n&