1.简介
在实际开发中,我们通过配置设备树里面的compatible属性,在将这个platform_driver注册到系统platform总线上时, 通过compatible属性匹配时,就会自动调用probe函数,进行platform_driver的初始化工作。在probe之前,其实有一些操作过程已经默认被执行了, 其整体流程如下:
2.platform_device生成时机
platform_device是自动在早期生成的。
2.1) 设备树解析时机
内核启动早期
- bootloader传递dtb给内核
- 内核入口->setup_arch->of_scan_flat_dt/unflatten_device_tree
- 把dtb解析成内核device_node树 ##### 2.2) 变换成platform_device 在arch/xxx/kernel/setup.c 里面of_platform_populate阶段
- a)遍历device_tree所有节点
- b)对根总线下、没有父总线的节点(如:串口、gpio、i2c控制器、触摸屏控制器)
- c)调用of_platform_device_create--->生成platform_device
d)在调用platform_device_add--->挂到platform_bus_type总线上。 备注:在内核启动很早阶段(init之前),设备树里面所有platform类型设备就已经 生成了platform_device,插入内核设备链表、sysfs。也就是driver注册前,所有platform_device都已经存在了。 ### 3.driver注册 ##### 1)驱动注册入口
module_platform_driver(xxx_driver); platform_driver_register(&xxx_driver); ->driver_register(&pdrv->driver) bus_add_driver driver_attach(drv) bus_for_each_dev(drv->bus,NULL,drv,__driver_attach)
##### 2)核心动作 遍历platform总线上所有的device。 bus_for_each_dev会把 platform_bus上所有 struct device(即所有platform_device) 逐个拿出来比对。
__driver_attach(dev,drv) driver_match_device(drv,dev) drv->bus->match(dev,drv) //platform_match
##### 3)platform_match 匹配顺序 代码路径:driver/base/platform.c
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); // 1. 优先:driver_override(强制绑定) if (pdev->driver_override) return !strcmp(pdev->driver_override, drv->name); // 2. 设备树:of_match_table 匹配 compatible //设备树compatible->of_match_table(最常用) if (of_driver_match_device(dev, drv)) return 1; // 3. ACPI if (acpi_driver_match_device(dev, drv)) return 1; // 4. platform_driver 的 id_table 匹配 if (pdrv->id_table) return platform_match_id(pdrv->id_table, pdev) != NULL; // 5. 最后:name 完全相等匹配(旧方式) return !strcmp(dev_name(dev), drv->name); }
### 4.匹配成功 成功后,调用流程。
__driver_attach device_bind_driver driver_probe_device really_probe pdrv->probe(pdev)
匹配成功后,驱动核心driver core主动调用probe 开发者,只负责注册driver,剩下内核遍历、匹配、调用probe全部自动完成 这个probe是在进程上下文,不是中断上下文,不是内核线程。 在多设备时,按照deive在总线链表上的顺序匹配,逐个probe,先匹配到先probe。 没有匹配成功的driver注册成功(返回0)不会调用probe,这个driver就静静在系统里面,等待未来出现的device 设备:
- platform_device 一直存在
- 没有驱动绑定 /sys/devices/.../driver目录不存在
- 不会有任何初始化,硬件存于默认/未管理状态 动态情况:
- 新设备被加入总线(比如热插拔,模块创建设备)
- 内核会再次扫描所有driver,尝试匹配并probe。 ### 5.汇总 platform_device:内核早期解析设备树时就全部建好并挂到 platform 总线。 platform_driver 注册时:内核在当前进程上下文,遍历总线所有 device,用 platform_match 按顺序匹配。 匹配成功 → 内核主动调用 probe(进程上下文);失败 → driver 待命,设备无驱动绑定。
您还没有登录,请您登录后发表评论。