日期:2014-05-16  浏览次数:20750 次

Linux设备模型分析之kset(基于3.10.1内核)

作者:刘昊昱 

博客:http://blog.csdn.net/liuhaoyutz

内核版本:3.10.1

 
一、kset结构定义
kset结构体定义在include/linux/kobject.h文件中,其内容如下:
142/**
143 * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
144 *
145 * A kset defines a group of kobjects.  They can be individually
146 * different "types" but overall these kobjects all want to be grouped
147 * together and operated on in the same manner.  ksets are used to
148 * define the attribute callbacks and other common events that happen to
149 * a kobject.
150 *
151 * @list: the list of all kobjects for this kset
152 * @list_lock: a lock for iterating over the kobjects
153 * @kobj: the embedded kobject for this kset (recursion, isn't it fun...)
154 * @uevent_ops: the set of uevent operations for this kset.  These are
155 * called whenever a kobject has something happen to it so that the kset
156 * can add new environment variables, or filter out the uevents if so
157 * desired.
158 */
159struct kset {
160    struct list_head list;
161    spinlock_t list_lock;
162    struct kobject kobj;
163    const struct kset_uevent_ops *uevent_ops;
164};


从注释可以看出,kset是一组kobject的集合,这些kobject可以具有不同的“types”,下面来看kset的成员变量:
list用于将该kset下的所有kobject链接成一个链表。
list_lock是一个自旋锁,在遍历该kset下的kobject时用来加锁。
kobj是代表该kset的一个kobject。
uevent_ops是一组函数指针,当kset中的某个kobject状态发生变化需要通知用户空间时,就通过这些函数来完成。uevent_ops是struct kset_uevent_ops类型,该结构体定义在include/linux/kobject.h文件中,其定义如下:
123struct kset_uevent_ops {
124    int (* const filter)(struct kset *kset, struct kobject *kobj);
125    const char *(* const name)(struct kset *kset, struct kobject *kobj);
126    int (* const uevent)(struct kset *kset, struct kobject *kobj,
127              struct kobj_uevent_env *env);
128};


关于kset_uevent_ops结构体中的成员函数的作用,我们后面再分析。
 
二、kset的创建和注册
要创建并注册一个kset,使用的是kset_create_and_add函数,该函数定义在lib/kobject.c文件中,其内容如下:
827/**
828 * kset_create_and_add - create a struct kset dynamically and add it to sysfs
829 *
830 * @name: the name for the kset
831 * @uevent_ops: a struct kset_uevent_ops for the kset
832 * @parent_kobj: the parent kobject of this kset, if any.
833 *
834 * This function creates a kset structure dynamically and registers it
835 * with sysfs.  When you are finished with this structure, call
836 * kset_unregister() and the structure will be dynamically freed when it
837 * is no longer being used.
838 *
839 * If the kset was not able to be created, NULL will be returned.
840 */
841struct kset *kset_create_and_add(const char *name,
842                 const struct kset_uevent_ops *uevent_ops,
843                 struct kobject *parent_kobj)
844{
845    struct kset *kset;
846    int error;
847
848    kset = kset_create(name, uevent_ops, parent_kobj);
849    if (!kset)
850        return NULL;
851    error = kset_register(kset);
852    if (error) {
853        kfree(kset);
854        return NULL;
855    }
856    return kset;
857}


828行,从注释可以看出,kset_create_and_add函数的作用是动态创建一个kset结构并把它注册到sysfs文件系统中。注意该函数的三个参数:
name是kset的名字,它会被赋值给kset.kobj.name。
uevent_ops是struct kset_uevent_ops变量,它会被赋值给kset.uevent_ops。
parent_kobj是该kset的父kobject,它会被赋值给kset.kobj.parent。
848行,调用kset_create函数动态创建kset结构并对其进行初始化,该函数定义在lib/kobject.c文件中,其内容如下:
783/**
784 * kset_create - create a struct kset dynamically
785 *
786 * @name: the name for the kset
787 * @uevent_ops: a struct kset_uevent_ops for the kset
788 * @parent_kobj: the parent kobject of this kset, if any.
789 *
790 * This function creates a kset structure dynamically.  This structure can
791 *