那么他们之间具有什么关系?那应该不是‘小3‘也不是'小5‘的关系,总之这种关系超越了人们,构成了Linux,是一种"你中有我,我中有你“的关系,其实关系复杂了,语言是难以描述的,不过还是先从文字开始吧。本文基于内核版本linux2.6.30.4,从分析bus总线来初步了解kobj, ktype,kset,subsys关系.因为bus总线本身是一个容器,包含了它们!
kobject,ktpye,kset可以说是Linux内核最基本,也是最重要的数据结构了。如果把Linux比做一栋大夏,那么它们就是大夏的基石。
struct kobject { const char *name; struct list_headentry; 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; };2. ktype
struct kobj_type { void (*release)(struct kobject *kobj); struct sysfs_ops *sysfs_ops; struct attribute **default_attrs; };
其中struct sysfs_ops 定义如下:
struct sysfs_ops { ssize_t (*show)(struct kobject *, struct attribute *,char *); ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); };
例如bus的ktype是这样定义的:
static struct sysfs_ops bus_sysfs_ops = { .show = bus_attr_show, .store = bus_attr_store, }; static struct kobj_type bus_ktype = { .sysfs_ops = &bus_sysfs_ops, };
3.kset
kset最重要的是建立上层(sub-system)和下层的(kobject)的关联性。kobject 也会利用它来分辨自已是属于那一個类型,然後在/sys 下建立正确的目录位置。而kset 的优先权比较高,kobject会利用自已的*kset 找到自已所属的kset,并把*ktype 指定成该kset下的ktype,除非沒有定义kset,才会用ktype來建立关系。Kobject通过kset组织成层次化的结构,kset是具有相同类型的kobject的集合,也可以说kset具有kobject所有的功能.struct kset { struct list_head list; //the list of all kobjects for this kset spinlock_t list_lock; //a lock for iterating over the kobjects struct kobject kobj; //the embedded kobject for this kset (recursion, isn't it fun...) struct kset_uevent_ops *uevent_ops;//the set of uevent operations for this kset. };
总线初始化buses_init时,建立了bus_kset.
static struct kset *bus_kset; int __init buses_init(void) { bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); if (!bus_kset) return -ENOMEM; return 0; }
4.subsystem
如果说kset是管理kobject 的集合,那么subsystem 就是管理kset 的集合。它描述系统中某一类设备子系统,如block subsys表示所有的块设备,对应于sysfs文件系统中的block目录。类似的,devices subsys对应于sysfs中的devices目录,描述系统中所有的设备。一个具体总线可称之为subsystem.如I2C,SPI子系统等.它们是bus的子系统.struct bus_type_private { struct kset subsys; struct kset *drivers_kset; struct kset *devices_kset; struct klist klist_devices; struct klist klist_drivers; struct blocking_notifier_head bus_notifier; unsigned int drivers_autoprobe:1; struct bus_type *bus; };
在bus下注册一个总线的过程,就是形成一个子系统subsystem的过程:
int bus_register(struct bus_type *bus) { int retval; struct bus_type_private *priv; priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); ... retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); if (retval) goto out; priv->subsys.kobj.kset = bus_kset; // priv->subsys.kobj.ktype = &bus_ktype; // priv->drivers_autoprobe = 1; ... }
下面这个图比较经典,直观的反映了kset 和kobj之间的关系
kset 本身嵌有一个kobj实体作为所以同类kobj的'父母亲',同时还维护一个链表kset child list, 这个链表中所有的kobj的kset分别指向“父母亲"的kset.
最后不得不说,要全部了解其中关系,涉及的东西太多了,要学习的东西也太多了,不过,不积跬步,无以至千里,继续努力!以后会继续结合内核源码分析....
相关参考:
hacktaojxnu的图解分析很值得一看:http://blog.csdn.net/hacktaojxnu/article/details/6717991
http://lwn.net/Articles/51437/