@HUST张友东 work@taobao zyd_com@126.com
分类: LINUX
2011-02-22 20:03:41
内核中很多地方都需要跟踪记录C语言中结构的实例。尽管这些对象的用法大不相同,但各个子系统的某些操作都非常类似,如引用计数,内核为了减少代码复制,采用了一般性的方法来管理内核对象。所引入的框架并不只是为了减少代码复制,同时也为内核不同部分管理的对象提供了一致的视图。
一般性的内核对象机制可用于执行下列对象操作:
1. 引用计数;
2. 管理对象链表;
3. 集合加锁;
4. 将对象属性导出到用户空间(通过sysfs文件系统);
一般性的内核对象kobject
struct kobject {
const char * k_name; // 对象的文本名称
char name[KOBJ_NAME_LEN];
struct kref kref; // 引用计数的管理
struct list_head entry; // 链接多个kobject
struct kobject * parent; //指向父对象的指针,用于在kobject之间建立层次结构
struct kset * kset; // 对象所属的集合
struct kobj_type * ktype; // 包含kobject数据结构的更多详细信息
struct dentry * dentry;
wait_queue_head_t poll;
};
kobject数据结构嵌入到其它结构中,用作内核对象的基础。通过管理kobjcet即达到了对包含kobject的对象的管理。
内核提供了处理kobject的一套标准方法,包括:
kobject_get, kobject_put |
对kobject的引用计数器加1或减1 |
kobject_(un)register |
注册或删除对象,对象被添加到父对象现存的集合中,同时在sysfs中创建一个对应项 |
kobjcet_init |
初始化kobject对象 |
kobject_add |
初始化内核对象,并使之显示在sysfs中 |
kobject_cleanup |
在不需要kobject(以及包含kobjcet的对象)时,释放分配的资源 |
在很多情况下,必须将不同的内核对象归类到集合中(相同类型的对象拥有公共的kobj_type),例如所有字符设备集合,或所有基于PCI的设备集合,内核通过kset完成这一目标。
struct kset {
struct subsystem * subsys;
struct kobj_type * ktype; // ktype指向kset中各个内核对象公用的kobj_type结构
struct list_head list; // 同类型对象链表
spinlock_t list_lock;
struct kobject kobj; // 管理kset对象本身的内嵌kobject对象
struct kset_uevent_ops * uevent_ops;
};
kset是内核对象应用的第一个例子,kset中内嵌kobject结构,用于管理kset对象本身,与集合中包含的各个kobject对象并无关系。
引用计数用于检测内核中有多少个地方使用了某个对象。每当内核的一个部分需要某个对象所包含的信息时,则增加该对象的引用计数;如果不再需要相应的信息,则减少该对象的引用计数,当对象的引用计数为0时,内核知道不在需要该对象。
内核通过kref结构来管理引用计数
struct kref {
atomic_t refcount;
};
在kref的设计中,将一个值封装在结构中,防止直接操纵该值,需使用辅助方法kref_init(初始化), kref_get(加1), kref_put(减1)进行操作。