LDD3的第14章《Linux设备模型》一章节把Linux内核中的很多结构体串讲了一遍,满满的干货,非常值得一看,这里简单的笔记下代码注释吧。作者的语文实在太差,很多阅读心得不知道怎么笔记出来,还请各位高手勿喷~
kset基于kobject,因此kset包含kobject的所有功能,比如组成树形结构,或者属于另一个kset。
CONTENTS
\linux-2.6.11\include\linux\kobject.h
/** * kset - a set of kobjects of a specific type, belonging * to a specific subsystem. * * All kobjects of a kset should be embedded in an identical * type. This type may have a descriptor, which the kset points * to. This allows there to exist sets of objects of the same * type in different subsystems. * * A subsystem does not have to be a list of only one type * of object; multiple ksets can belong to one subsystem. All * ksets of a subsystem share the subsystem's lock. * * Each kset can support hotplugging; if it does, it will be given * the opportunity to filter out specific kobjects from being * reported, as well as to add its own "data" elements to the * environment being passed to the hotplug helper. */ struct kset_hotplug_ops { int (*filter)(struct kset *kset, struct kobject *kobj); char *(*name)(struct kset *kset, struct kobject *kobj); int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp, int num_envp, char *buffer, int buffer_size); }; struct kset { struct subsystem * subsys;/* kset一般都属于一个特定的subsystem */ struct kobj_type * ktype; /* kset对应的kobj_type,这个优先于kobject里面的kobj_type */ struct list_head list; /* kset内部维护一个链表,连接着内部管理的kobject */ struct kobject kobj; /* kset也是一个kobject,由于无法继承,这里包含一个kobject */ struct kset_hotplug_ops * hotplug_ops; }; extern void kset_init(struct kset * k); extern int kset_add(struct kset * k); extern int kset_register(struct kset * k); extern void kset_unregister(struct kset * k); /* 根据kobject获取外部包含的kset */ static inline struct kset * to_kset(struct kobject * kobj) { return kobj ? container_of(kobj,struct kset,kobj) : NULL; } /* 增加一个kset的引用计数,可以发现,是调用的内部的kobject来进行引用计数 */ static inline struct kset * kset_get(struct kset * k) { return k ? to_kset(kobject_get(&k->kobj)) : NULL; } /* 减少一个kset的引用计数 */ static inline void kset_put(struct kset * k) { kobject_put(&k->kobj); } /* 返回一个kobject对应的kobj_type,注意这里的k不一定是kset,外部包裹的 不一定是kset。 这里可以看到对于一个kobject,它的kobj_type的获取不是直接获取它自己的, 而是先查询下它有没有在一个kset中,如果在一个kset中,就用kset的kobj_type来 作为自己的kobj_type。这点非常重要,否则属性的读写调用就会出现问题 */ static inline struct kobj_type * get_ktype(struct kobject * k) { if (k->kset && k->kset->ktype) return k->kset->ktype; else return k->ktype; } extern struct kobject * kset_find_obj(struct kset *, const char *); /** * Use this when initializing an embedded kset with no other * fields to initialize. */ /* 设置一个kset的名字,其实就是设置kset内部包含的kobject的名字 */ #define set_kset_name(str) .kset = { .kobj = { .name = str } }
\linux-2.6.11\lib\kobject.c
/** * kset_init - initialize a kset for use * @k: kset */ /* 初始化kset */ void kset_init(struct kset * k) { kobject_init(&k->kobj); INIT_LIST_HEAD(&k->list); } /** * kset_add - add a kset object to the hierarchy. * @k: kset. * * Simply, this adds the kset's embedded kobject to the * hierarchy. * We also try to make sure that the kset's embedded kobject * has a parent before it is added. We only care if the embedded * kobject is not part of a kset itself, since kobject_add() * assigns a parent in that case. * If that is the case, and the kset has a controlling subsystem, * then we set the kset's parent to be said subsystem. */ /* 讲kset加入到某个树形中,注意这里的关系在调用函数之前已经设置了。 */ int kset_add(struct kset * k) { /* 如果kset附属于某个subsystem,那么就把kset的parent设置为该subsystem */ if (!k->kobj.parent && !k->kobj.kset && k->subsys) k->kobj.parent = &k->subsys->kset.kobj; return kobject_add(&k->kobj);/* 内部调用kobject */ } /** * kset_register - initialize and add a kset. * @k: kset. */ int kset_register(struct kset * k) { kset_init(k); return kset_add(k); } /** * kset_unregister - remove a kset. * @k: kset. */ void kset_unregister(struct kset * k) { kobject_unregister(&k->kobj); } /** * kset_find_obj - search for object in kset. * @kset: kset we're looking in. * @name: object's name. * * Lock kset via @kset->subsys, and iterate over @kset->list, * looking for a matching kobject. If matching object is found * take a reference and return the object. */ /* 在kset管理的链表中查找指定名称的kobject */ struct kobject * kset_find_obj(struct kset * kset, const char * name) { struct list_head * entry; struct kobject * ret = NULL; down_read(&kset->subsys->rwsem); list_for_each(entry,&kset->list) { struct kobject * k = to_kobj(entry); if (kobject_name(k) && !strcmp(kobject_name(k),name)) { ret = kobject_get(k); break; } } up_read(&kset->subsys->rwsem); return ret; }
发表评论