大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。
- 模块初始化
- 驱动程序注冊
以下以内核提供的演示样例代码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这个函数。
1.2 模块初始化
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 MODULE1910 printk(version);1911 #endif1912 return pci_register_driver(&netdrv_pci_driver);1913 }
能够看到,初始化函数非常easy,仅仅运行了一个pci_register_driver函数就返回了。
2. 驱动程序注冊
2.1 linux总线设备驱动模型
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); 。。。 68 };
设备:
406 struct device { 407 struct device *parent; 408 409 struct device_private *p; 410 411 struct kobject kobj; 412 const char *init_name; /* initial name of the device */ 413 struct device_type *type; 414 415 struct mutex mutex; /* mutex to synchronize calls to 416 * its driver. 417 */ 418 419 struct bus_type *bus; /* type of bus device is on */ 420 struct device_driver *driver; /* which driver has allocated this 421 device */ 。。。 456 457 void (*release)(struct device *dev); 458 };
驱动:
122 struct device_driver { 123 const char *name; 124 struct bus_type *bus; 125 126 struct module *owner; 127 const char *mod_name; /* used for built-in modules */ 128 129 bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ 130 131 #if defined(CONFIG_OF) 132 const struct of_device_id *of_match_table; 133 #endif 134 135 int (*probe) (struct device *dev); 136 int (*remove) (struct device *dev); 。。。 145 };
2.2 注冊函数具体解释
2.2.1 驱动的描写叙述
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 calle d */ 546 int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New de vice 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。。。174 struct device_driver driver;175 const struct i2c_device_id *id_table;176177 /* 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 };
我们能够看出来,并非这个结构体的全部成员我们都要操作,我们仅仅管当中最关键的几个即可了。
它的作用是匹配驱动所支持的设备。相同看看代码中的使用方法:
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);
这里表示的就是本驱动程序支持的设备类型。
当驱动匹配到了相应的设备之后,就会调用该函数来驱动设备。所以能够说这个函数才是驱动程序真正的入口。
2.2.2 驱动-设备的匹配
匹配到了相应的设备之后,就会调用该函数来驱动设备。这个匹配是什么意思?怎样进行匹配?跟bus结构体中的match函数有没有关系?
1103 int __pci_register_driver(struct pci_driver *drv, struct module *owner, 1104 const char *mod_name) 1105 { 1106 int error; 1107 1108 /* 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 1114 spin_lock_init(&drv->dynids.lock); 1115 INIT_LIST_HEAD(&drv->dynids.list); 1116 1117 /* register with core */ 1118 error = driver_register(&drv->driver); 1119 if (error) 1120 goto out; 1121 。。。。。。。。 1137 }
222 int driver_register(struct device_driver *drv) 223 { 224 int ret; 225 struct device_driver *other; 226 227 BUG_ON(!drv->bus->p); 228 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); 234 235 other = driver_find(drv->name, drv->bus); 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 243 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, NULL, NULL); 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 <span style="color:#ff0000;">error = fn(dev, data);</span> 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)) 280 return 0; 281 282 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); 287 device_unlock(dev); 288 if (dev->parent) 289 device_unlock(dev->parent); 290 291 return 0; 292 }
279行的driver_match_device函数就是用来为driver匹配device的
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中注冊的match函数来进行匹配了,匹配的详细过程就不看了。再回到上面的__driver_attach函数的driver_probe_device中。
200 int driver_probe_device(struct device_driver *drv, struct device *dev) 201 { 202 int ret = 0; 203 204 if (!device_is_registered(dev)) 205 return -ENODEV; 206 207 pr_debug("bus: '%s': %s: matched device %s with driver %s\n", 208 drv->bus->name, __func__, dev_name(dev), drv->name); 209 210 pm_runtime_get_noresume(dev); 211 pm_runtime_barrier(dev); 212 ret = really_probe(dev, drv); 213 pm_runtime_put_sync(dev); 214 215 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 124 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. 总结
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118281.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...