日期:2014-05-16 浏览次数:20706 次
作者:刘昊昱
博客: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&