我该怎么样来形容这个图呢? 它把依赖关系说的已经足够清楚了!!我这里唯一要解释的仅仅是在驱动文件夹被正确后所谓的文件属性有在那里。同样我们顺着目录 /sys/bus/sdio/driver/wlan_sdio/下我们发现了 bind、unbind和 new_id三个文件。
好了,别忘了我们在前面提过的问题,kset 是如何扮演容器的角色的呢?图中很清楚吧,看看粉红色的箭头,kset children list用来将将同类型的kobject连接起来以达到容器的效果。
但是我们的驱动还没有结束,关于这个图的建立,我们势必要用代码才能说得明白。
我们还是花费一点时间来看一下内核中的代码,关于 sdio 总线注册的代码部分,其它的部分,大家类举就可以了。懂了这段自然就懂了全部:
int bus_register( structbus_type
* bus)
{
int retval;
BLOCKING_INIT_NOTIFIER_HEAD (&bus->bus_notifier);
retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);//总线的名字 ”sdio”,我们说过了一个 kobject对应一个目录,这时会为这个目录赋值名字。
if (retval)
goto out;
bus->subsys.kobj.kset = &bus_subsys;//将其 kset指向 bus_subsys.,如何理解? 看看ldd_bus_type指向 bus_subsys的那条蓝线
retval = subsystem_register(&bus->subsys);//bus->subsys的注册,实际上是用 kset指针将其链接在一起。好吧 我得承认实际上这里取消了 subsysem结构的概念,用 kset代替了。这里会创建一个目录。它是一个 kset也是一个 kobject,因为 kset包含了 kobject。
if (retval)
goto out;
retval = bus_create_file(bus, &bus_attr_uevent);//创建属性文件
if (retval)
goto bus_uevent_fail;
kobject_set_name(&bus->devices.kobj, "devices");//设置 devices
kset的名字为 devices
bus->devices.kobj.parent = &bus->subsys.kobj;//参见 ldd_bus_type->devices指向 ldd_bus_type->sub_sys的红色箭头(注意这里也不是 subsystem,而是 kset)
retval = kset_register(&bus->devices);//创建 devices命名的目录
if (retval)
goto bus_devices_fail;
kobject_set_name(&bus->drivers.kobj, "drivers");//设置 devices
kset的名字为 drivers
bus->drivers.kobj.parent = &bus->subsys.kobj;//同样参见 ldd_bus_type->drivers指向 ldd_bus_type->sub_sys的红色箭头(注意这里也不是 subsystem,而是 kset)。
bus->drivers.ktype = &driver_ktype;//对 kobject默认属性的赋值
retval = kset_register(&bus->drivers);//创建 drivers命名的目录
if (retval)
goto bus_drivers_fail;
klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);//klist结构的初始化,关于 klist链接的作用我们已经说得很清楚了
klist_init(&bus->klist_drivers, NULL, NULL);
bus->drivers_autoprobe = 1;
retval = add_probe_files(bus);//添加探测属性
if (retval)
goto bus_probe_files_fail;
retval = bus_add_attrs(bus);//添加其他属性
if (retval)
goto bus_attrs_fail;
pr_debug("bus type '%s' registered/n", bus->name);
return0;
bus_attrs_fail :
remove_probe_files(bus);
bus_probe_files_fail :
kset_unregister(&bus->drivers);
bus_drivers_fail :
kset_unregister(&bus->devices);
bus_devices_fail :
bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail :
subsystem_unregister(&bus->subsys);
out :
return retval;
}
至此 我们终于理顺了整个过程。