linux设备驱动程序注册过程详解

 原文地址:http://blog.csdn.net/tuzhutuzhu/article/details/34445847

Linux的驱动程序注册过程,大致分为两个步骤:

  • 模块初始化
  • 驱动程序注册

下面以内核提供的示例代码pci-skeleton.c,详细说明一个pci设备驱动程序的注册过程。其他设备的驱动代码注册过程基本相同,大家可自行查看。使用的内核代码版本是2.6.38。

1. 模块初始化

1.1 驱动程序入口

所有的设备驱动程序都会有如下两行代码:

1922 module_init( netdrv_init_module) ;
1923 module_exit( netdrv_cleanup_module) ;
module_init/module_exit是两个宏。module_init是该驱动程序的入口,加载驱动模块时,驱动程序就从netdrv_init_module函数开始执行。而当该驱动程序对应的设备被删除了,则会执行netdrv_cleanup_module这个函数。---至于何时驱动模块加载,何时驱动模块卸载,有待后续追踪follow up

1.2 模块初始化

当驱动程序开始执行时,首先会执行该驱动程序的初始化函数netdrv_init_module,代码如下:

1906  static  int __init  netdrv_init_module( void)
1907 {
1908  /* when a module, this is printed whether or not devices are found in probe */ 1909  #ifdef MODULE
1910     printk(version);
1911  #endif
1912      return  pci_register_driver(&netdrv_pci_driver);
1913 }
可以看到,模块初始化函数很简单,只执行了一个pci_register_driver函数就返回了。
其实模块的初始化过程就是这么简单,这也是linux驱动程序的ISO标准流程:module_init-->xx_init_module-->xx_register_driver。在这里xxx_register_driver中是驱动注册到XX总线上

International Standardization Operation
2. 驱动程序注册
什么是驱动模块的注册?上面讲到的初始化函数中调用的pci_register_driver()函数就是注册驱动程序啦。在介绍注册函数之前,必须要详细说明下linux的总线设备驱动模型,否则下面的内容很难描述清楚。

2.1 linux总线设备驱动模型

关于总线设备驱动模型,很多书上都有详细的讲解,但是都很抽象,很难理解(至少我是这样认为的)。下面我尽量用最简单的方法来说明相关内容。

linux内核中分别用struct bus_type,struct device和struct device_driver来描述总线、设备和驱动。

总线:

50  struct  bus_type {
  51      const char      *name;
  52      struct bus_attribute    *bus_attrs;
  53      struct  device_attribute *dev_attrs;
  54      struct  driver_attribute *drv_attrs;
  55
  56      int (*match)( struct device *dev, struct device_driver *drv);
};
设备:
406   struct  device {
407       struct  device       *parent;
408     struct  device_private   *p;
410     struct  kobject kobj;
412       const  char      *init_name;  /* initial name of the device */
413       struct  device_type  * type ;
414     struct  mutex        mutex;  /* mutex to synchronize calls to */
419       struct  bus_type *bus;        /* type of bus device is on */
420      struct device_driver *driver; /* which driver has allocated this 421 device */
456       void (* release )( struct device *dev);
458 };
驱动:
122  struct  device_driver {
123      const  char      *name;
124      struct bus_type *bus;
125      struct module *owner;
127      const  char *mod_name; /* used for built-in modules */
128      bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
130      #if defined(CONFIG_OF)
132      const  struct of_device_id *of_match_table;
133 #endif
135      int (* probe) ( struct device *dev);</span></strong>
136      int (* remove) ( struct device *dev); };

上述三个结构体中,我将下文需要使用的成员进行了标识,后面会讨论到。

对比上面的三个结构体,你会发现:总线中既定义了设备,也定义了驱动;设备中既有总线,也有驱动;驱动中既有总线也有设备相关的信息。那这三个的关系到底是什么呢?

