根据设备、总线、驱动这条线,已经分析过总线以及设备。现在来看一下设备模型中驱动这个层次。
和总线、设备的分析方法一样,分析驱动的入口在driver_register()函数当中.定义在drivers/base/driver.c文件中。根据源代码来分析:
235 other = driver_find(drv->name, drv->bus);
在driver_find函数当中
282 struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
bus->p->drivers_kset是该总线上的设备所对应的所有驱动的容器。在其中查找驱动名与name匹配的"驱动",实际上只是获取了驱动结构指向的私有结构里内嵌的kobject,在通过container_of就可以获取这个私有结构priv.而priv->driver就是所属驱动结构了。从这条语句可以窥出一些设备模型的结构组织。
243 ret = bus_add_driver(drv);
bus_add_driver()定义在drivers/base/bus.c文件中。
668 priv->kobj.kset = bus->p->drivers_kset;
priv是该驱动结构所拥有的私有结构信息。这条语句就是将该驱动结构放入其所将驱动的设备所在总线的驱动容器当中。当然这个说法不严谨,但按照面向对象的思想来思考。
669 error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
670 "%s", drv->name);
在调用kobject_init_and_add函数时将其父结构参数设置为NULL,故将把其父结构设置为
bus->p->drivers_kset.kobj,并添加到链表当中。
679 klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
将该驱动加入对应设备连接的总线的驱动链表上。由此可知,只要有总线结构,就可以通过遍历总线结构中的驱动链表访问连接到该总线的所有设备对应的驱动。
从以上可知.driver_register()函数主要设置驱动结构所属容器,以及加入到对应设备所连接的总线的驱动链表上。一个是设置在驱动模型中的层次,一个方便从总线这个层次上管理所有的驱动。
在该函数中遗漏了将驱动与设备绑定的过程.这与设备模型似乎没多大关系。但其中的一个函数调用
bus_for_each_dev():
klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->p->knode_bus : NULL));
遍历驱动所将驱动的设备所在总线上的所有设备,并条用一个指定函数。bus->p->klist_devices就是链接在该总线上的所有设备。在驱动与设备绑定的过程当中,若发现匹配的设备以及能够驱动的设备.通过调用bus的probe方法或者驱动自身的probe方法所确定。则会将能驱动的设备加入到驱动结构的devices字段构成的链表当中。而在设备结构中会将driver字段指向能驱动该设备的驱动结构。需要注意的是一个设备只对应一个驱动,而驱动却能够驱动多个设备。
阅读(3580) | 评论(1) | 转发(0) |