赞
踩
记得有次面试的时候,面试官问我linux设备和驱动具体是如何匹配的。当时没有很详细的回答出来,我们可能就知道是通过设备树中的compatible属性进行匹配,但具体的匹配流程可能不知道。
Linux设备驱动模型中,需要我们关心总线、设备、驱动三个实体,总线将设备和驱动进行绑定,在内核每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,也会寻找与之匹配的设备,而匹配由总线完成。一般而言,一个现实的Linux设备和驱动需要挂接在一种总线上。根据代码,总结出大致的流程如下:
driver_match_device函数中会调用到bus_type中定义到match函数
- static inline int driver_match_device(struct device_driver *drv,
- struct device *dev)
- {
- return drv->bus->match ? drv->bus->match(dev, drv) : 1;
- }
以平台总线为例:
- struct bus_type platform_bus_type = {
- .name = "platform",
- .dev_groups = platform_dev_groups,
- .match = platform_match,
- .uevent = platform_uevent,
- .pm = &platform_dev_pm_ops,
- };
- EXPORT_SYMBOL_GPL(platform_bus_type);
则会调用到platform_match函数:
- static int platform_match(struct device *dev, struct device_driver *drv)
- {
- struct platform_device *pdev = to_platform_device(dev);
- struct platform_driver *pdrv = to_platform_driver(drv);
-
- /* When driver_override is set, only bind to the matching driver */
- if (pdev->driver_override)
- return !strcmp(pdev->driver_override, drv->name);
-
- /* Attempt an OF style match first */ /* 匹配设备数中compatible属性 */
- if (of_driver_match_device(dev, drv))
- return 1;
-
- /* Then try ACPI style match */
- if (acpi_driver_match_device(dev, drv))
- return 1;
-
- /* Then try to match against the id table */ /* 匹配id_table中的name */
- if (pdrv->id_table)
- return platform_match_id(pdrv->id_table, pdev) != NULL;
-
- /* fall-back to driver name match */ /* 最后匹配设备和驱动的name */
- return (strcmp(pdev->name, drv->name) == 0);
- }
我们可以看到匹配的顺序:
1、先用设备树中的 compatible
属性和 platform_driver
中的driver
中的 of_match_table
来匹配
2、再用 platform_driver
中的 id_table
中的 name
和 platform_device
中的 name
来匹配
3、最后用platform_device
中的name
和 platform_driver
中的 driver
中的 name
来匹配
以上是以平台总线的样例,其他定义总线bus_type匹配的亦如此。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。