扫描二维码关注公众号,回复: 1158850 查看本文章
三者的关系是:
内核要求每次出现一个设备,就要向总线汇报,会着说注册;每次出现一个驱动,也要向总线汇报,或者叫注册。比如系统初始化时,会扫描连接了哪些设备,并为每一个设备建立一个struct device变量,并为每一个驱动程序准备一个struct device_driver结构的变量。把这些量变量加入相应的链表,形成一条设备链表和一条驱动链表 。这样,就能通过总线找到注册挂载在该总线上的每一个设备和每一个驱动程序。

当一个struct device诞生,总线就会去driver链表找设备对应的驱动程序。如果找到就执行设备的驱动程序,否则就等待。反之亦然。

还有一个需要注意的地方:
usb_type总线结构体的match函数,它的两个参数一个是驱动struct device_driver*,另一个则是设备struct device *。这个函数就是用来进行判断,总线上的驱动程序能不能处理设备的。至于这个函数什么时候调用,怎么调用,后面会有说。

2.2 注册函数详解

下面我们来详细解释驱动的注册函数。

2.2.1 驱动的描述

首先从register函数的函数原型看起:

896  #define pci_register_driver(driver)     \
897     __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)


1103  int  __pci_register_driver( struct  pci_driver *drv,  struct  module *owner,
1104                const  char *mod_name)
真正的注册函数是__pci_register_driver(),它的第一个参数是struct pci_driver类型的,再看看这个结构的定义:
542   struct  pci_driver {
 
543       struct  list_head node;
  544       const  char *name;
  545       const   struct  pci_device_id *id_table;    /* must be non-NULL for probe to be called */
  546       int   (*probe)  ( struct  pci_dev *dev,  const   struct  pci_device_id *id);    /* New device inserted */
  547       void  (*remove) ( struct  pci_dev *dev);    /* Device removed (NULL if not a hot-plug capable driver) */
  548       int   (*suspend) ( struct  pci_dev *dev, pm_message_t state);  /* Device suspended */
 549     int  (*suspend_late) (struct pci_dev *dev, pm_message_t state);
 550     int  (*resume_early) (struct pci_dev *dev);
 551     int  (*resume) (struct pci_dev *dev);     /* Device woken up */
  552       void  (*shutdown) ( struct  pci_dev *dev);
  553       struct  pci_error_handlers *err_handler;
 554     struct device_driver    driver;
  555       struct  pci_dynids dynids;
 
556  };
仔细看这个结构,发现其中一个成员是我们上面的总线设备模型中的driver的结构体。 其实在linux内核中,所有设备的驱动的定义,都是以struct device_driver为基类,进行继承与扩展的。 你没有看错,内核当中使用了很多OO面向对象的思想。再看看网卡I2C设备的的驱动描述:
143  struct i2c_driver {
144      unsigned  int  class;
145     struct device_driver driver;
175      const  struct i2c_device_id *id_table;
176      /* Device detection callback for automatic device creation */
178      int (*detect)( struct i2c_client *, struct i2c_board_info *);
179      const  unsigned short *address_list;
180      struct list_head clients;
181 };
现在我们知道了pci设备的驱动程序的描述方法。但是问题又来了:这么复杂的一个结构体,我们怎么用呢?

首先看下实例代码中是怎么玩的:

1894  static  struct pci_driver netdrv_pci_driver = {
1895     .name       = MODNAME,
1896     .id_table   =  netdrv_pci_tbl,
1897     . probe      = netdrv_init_one,
1898     . remove     = __devexit_p(netdrv_remove_one),
1899  #ifdef CONFIG_PM 1900     .suspend    = netdrv_suspend,
1901     .resume     = netdrv_resume,
1902  #endif /* CONFIG_PM */
1903 };
我们可以看出来,并不是这个结构体的所有成员我们都要操作,我们只管其中最关键的几个就行了。

那上面的几个分别什么作用呢?

name:驱动模块的名字,这个可以忽略。

id_table:这个id的表很重要, 它的作用是匹配驱动所支持的设备 同样看看代码中的用法:

