LV06-05-linux平台总线模型-03-平台总线的匹配
平台总线怎么完成平台设备和平台驱动的匹配的?若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.2的64位版本 | |
VMware® Workstation 17 Pro | 17.6.0 build-24238078 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04 | |
linux内核 | linux-4.19.71(NXP官方提供) |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
nxp-imx/linux-imx/releases/tag/v4.19.71 | NXP linux内核仓库tags中的v4.19.71 | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 | NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0 | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) | |
Source Code | https://elixir.bootlin.com/linux/latest/source | linux kernel源码 |
kernel/git/stable/linux.git - Linux kernel stable tree | linux kernel源码(官网,tag 4.19.71) | |
https://elixir.bootlin.com/u-boot/latest/source | uboot源码 |
一、平台总线匹配
在前面学习总线的时候,我们知道,在编写总线驱动的时候都会实现一个xxx_match()函数来完成驱动和设备的匹配,平台总线也属于总线,内核已经帮我们实现好了这个函数:platform_match()。接下来就来了解一下。
1. platform_match()
platform_match() 函数定义如下:
1 | static int platform_match(struct device *dev, struct device_driver *drv) |

这里调用了 to_platform_device() 和 to_platform_driver() 宏。这两个宏定义的原型如下:
1 |
其中, to_platform_device() 和 to_platform_driver() 实现了对 container_of() 的封装, dev、driver分别作为struct platform_device、struct platform_driver 的成员变量, 通过 container_of() 宏可以获取到正在进行匹配的platform_driver 和platform_device 。

platform总线提供了四种匹配方式,并且这四种方式存在着优先级:设备树机制 > ACPI匹配模式 > id_table方式 > 字符串比较。
虽然匹配方式有这么多种,但是并没有涉及到任何复杂的算法,都只是在匹配的过程中,比较一下设备和驱动提供的某个成员的字符串是否相同。 设备树是一种描述硬件的数据结构,它用一个非C语言的脚本来描述这些硬件设备的信息,后面会详细学习。驱动和设备之间的匹配时通过比较compatible的值。 acpi主要是用于电源管理,基本上用不到,这里就暂时不去了解了。
2. 四种匹配方式
其实算起来算是5种匹配方式,并且有有优先级:
- 方式一:最先比较是否强制选择某个 driver
- 方式二:设备树匹配
- 方式三:ACPI匹配
- 方式四:id匹配
- 方式五:name匹配
2.1 方式一:是否强制选择某个 driver

这种方式比较的是 platform_device.driver_override 和 platform_driver.driver.name。可以设置 platform_device 的 driver_override,强制选择某个 platform_driver。这里就暂时不深入了解了。
2.2 方式二:设备树匹配
这个后面学习设备树的时候再学习,这里先简单了解一下。

设备树匹配比较的是 platform_device.dev.of_node 和 platform_driver.driver.of_match_table。由设备树节点转换得来的 platform_device 中,含有一个结构: struct device_node。它的类型如下:
1 | struct device_node { |
如果一个platform_driver支持设备树,它的 platform_driver.driver.of_match_table 是一个数组,类型为 struct of_device_id:
1 | /* |
使用设备树信息来判断 dev 和 drv 是否配对时 :
(1)首先,如果 of_match_table 中含有 compatible 值,就跟 dev 的 compatile属性比较,若一致则成功,否则返回失败;
(2)其次,如果 of_match_table 中含有 type 值,就跟 dev 的 device_type 属性比较,若一致则成功,否则返回失败;
(3)最后,如果 of_match_table 中含有 name 值,就跟 dev 的 name 属性比较,若一致则成功,否则返回失败。而设备树中建议不再使用 devcie_type 和 name 属性,所以基本上只使用设备节点的 compatible 属性来寻找匹配的 platform_driver。
2.3 方式三:ACPI匹配

ACPI(高级配置和电源接口),这里就暂时不去了解了。
2.4 方式四:id匹配

比较 platform_device.name 和 platform_driver.id_table[i].name, id_table 中可能有多项。
platform_driver.id_table是“platform_device_id”指针,表示该 drv支持若干个 device,它里面列出了各个 device 的{.name, .driver_data},其中的“ name”表示该 drv 支持的设备的名字, driver_data 是些提供给该device 的私有数据。
在platform_device和platform_driver中均含有“platform_device_id”指针,名字分别为platform_device.id_entry 和 platform_driver.id_table 。platform_driver.id_table 将会提供一个数组,里面包含这个驱动支持的所有设备的名称,以及私有数据,当设备和驱动匹配之后,会将驱动中匹配的这个设备的名字以及驱动将要提供的私有信息返回给设备中的platform_device.id_entry 成员:

所以,通过这种方式匹配的时候,platform_device.name 一定要存在于 platform_driver.id_table 指向的数组中,这样才可以完成匹配,并且匹配后,还可以获取到驱动中的一些信息。
2.5 方式五:name匹配

当前面的都没有匹配上时,就会使用名称匹配,就是比较 platform_device.name 和 platform_driver.driver.name :

通过这种方式完成匹配的话, platform_driver.id_table 需要为空或者里面没有 platform_device.name 。
3. 匹配方式总结
画张图来帮助理解,不考虑ACPI匹配方式:

二、平台总线匹配实现demo
1. 名称匹配demo
1.1 demo源码
06_platform_bus/03_name_match · 苏木/imx6ull-driver-demo - 码云 - 开源中国
1.2 开发板验证
将编译完的sdriver_demo.ko、sdevice_demo.ko拷贝到开发板,然后执行以下命令加载:
1 | insmod sdriver_demo.ko |
然后就会看到以下打印信息:

可以看到设备和驱动名称相同时,驱动中的xxx_probe()函数执行,然后会有提示驱动和设备匹配成功。我们再看一下 /sys/bus/platform/devices 和 /sys/bus/platform/drivers:

发现两个设备和驱动已经绑定在一起了。需要知道的是,这种匹配方式,驱动和设备的名称都是一样的,都是 sumu-sdev。
2. id匹配demo
2.1 demo源码
06_platform_bus/04_id_match · 苏木/imx6ull-driver-demo - 码云 - 开源中国
2.2 开发板验证
将编译完的sdriver_demo.ko、sdevice_demo.ko拷贝到开发板,然后执行以下命令加载:
1 | insmod sdevice_demo.ko |
然后就会看到以下打印信息:

驱动中的xxx_probe()函数执行,然后会有提示驱动和设备匹配成功。我们再看一下 /sys/bus/platform/devices 和 /sys/bus/platform/drivers:

可以看到驱动和设备的名字已经不同了,但是两者还是成功进行了匹配。
3. 设备树匹配
这个后面学习设备树了再说。
参考资料: