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

posted @ 2020-05-16 14:17  Action_er  阅读(2201)  评论(0编辑  收藏  举报