# 统一设备模型(1)——bus、subsys_interface、class、class_interface分析
在这一篇系列中,将着重分析内核是如何使用内核模块的。内核模块的详细分析请参考上一系列文章《内核对象kobject和sysfs》。
在统一设备模型里,内核利用kobj以及kset建立sysfs内的目录结构,并根据业务的不同,抽象出device、driver、bus、class等模型。几乎所有的内核驱动子系统都用到这一类模型。在本篇,先着重分析提供服务的较低层次的模型:bus、subsys_interface、class、class_interface。
在具体介绍之前,先大致用文字描述一下该模型的原理。bus是内核模拟出来的一条虚拟总线,device是逻辑设备,driver是驱动。每一个device和driver都需要向bus去注册,每次注册都会引发device和driver的匹配。如果匹配成功,那么将成功绑定,从而执行driver内自定义的或者bus内定义的probe函数对device进行各种初始化,进而使物理设备正常工作。subsys_interface是向bus中注册的其他接口,class_interface是向class中注册的其他接口。
不管是device还是driver,都必须要注册到bus上。因此我们先分析bus的相关实现,首先先看看bus的结构:
108 struct bus_type {
109 const char *name; // 该bus的名称
110 const char *dev_name; //
111 struct device *dev_root;
112 struct device_attribute *dev_attrs; /* use dev_groups instead */
113 const struct attribute_group **bus_groups;
114 const struct attribute_group **dev_groups;
115 const struct attribute_group **drv_groups;
116
117 int (*match)(struct device *dev, struct device_driver *drv);
118 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
119 int (*probe)(struct device *dev);
120 int (*remove)(struct device *dev);
121 void (*shutdown)(struct device *dev);
122
123 int (*online)(struct device *dev);
124 int (*offline)(struct device *dev);
125
126 int (*suspend)(struct device *dev, pm_message_t state);
127 int (*resume)(struct device *dev);
128
129 const struct dev_pm_ops *pm;
130
131 const struct iommu_ops *iommu_ops;
132
133 struct subsys_private *p;
134 struct lock_class_key lock_key;
135 };
对于复杂的结构体,我们往往只关注其核心成员。目前我学疏才浅,在我看来,bus_type的核心是109~121行之间的内容。成员意义已经标注在结构体中。
bus_type的操作函数也不外乎是那几个:注册、注销。下面我们分别来看。
887 int bus_register(struct bus_type *bus)
888 {
889 int retval;
890 struct subsys_private *priv;
891 struct lock_class_key *key = &bus->lock_key;
892
893 priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL);
894 if (!priv)
895 return -ENOMEM;
896
897 priv->bus = bus;
898 bus->p = priv;
899
900 BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
901
902 retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
903 if (retval)
904 goto out;
905
906 priv->subsys.kobj.kset = bus_kset;
907 priv->subsys.kobj.ktype = &bus_ktype;
908 priv->drivers_autoprobe = 1;
909
910 retval = kset_register(&priv->subsys);
911 if (retval)
912 goto out;
913
914 retval = bus_create_file(bus, &bus_attr_uevent);
915 if (retval)
916 goto bus_uevent_fail;
917
918 priv->devices_kset = kset_create_and_add("devices", NULL,
919 &priv->subsys.kobj);
920 if (!priv->devices_kset) {
921 retval = -ENOMEM;
922 goto bus_devices_fail;
923 }
924
925 priv->drivers_kset = kset_create_and_add("drivers", NULL,
926 &priv->subsys.kobj);
927 if (!priv->drivers_kset) {
928 retval = -ENOMEM;
929 goto bus_drivers_fail;
930 }
931
932 INIT_LIST_HEAD(&priv->interfaces);
933 __mutex_init(&priv->mutex, "subsys mutex", key);
934 klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
935 klist_init(&priv->klist_drivers, NULL, NULL);
936
937 retval = add_probe_files(bus);
938 if (retval)
939 goto bus_probe_files_fail;
940
941 retval = bus_add_groups(bus, bus->bus_groups);
942 if (retval)
943 goto bus_groups_fail;
944
945 pr_debug("bus: '%s': registered\n", bus->name);
946 return 0;
947
948 bus_groups_fail:
949 remove_probe_files(bus);
950 bus_probe_files_fail:
951 kset_unregister(bus->p->drivers_kset);
952 bus_drivers_fail:
953 kset_unregister(bus->p->devices_kset);
954 bus_devices_fail:
955 bus_remove_file(bus, &bus_attr_uevent);
956 bus_uevent_fail:
957 kset_unregister(&bus->p->subsys);
958 out:
959 kfree(bus->p);
960 bus->p = NULL;
961 return retval;
962 }
963 EXPORT_SYMBOL_GPL(bus_register);
893行分配了subsys_private这么一个结构。这个结构是用来记录在内核中关于bus的动态信息的,和bus_type结构相对应。这个结构也贴出如下,并将关键成员注释。
28 struct subsys_private {
29 struct kset subsys; // 该子系统的内嵌kset
30 struct kset *devices_kset; // 该子系统管理的设备kset
31 struct list_head interfaces;
32 struct mutex mutex;
33
34 struct kset *drivers_kset; // 该子系统管理的驱动kset
35 struct klist klist_devices; // 该子系统下的所有设备的链表头
36 struct klist klist_drivers; // 该子系统下的所有驱动的链表头
37 struct blocking_notifier_head bus_notifier;
38 unsigned int drivers_autoprobe:1;
39 struct bus_type *bus; // 与该子系统关联的bus
40
41 struct kset glue_dirs;
42 struct class *class;
43 };
906行和910行可以看到,bus_type类通过内嵌的kset在sysfs中有层次的目录,当然,归根结底,是使用kobj来形成这种层次。918行和925行,可以看到,我们知道,比如在/sys/bus/pci 下,一定有devices和drivers这两个目录。这就是这个函数的功劳。把这个函数展开:
937 struct kset *kset_create_and_add(const char *name,
938 const struct kset_uevent_ops *uevent_ops,
939 struct kobject *parent_kobj)
940 {
941 struct kset *kset;
942 int error;
943
944 kset = kset_create(name, uevent_ops, parent_kobj);
945 if (!kset)
946 return NULL;
947 error = kset_register(kset);
948 if (error) {
949 kfree(kset);
950 return NULL;
951 }
952 return kset;
953 }
894 static struct kset *kset_create(const char *name,
895 const struct kset_uevent_ops *uevent_ops,
896 struct kobject *parent_kobj)
897 {
898 struct kset *kset;
899 int retval;
900
901 kset = kzalloc(sizeof(*kset), GFP_KERNEL);
902 if (!kset)
903 return NULL;
904 retval = kobject_set_name(&kset->kobj, "%s", name);
905 if (retval) {
906 kfree(kset);
907 return NULL;
908 }
909 kset->uevent_ops = uevent_ops;
910 kset->kobj.parent = parent_kobj;
911
912 /*
913 * The kobject of this kset will have a type of kset_ktype and belong to
914 * no kset itself. That way we can properly free it when it is
915 * finished being used.
916 */
917 kset->kobj.ktype = &kset_ktype;
918 kset->kobj.kset = NULL;
919
920 return kset;
921 }
其实我们发现,这个函数只不过是比kset_register多了个分配kset内存的过程。我们之前的博文有说过,在使用kset_register之前,一定要为kset内嵌的kobj内的parent指针初始化指向,否则该kset会创建在/sys下。之前我们是手动初始化的,现在这个操作被包含到kset_create中了。910行体现了这一点,这也证明了devices目录会建立在pci这些具体的bus目录下。
我们注意到subsys_private结构里,在第31行,有interfaces成员。该成员即是提供给该bus的一个管理接口。一个bus可以有多个管理接口,这些接口通过interfaces连在一起。interfaces实际也只是一个链表头。当然,该接口一般不是用作控制设备,而是作为管理class或者bus的一个功能。
343 struct subsys_interface {
344 const char *name;
345 struct bus_type *subsys;
346 struct list_head node;
347 int (*add_dev)(struct device *dev, struct subsys_interface *sif);
348 void (*remove_dev)(struct device *dev, struct subsys_interface *sif);
349 };
1125 int subsys_interface_register(struct subsys_interface *sif)
1126 {
1127 struct bus_type *subsys;
1128 struct subsys_dev_iter iter;
1129 struct device *dev;
1130
1131 if (!sif || !sif->subsys)
1132 return -ENODEV;
1133
1134 subsys = bus_get(sif->subsys);
1135 if (!subsys)
1136 return -EINVAL;
1137
1138 mutex_lock(&subsys->p->mutex);
1139 list_add_tail(&sif->node, &subsys->p->interfaces);
1140 if (sif->add_dev) {
1141 subsys_dev_iter_init(&iter, subsys, NULL, NULL);
1142 while ((dev = subsys_dev_iter_next(&iter)))
1143 sif->add_dev(dev, sif);
1144 subsys_dev_iter_exit(&iter);
1145 }
1146 mutex_unlock(&subsys->p->mutex);
1147
1148 return 0;
1149 }
调用subsys_interface_register向一个bus注册该接口。1139行可以看到,注册的实质就是将自身链到interfaces的链表尾部。1140~1145行为了保证在接口注册之前就已经注册进bus的设备,也能使用该接口的add_dev函数。
在新版本的linux内核代码里,bus是一条虚拟的设备,但是无从体现。在新版本linxu内核里,增加了子系统这么一个概念。因此,大家可以看到,注册bus进内核,生成的动态结构名称都是subsys_private。此外,新版本中的bus还有设备的抽象概念。为此,linux提供了subsys_system_register函数:
int subsys_system_register(struct bus_type *subsys,
1243 const struct attribute_group **groups)
1244 {
1245 return subsys_register(subsys, groups, &system_kset->kobj);
1246 }
1182 static int subsys_register(struct bus_type *subsys,
1183 const struct attribute_group **groups,
1184 struct kobject *parent_of_root)
1185 {
1186 struct device *dev;
1187 int err;
1188
1189 err = bus_register(subsys);
1190 if (err < 0)
1191 return err;
1192
1193 dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1194 if (!dev) {
1195 err = -ENOMEM;
1196 goto err_dev;
1197 }
1198
1199 err = dev_set_name(dev, "%s", subsys->name);
1200 if (err < 0)
1201 goto err_name;
1202
1203 dev->kobj.parent = parent_of_root;
1204 dev->groups = groups;
1205 dev->release = system_root_device_release;
1206
1207 err = device_register(dev);
1208 if (err < 0)
1209 goto err_dev_reg;
1210
1211 subsys->dev_root = dev;
1212 return 0;
1213
1214 err_dev_reg:
1215 put_device(dev);
1216 dev = NULL;
1217 err_name:
1218 kfree(dev);
1219 err_dev:
1220 bus_unregister(subsys);
1221 return err;
1222 }
可以看到1193之后,在bus_register之后,还有额外的事情去做。把总线也作为一个设备,支持注册到别的总线上。这对于开发者来说,可以更加便利的实现对多级设备的分类统一管理。关于device的介绍见下一篇。
387 struct class {
388 const char *name;
389 struct module *owner;
390
391 struct class_attribute *class_attrs;
392 const struct attribute_group **dev_groups;
393 struct kobject *dev_kobj;
394
395 int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
396 char *(*devnode)(struct device *dev, umode_t *mode);
397
398 void (*class_release)(struct class *class);
399 void (*dev_release)(struct device *dev);
400
401 int (*suspend)(struct device *dev, pm_message_t state);
402 int (*resume)(struct device *dev);
403
404 const struct kobj_ns_type_operations *ns_type;
405 const void *(*namespace)(struct device *dev);
406
407 const struct dev_pm_ops *pm;
408
409 struct subsys_private *p;
410 };
class的结构如上所示。乍一看和bus_type很相似。其实,个人理解,把bus的绑定device和driver功能删除,bus就成了class。而在很多子系统中,class也正是作为一个bus的补充。例如,一个SCSI设备,需要注册到SCSI总线上,那么在对该设备的操作,都需要对应于SCSI生成的动态结构。这个结构将被SCSI上层驱动(例如磁盘驱动)识别获取和绑定。那么对一个磁盘的操作,将绕不开磁盘驱动。class提供了一个相当于第三方的接口。在SCSI子系统中,内核把每一个SCSI设备不但注册进了SCSI总线,还注册进了sg类。这样,用户可以有多重选择操作设备。
class的操作不外乎也就是注册注销。
166 int __class_register(struct class *cls, struct lock_class_key *key)
167 {
168 struct subsys_private *cp;
169 int error;
170
171 pr_debug("device class '%s': registering\n", cls->name);
172
173 cp = kzalloc(sizeof(*cp), GFP_KERNEL);
174 if (!cp)
175 return -ENOMEM;
176 klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
177 INIT_LIST_HEAD(&cp->interfaces);
178 kset_init(&cp->glue_dirs);
179 __mutex_init(&cp->mutex, "subsys mutex", key);
180 error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
181 if (error) {
182 kfree(cp);
183 return error;
184 }
185
186 /* set the default /sys/dev directory for devices of this class */
187 if (!cls->dev_kobj)
188 cls->dev_kobj = sysfs_dev_char_kobj;
189
190 #if defined(CONFIG_BLOCK)
191 /* let the block class directory show up in the root of sysfs */
192 if (!sysfs_deprecated || cls != &block_class)
193 cp->subsys.kobj.kset = class_kset;
194 #else
195 cp->subsys.kobj.kset = class_kset;
196 #endif
197 cp->subsys.kobj.ktype = &class_ktype;
198 cp->class = cls;
199 cls->p = cp;
200
201 error = kset_register(&cp->subsys);
202 if (error) {
203 kfree(cp);
204 return error;
205 }
206 error = add_class_attrs(class_get(cls));
207 class_put(cls);
208 return error;
209 }
正因为class和bus的相似之处,在新版本linxu内核里,将对class和bus采用相同的动态结构。即subsys_private。代码中也可以看出,注册的过程和bus几乎一样,这里不再赘述。
当然,class中也有类似bus中提供的接口。这个接口如下:
503 struct class_interface {
504 struct list_head node;
505 struct class *class;
506
507 int (*add_dev) (struct device *, struct class_interface *);
508 void (*remove_dev) (struct device *, struct class_interface *);
509 };
可以看到,和bus的接口在结构上,几乎一样。这里分析也留给读者。
那么,到这里为止,内核提供的这些为驱动编程打造的基础设施就介绍完毕了。下面我们用一个图来表示他们之间的关系。