linux设备驱动(3)devive_driver 详解
linux 设备驱动模型中,之前内核直接叫做driver,后来改为device_driver,device和device_drvier 对应,驱动模型中最重要抽象两个概念。接下一步步分析device_driver的注册初始化过程。
1driver_register
code位于:drivers\base\Driver.c ,向bus中注册一个device_driver
1 /**
2 * driver_register - register driver with bus
3 * @drv: driver to register
4 *
5 * We pass off most of the work to the bus_add_driver() call,
6 * since most of the things we have to do deal with the bus
7 * structures.
8 */
9 int driver_register(struct device_driver *drv)
10 {
11 int ret;
12 struct device_driver *other;
13
14 BUG_ON(!drv->bus->p);//driver的总线必须要有自己的subsys,因为这个才是整个bus连接device和driver的核心
15 /* driver和bus两种都实现了下面函数,而实际最只能执行一个,所以告警说重复 */
16 if ((drv->bus->probe && drv->probe) ||
17 (drv->bus->remove && drv->remove) ||
18 (drv->bus->shutdown && drv->shutdown))
19 printk(KERN_WARNING "Driver '%s' needs updating - please use "
20 "bus_type methods\n", drv->name);
21 /* 查找驱动是否已经装载注册,已经装载的则直接返回 */
22 other = driver_find(drv->name, drv->bus);
23 if (other) {
24 printk(KERN_ERR "Error: Driver '%s' is already registered, "
25 "aborting...\n", drv->name);
26 return -EBUSY;
27 }
28 /* 把驱动加入总线的驱动链表 */
29 ret = bus_add_driver(drv);
30 if (ret)
31 return ret;
32 ret = driver_add_groups(drv, drv->groups);//把驱动加入驱动的group中
33 if (ret) {
34 bus_remove_driver(drv);
35 return ret;
36 }
37 kobject_uevent(&drv->p->kobj, KOBJ_ADD);//向上报告一个增加事件
38
39 return ret;
40 }
1.1driver_find
查找驱动是否已经装载注册,已经装载的则直接返回
1 /** 2 * driver_find - locate driver on a bus by its name. 3 * @name: name of the driver. 4 * @bus: bus to scan for the driver. 5 * 6 * Call kset_find_obj() to iterate over list of drivers on 7 * a bus to find driver by name. Return driver if found. 8 * 9 * This routine provides no locking to prevent the driver it returns 10 * from being unregistered or unloaded while the caller is using it. 11 * The caller is responsible for preventing this. 12 */ 13 struct device_driver *driver_find(const char *name, struct bus_type *bus) 14 { 15 struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);//在bus所管理的driver链表中,查找有没有name这个driver 16 struct driver_private *priv; 17 18 if (k) { 19 /* Drop reference added by kset_find_obj() */ 20 kobject_put(k);//把该driver的kobject引用计数减1,kset_find_obj函数对其+1了 21 priv = to_driver(k);// 22 return priv->driver;//通过driver里面的kobject返回driver 23 } 24 return NULL; 25 } 26 27 /** 28 * kset_find_obj - search for object in kset. 29 * @kset: kset we're looking in. 30 * @name: object's name. 31 * 32 * Lock kset via @kset->subsys, and iterate over @kset->list, 33 * looking for a matching kobject. If matching object is found 34 * take a reference and return the object. 35 */ 36 struct kobject *kset_find_obj(struct kset *kset, const char *name) 37 {//遍历kset的kobject链表中有没有名为name的kobject 38 struct kobject *k; 39 struct kobject *ret = NULL; 40 41 spin_lock(&kset->list_lock); 42 /*查找方法很简单,依次遍历bus的driver链表每个driver的kobject的name,如果有相同的返回对应的kobject*/ 43 list_for_each_entry(k, &kset->list, entry) { 44 if (kobject_name(k) && !strcmp(kobject_name(k), name)) { 45 ret = kobject_get_unless_zero(k);//引用计数加1 46 break; 47 } 48 } 49 50 spin_unlock(&kset->list_lock); 51 return ret; 52 }
1.2 bus_add_driver
把device_driver加入到bus中。source code位于:drivers\base\bus.c
1 /**
2 * bus_add_driver - Add a driver to the bus.
3 * @drv: driver.
4 */
5 int bus_add_driver(struct device_driver *drv)
6 {
7 struct bus_type *bus;
8 struct driver_private *priv;
9 int error = 0;
10
11 bus = bus_get(drv->bus);//拿到driver所属的总线
12 if (!bus)
13 return -EINVAL;
14
15 pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
16 /* bus有自己的private,device有自己的private,driver也有,功能就是负责连接对方 */
17 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
18 if (!priv) {
19 error = -ENOMEM;
20 goto out_put_bus;
21 }
22 klist_init(&priv->klist_devices, NULL, NULL);//初始化klist,以及填充dricer的private里面的内容
23 priv->driver = drv;
24 drv->p = priv;
25 priv->kobj.kset = bus->p->drivers_kset;//driver绑定bus(通过各自里面的privte)
26 error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
27 "%s", drv->name);
28 if (error)
29 goto out_unregister;
30 /*把driver在bus的节点,加入到bus的driver链表的最后一个*/
31 klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
32 if (drv->bus->p->drivers_autoprobe) {
33 error = driver_attach(drv);//driver匹配device
34 if (error)
35 goto out_unregister;
36 }
37 module_add_driver(drv->owner, drv);
38
39 error = driver_create_file(drv, &driver_attr_uevent);
40 if (error) {
41 printk(KERN_ERR "%s: uevent attr (%s) failed\n",
42 __func__, drv->name);
43 }
44 error = driver_add_attrs(bus, drv);//添加driver的属性
45 if (error) {
46 /* How the hell do we get out of this pickle? Give up */
47 printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
48 __func__, drv->name);
49 }
50
51 if (!drv->suppress_bind_attrs) {
52 error = add_bind_files(drv);
53 if (error) {
54 /* Ditto */
55 printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
56 __func__, drv->name);
57 }
58 }
59
60 return 0;
61
62 out_unregister:
63 kobject_put(&priv->kobj);
64 kfree(drv->p);
65 drv->p = NULL;
66 out_put_bus:
67 bus_put(bus);
68 return error;
69 }
1.2.1driver_attach
1 /** 2 * driver_attach - try to bind driver to devices. 3 * @drv: driver. 4 * 5 * Walk the list of devices that the bus has on it and try to 6 * match the driver with each one. If driver_probe_device() 7 * returns 0 and the @dev->driver is set, we've found a 8 * compatible pair. 9 */ 10 int driver_attach(struct device_driver *drv) 11 { 12 return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//遍历总线上的dev,调用_driver_attach匹配dev 13 } 14 15 /** 16 * bus_for_each_dev - device iterator. 17 * @bus: bus type. 18 * @start: device to start iterating from. 19 * @data: data for the callback. 20 * @fn: function to be called for each device. 21 * 22 * Iterate over @bus's list of devices, and call @fn for each, 23 * passing it @data. If @start is not NULL, we use that device to 24 * begin iterating from. 25 * 26 * We check the return of @fn each time. If it returns anything 27 * other than 0, we break out and return that value. 28 * 29 * NOTE: The device that returns a non-zero value is not retained 30 * in any way, nor is its refcount incremented. If the caller needs 31 * to retain this data, it should do so, and increment the reference 32 * count in the supplied callback. 33 */ 34 int bus_for_each_dev(struct bus_type *bus, struct device *start, 35 void *data, int (*fn)(struct device *, void *)) 36 { 37 struct klist_iter i; 38 struct device *dev; 39 int error = 0; 40 41 if (!bus || !bus->p) 42 return -EINVAL; 43 44 klist_iter_init_node(&bus->p->klist_devices, &i, 45 (start ? &start->p->knode_bus : NULL)); 46 while ((dev = next_device(&i)) && !error) 47 error = fn(dev, data); 48 klist_iter_exit(&i); 49 return error; 50 }
1.2.1.1__driver_attach
1 static int __driver_attach(struct device *dev, void *data) 2 { 3 struct device_driver *drv = data; 4 5 /* 6 * Lock device and try to bind to it. We drop the error 7 * here and always return 0, because we need to keep trying 8 * to bind to devices and some drivers will return an error 9 * simply if it didn't support the device. 10 * 11 * driver_probe_device() will spit a warning if there 12 * is an error. 13 */ 14 15 if (!driver_match_device(drv, dev))//匹配dev,drv和dev匹配成功的话,才会往下执行的probe函数 16 return 0; 17 18 if (dev->parent) /* Needed for USB */ 19 device_lock(dev->parent); 20 device_lock(dev); 21 if (!dev->driver) 22 driver_probe_device(drv, dev);//执行探针函数 23 device_unlock(dev); 24 if (dev->parent) 25 device_unlock(dev->parent); 26 27 return 0; 28 }
1.2.1.1.1driver_match_device driver_probe_device
以下的两个API和device中一样,调用的是同一个接口,不再详述。
static inline int driver_match_device(struct device_driver *drv, struct device *dev) { return drv->bus->match ? drv->bus->match(dev, drv) : 1; } /** * driver_probe_device - attempt to bind device & driver together * @drv: driver to bind a device to * @dev: device to try to bind to the driver * * This function returns -ENODEV if the device is not registered, * 1 if the device is bound successfully and 0 otherwise. * * This function must be called with @dev lock held. When called for a * USB interface, @dev->parent lock must be held as well. */ int driver_probe_device(struct device_driver *drv, struct device *dev) { int ret = 0; if (!device_is_registered(dev)) return -ENODEV; pr_debug("bus: '%s': %s: matched device %s with driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); pm_runtime_barrier(dev); ret = really_probe(dev, drv); pm_request_idle(dev); return ret; }
2.总结
总结下整个flow:
driver_register(struct device_driver *drv)
BUG_ON(!drv->bus->p); //driver的总线必须要有自己的subsys,因为这个才是整个bus连接device和driver的核心
driver_find();//找到对应的driver
kset_find_obj();//在bus所管理的driver链表中,查找有没有name这个driver
list_for_each_entry()
kobject_get();//找到的话,引用计数+1
kobject_put();//把该driver的kobject引用计数减1,kset_find_obj函数对其+1了
priv = to_driver(); //通过driver中的kobject找到driver
bus_add_driver();//把驱动加入总线的驱动链表
driver_add_groups();//驱动加到group中
kobject_uevent();//向上增报告一个增加事件
bus_add_driver();//把驱动加入总线的驱动链表
bus_get(drv->bus);//拿到bus
priv = kzalloc(sizeof(*priv), GFP_KERNEL);//bus/device/ driver都有自己的private指针,负责连接对方
klist_init();
kobject_init_and_add();
klist_add_tail();//把driver在bus的节点,加入到bus的driver链表的最后一个
driver_attach();//否则,同步,直接执行匹配函数
bus_for_each_dev();
__driver_attach();
driver_match_device();//drv和dev匹配成功的话,才会往下执行的probe函数
return drv->bus->match ? drv->bus->match(dev, drv) : 1;// 调用bus的match函数匹配,bus的match函数不存在,则返回1
device_lock(dev->parent);//设备的parent锁定,不能执行睡眠,卸载之类的操作,否则下面driver_probe_device函数如果匹配上指行probe函数,就没parent了
device_lock(dev);//要用device,锁定device。
driver_probe_device();//同device,call对应的probe函数
device_unlock(dev);
device_unlock(dev->parent);
driver_probe_device()
device_is_registered();//判断设备是都注册
really_probe();//真正的probe函数
3. 设备模型框架下驱动开发的基本步骤
在设备模型框架下,设备驱动的开发是一件很简单的事情,主要包括2个步骤:
步骤1:分配一个struct device类型的变量,填充必要的信息后,把它注册到内核中。
步骤2:分配一个struct device_driver类型的变量,填充必要的信息后,把它注册到内核中。
这两步完成后,内核会在合适的时机,调用struct device_driver变量中的probe、remove、suspend、resume等回调函数,从而触发或者终结设备驱动的执行。而所有的驱动程序逻辑,都会由这些回调函数实现,此时,驱动开发者眼中便不再有“设备模型”,转而只关心驱动本身的实现。
以上两个步骤的补充说明:
(1)一般情况下,Linux驱动开发很少直接使用device和device_driver,因为内核在它们之上又封装了一层,如soc device、platform device等等,而这些层次提供的接口更为简单、易用(也正是因为这个原因,本文并不会过多涉及device、device_driver等模块的实现细节)。
(2)内核提供很多struct device结构的操作接口(具体可以参考include/linux/device.h和drivers/base/core.c的代码),主要包括初始化(device_initialize)、注册到内核(device_register)、分配存储空间+初始化+注册到内核(device_create)等等,可以根据需要使用。
(3) device和device_driver必须具备相同的名称,内核才能完成匹配操作,进而调用device_driver中的相应接口。这里的同名,作用范围是同一个bus下的所有device和device_driver。
(4) device和device_driver必须挂载在一个bus之下,该bus可以是实际存在的,也可以是虚拟的。
(5) driver开发者可以在struct device变量中,保存描述设备特征的信息,如寻址空间、依赖的GPIOs等,因为device指针会在执行probe等接口时传入,这时driver就可以根据这些信息,执行相应的逻辑操作了。
4. 设备驱动probe的时机
所谓的"probe”,是指在Linux内核中,如果存在相同名称的device和device_driver(注:还存在其它方式,我们先不关注了),内核就会执行device_driver中的probe回调函数,而该函数就是所有driver的入口,可以执行诸如硬件设备初始化、字符设备注册、设备文件操作ops注册等动作("remove”是它的反操作,发生在device或者device_driver任何一方从内核注销时,其原理类似,就不再单独说明了)。
设备驱动prove的时机有如下几种(分为自动触发和手动触发):
将struct device类型的变量注册到内核中时自动触发(device_register,device_add,device_create_vargs,device_create)
将struct device_driver类型的变量注册到内核中时自动触发(driver_register)
手动查找同一bus下的所有device_driver,如果有和指定device同名的driver,执行probe操作(device_attach)
手动查找同一bus下的所有device,如果有和指定driver同名的device,执行probe操作(driver_attach)
自行调用driver的probe接口,并在该接口中将该driver绑定到某个device结构中----即设置dev->driver(device_bind_driver)
注2:probe动作实际是由bus模块(会在下一篇文章讲解)实现的,这不难理解:device和device_driver都是挂载在bus这根线上,因此只有bus最清楚应该为哪些device、哪些driver配对。
注3:每个bus都有一个drivers_autoprobe变量,用于控制是否在device或者driver注册时,自动probe。该变量默认为1(即自动probe),bus模块将它开放到sysfs中了,因而可在用户空间修改,进而控制probe行为。
参考博文:https://blog.csdn.net/qq_16777851/java/article/details/81459931