--------------------------------------------------------
本文系本站原创,欢迎转载!
转载请注明出处:http://blog.csdn.net/gdt_a20
--------------------------------------------------------
一、sysfs文件系统下的每个目录对应于一个kobj,kset是kobj的封装,内嵌了一个kobj,其代表kset自身,ktype代表属性
操作集,但由于通用性,因此把ktype单独剥离出来,kobj,kset,ktype成为了各个驱动模型最底层的关联元素,并由此形成了sys下的各种
拓扑结构。
二、关于kobject
首先看一下kobject的原型
- struct kobject {
- const char *name;
- struct list_head entry;
- struct kobject *parent;
- struct kset *kset;
- struct kobj_type *ktype;
- struct sysfs_dirent *sd;
- 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;
- };
分析一下kobject的初始化过程
初始化函数为
- ---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;
- }
- ---void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
- {
- char *err_str;
- if (!kobj) {
- err_str = "invalid kobject pointer!";
- goto error;
- }
- if (!ktype) {
- err_str = "must have a ktype to be initialized properly!/n";
- goto error;
- }
- if (kobj->state_initialized) {
-
- printk(KERN_ERR "kobject (%p): tried to init an initialized "
- "object, something is seriously wrong./n", kobj);
- dump_stack();
- }
- kobject_init_internal(kobj);
- kobj->ktype = ktype;
- return;
- error:
- printk(KERN_ERR "kobject (%p): %s/n", kobj, err_str);
- dump_stack();
- }
- -------static void kobject_init_internal(struct kobject *kobj)
- {
- if (!kobj)
- return;
- kref_init(&kobj->kref);
- INIT_LIST_HEAD(&kobj->entry);
- kobj->state_in_sysfs = 0;
- kobj->state_add_uevent_sent = 0;
- kobj->state_remove_uevent_sent = 0;
- kobj->state_initialized = 1;
- }
- -------static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
- const char *fmt, va_list vargs)
- {
- int retval;
- retval = kobject_set_name_vargs(kobj, fmt, vargs);
- if (retval) {
- printk(KERN_ERR "kobject: can not set name properly!/n");
- return retval;
- }
- kobj->parent = parent;
- return kobject_add_internal(kobj);
- }
- ----static int kobject_add_internal(struct kobject *kobj)
- {
- int error = 0;
- struct kobject *parent;
- if (!kobj)
- return -ENOENT;
- if (!kobj->name || !kobj->name[0]) {
- WARN(1, "kobject: (%p): attempted to be registered with empty "
- "name!/n", kobj);
- return -EINVAL;
- }
- parent = kobject_get(kobj->parent);
-
- if (kobj->kset) {
- if (!parent)
- parent = kobject_get(&kobj->kset->kobj);
-
- kobj_kset_join(kobj);
- kobj->parent = parent;
- }
- pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'/n",
- kobject_name(kobj), kobj, __func__,
- parent ? kobject_name(parent) : "",
- kobj->kset ? kobject_name(&kobj->kset->kobj) : "");
- error = create_dir(kobj);
- if (error) {
- kobj_kset_leave(kobj);
- kobject_put(parent);
- kobj->parent = NULL;
-
- if (error == -EEXIST)
- printk(KERN_ERR "%s failed for %s with "
- "-EEXIST, don't try to register things with "
- "the same name in the same directory./n",
- __func__, kobject_name(kobj));
- else
- printk(KERN_ERR "%s failed for %s (%d)/n",
- __func__, kobject_name(kobj), error);
- dump_stack();
- } else
- kobj->state_in_sysfs = 1;
- return error;
- }
- ---static int create_dir(struct kobject *kobj)
- {
- int error = 0;
- if (kobject_name(kobj)) {
- error = sysfs_create_dir(kobj);
- if (!error) {
- error = populate_dir(kobj);
- if (error)
- sysfs_remove_dir(kobj);
- }
- }
- return error;
- }
三、关于 kset
首先看一下kset的原型
- struct kset {
- struct list_head list;
- spinlock_t list_lock;
- struct kobject kobj;
- const struct kset_uevent_ops *uevent_ops;
- };
再来看一下kset的初始化操作,kset表现为更高级一点的kobj,其初始化操作仍然是围绕其内部的kobj展开的。
- struct kset *kset_create_and_add(const char *name,
- const struct kset_uevent_ops *uevent_ops,
- struct kobject *parent_kobj)
- {
- struct kset *kset;
- int error;
- kset = kset_create(name, uevent_ops, parent_kobj);
- if (!kset)
- return NULL;
- error = kset_register(kset);
- if (error) {
- kfree(kset);
- return NULL;
- }
- return kset;
- }
- ---static struct kset *kset_create(const char *name,
- const struct kset_uevent_ops *uevent_ops,
- struct kobject *parent_kobj)
- {
- struct kset *kset;
- int retval;
- kset = kzalloc(sizeof(*kset), GFP_KERNEL);
- if (!kset)
- return NULL;
- retval = kobject_set_name(&kset->kobj, name);
- if (retval) {
- kfree(kset);
- return NULL;
- }
- kset->uevent_ops = uevent_ops;
- kset->kobj.parent = parent_kobj;
-
-
-
-
-
- kset->kobj.ktype = &kset_ktype;
- kset->kobj.kset = NULL;
- return kset;
- }
- ----int kset_register(struct kset *k)
- {
- int err;
- if (!k)
- return -EINVAL;
- kset_init(k);
- err = kobject_add_internal(&k->kobj);
- if (err)
- return err;
- kobject_uevent(&k->kobj, KOBJ_ADD);
- return 0;
- }
- ----void kset_init(struct kset *k)
- {
- kobject_init_internal(&k->kobj);
- INIT_LIST_HEAD(&k->list);
- spin_lock_init(&k->list_lock);
- }
四、上面给出了kobj,kset的初始化过程,以及相互产生关联的关键点,下面给出整体的一个流程图:
阅读(1398) | 评论(0) | 转发(4) |