221 static DEFINE_PCI_DEVICE_TABLE(netdrv_pci_tbl) = {
 222     {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 223     {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NETDRV_CB },
 224     {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },
 225 /*  {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/
 226     {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 },
 227     {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
 228     {0,}
 229 };
 230 MODULE_DEVICE_TABLE(pci, netdrv_pci_tbl);
这里表示的就是本驱动程序支持的设备类型。

probe:这个函数指针同样很重要。 当驱动匹配到了对应的设备之后,就会调用该函数来驱动设备。 所以可以说这个函数才是驱动程序真正的入口。

remove:当驱动程序对应的设备被删除之后,使用这个函数来删除驱动程序。

综合看来,上面的id_table和probe函数好像是最重要的,那我们就看看它们是怎么使用的。

2.2.2 驱动-设备的匹配

上面在说明probe函数的时候说到:当驱动 匹配 到了对应的设备之后,就会调用该函数来驱动设备。这个匹配是什么意思?如何进行匹配?跟bus结构体中的match函数有没有关系?

带着这几个问题,我们来看看register函数。这里我将只说明驱动-设备匹配相关的内容,过程中看到的其他内容不在讨论范围内。我们将调用过程加粗和标红。

1103  int __pci_register_driver( struct pci_driver *drv,  struct  module *owner,
1104               const  char *mod_name)
1105 {
1106      int error;
1107     /* initialize common driver fields */
1109     drv->driver.name = drv->name;
1110     drv->driver.bus = &pci_bus_type;
1111     drv->driver.owner = owner;
1112     drv->driver.mod_name = mod_name;
1113     spin_lock_init(&drv->dynids.lock);
1115      INIT_LIST_HEAD(&drv->dynids. list);
1116     /* register  with core */
1118     error =  driver_register(&drv->driver);
1119      if (error)
1120         goto out;
1121
         。。。。。。。。
1137 }

__pci_register_driver函数中,调用driver_register,在总线上注册驱动。

222 int  driver_register( struct device_driver *drv)
223 {
224     int ret;
225     struct device_driver *other ;
227     BUG_ON(!drv->bus->p) ;
229     if (( drv->bus->probe  && drv->probe) ||
230         ( drv->bus->remove  && drv->remove) ||
231         ( drv->bus->shutdown  && drv->shutdown))
232         printk( KERN_WARNING  "Driver '%s' needs updating - please use "
233              "bus_type methods\n", drv->name) ;
235     other = driver_find( drv->name, drv->bus) ;//根据driver_name 在bus链表上面查找到驱动driver(驱动链表& 设备链表)
236     if ( other) {//驱动已经被注册了
237         put_driver( other) ;
238         printk( KERN_ERR  "Error: Driver '%s' is already registered, "
239              "aborting...\n", drv->name) ;
240         return -EBUSY ;
241     }
242     ret = bus_add_driver(drv) ;//总线上添加传递的驱动(将驱动添加到驱动链表中去)
244     if ( ret)
245         return ret ;
246     ret = driver_add_groups( drv, drv->groups) ;
247     if ( ret)
248         bus_remove_driver( drv) ;
249     return ret ;
250 }

driver_register中调用bus_add_driver,将设备驱动添加到总线上。

625 int  bus_add_driver(struct device_driver *drv)
  626 {
  。。。。。。。。。。。。。
  642     klist_init(&priv->klist_devices,  NULLNULL);
  643     priv->driver = drv;
  644     drv->p = priv;
  645     priv->kobj.kset = bus->p->drivers_kset;
  646     error = kobject_init_and_add(&priv->kobj, &driver_ktype,  NULL,
  647                      "%s", drv->name);
  648      if (error)
  649          goto out_unregister;
  650
  651      if (drv->bus->p->drivers_autoprobe) {
  652         error = driver_attach(drv);
  653 if (error)
654      goto out_unregister
655 } 。。。。。。。。。。。。。。。
690 }
303 int  driver_attach(struct device_driver *drv)
304 {
305      return  bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
306 }
可以看出来,上面将驱动程序追加到总线上之后,现在开始将设备与驱动进行匹配了。
285 int  bus_for_each_dev(struct bus_type *bus, struct device *start,
  286              void * data, int (* fn)( struct  device *,  void *))
  287 {
  。。。。。。。。。。。。
  295     klist_iter_init_node(&bus->p->klist_devices, &i,
  296                  (start ? &start->p->knode_bus :  NULL));
  297     while ((dev = next_device(&i)) && !error)
  298         error = fn(dev, data);
299          klist_iter_exit(&i);
300          return error;
301 }
这里的fn就是__driver_attach函数,我们来看一下它干了什么:
265  static  int  __driver_attach( struct device *dev,  void *data)
266 {
267      struct device_driver *drv = data;
。。。。。。。。。。。。。。。
279     if (!driver_match_device(drv, dev))//在驱动driver注册到总线时调用match函数
280          return  0;
281     if (dev->parent)    /* Needed for USB */
283     device_lock(dev->parent);
284     device_lock(dev);
285      if (!dev->driver)
286         driver_probe_device(drv, dev);//当驱动注册到总线并match成功后,调用驱动probe()函数
287     device_unlock(dev);
288      if (dev->parent)
289         device_unlock(dev->parent);
290     return  0;
292 }

279行的driver_match_device函数就是用来为driver匹配device的。match函数和probe函数被调用的地方

 if (!driver_match_device(drv, dev))//在驱动driver注册到总线时调用match函数。

286         driver_probe_device(drv, dev);//当驱动注册到总线并match成功后,调用驱动probe()函数


108 static inline int driver_match_device(struct device_driver *drv,
109                       struct device *dev)
110 {
111     return drv->bus->match ? drv->bus->match(dev, drv) : 1;
112 }

这里开始调用device_driver中注册BUS总线上的match函数来进行匹配了,匹配的具体过程就不看了。再回到上面的__driver_attach函数的driver_probe_device中。

200  int  driver_probe_device( struct  device_driver *drv,  struct  device *dev)
201 {
202      int ret =  0;
203     if (!device_is_registered(dev))
205          return -ENODEV;
206     pr_debug( "bus: '%s': %s: matched device %s with driver %s\n",
208          drv->bus->name, __func__, dev_name(dev), drv->name);
209     pm_runtime_get_noresume(dev);
211     pm_runtime_barrier(dev);
212     ret =  really_probe(dev, drv);
213     pm_runtime_put_sync(dev);
214     return ret;
216 }
108  static  int  really_probe( struct  device *dev,  struct  device_driver *drv)
109 {
110      int ret =  0;
111 112     atomic_inc(&probe_count);
113     pr_debug( "bus: '%s': %s: probing driver %s with device %s\n",
114          drv->bus->name, __func__, drv->name, dev_name(dev));
115     WARN_ON(!list_empty(&dev->devres_head));
116 117     dev->driver = drv;
118      if (driver_sysfs_add(dev)) {
119         printk(KERN_ERR  "%s: driver_sysfs_add(%s) failed\n",
120             __func__, dev_name(dev));
121         goto probe_failed;
122     }
123     if (dev->bus->probe) {
125         ret =  dev->bus->probe(dev);
126          if (ret)
127             goto probe_failed;
128     }  else  if (drv->probe) {
129         ret =  drv->probe(dev);
130          if (ret)
131             goto probe_failed;
132     }
133
   。。。。。。。。。。。。。。
160 }

到这里,终于看到drv->probe函数了。驱动程序的probe函数开始执行了,驱动程序的注册工作也就大功告成了。

3. 总结

我们来总结一下设备驱动程序初始化的几个步骤:

1. 根据设备类型,构造所需描述驱动的结构体。该结构体需要继承struct device_driver结构,并给几个重要的成员初始化。

2. 通过module_init宏调用驱动程序的初始化函数xx_init_module,在初始化函数中注册驱动程序。

3.驱动程序会遍历总线上的struct device和struct device_driver两条链表,调用总线的match函数,对设备与驱动程序进行匹配。

4.如果设备与驱动程序匹配成功,则调用驱动程序的probe函数。probe函数的实现,需要根据驱动程序的功能来定,不属于本文的讨论范围。


猜你喜欢

转载自blog.csdn.net/clam_zxf/article/details/80340664