1. 课程导论:设备树与 platform 总线在 Linux 驱动中的地位与作用
在嵌入式 Linux 驱动开发中,设备树(Device Tree)与 platform 总线是驱动框架的两大基石。设备树解决了硬件描述与内核代码的耦合问题,platform 总线则提供了驱动与设备之间的标准匹配与绑定机制。理解这两者的关系,是掌握现代 Linux 驱动开发的关键。
1.1 设备树:硬件描述的解耦利器
设备树是一种用于描述硬件资源的数据结构,以树形节点组织,每个节点代表一个硬件设备或总线。它替代了传统内核中大量的板级代码(board file),使得同一份内核镜像可以支持多种硬件平台。
核心价值:设备树将硬件配置信息从内核源码中剥离,由 bootloader 在启动时传递给内核,实现“一次编译,多处运行”。
设备树的核心组成
| 组件 | 说明 | 示例 |
|---|---|---|
| 节点(node) | 表示一个设备或总线,包含属性和子节点 | uart@fe001000 |
| 属性(property) | 描述设备的寄存器地址、中断号、时钟等资源 | reg = <0xfe001000 0x1000> |
| 兼容性(compatible) | 驱动与设备匹配的关键字符串 | compatible = "fsl,imx6q-uart" |
| 中断(interrupts) | 指定设备使用的中断号与触发方式 | interrupts = <0 56 4> |
设备树在驱动加载流程中的位置
下图展示了从设备树源文件(.dts)到驱动匹配成功的完整链路:
1.2 platform 总线:驱动与设备的桥梁
platform 总线是 Linux 内核中一种虚拟总线,用于管理那些不挂载在传统物理总线(如 PCI、USB、I2C)上的设备。它通过 name 或 compatible 属性实现驱动与设备的匹配,是嵌入式系统中使用最广泛的驱动模型。
platform 总线的核心数据结构
- platform_device:描述设备资源(地址、中断、DMA 等),可由设备树自动生成。
- platform_driver:描述驱动逻辑,包含 probe()、remove() 等回调函数。
- 匹配机制:通过
of_match_table与设备树节点的compatible属性进行匹配。
关键点:设备树中的每个节点在启动阶段会被内核解析为 platform_device,而驱动通过注册 platform_driver 并声明 compatible 字符串,即可与对应设备绑定。
设备树与 platform 总线的协作关系
下表总结了二者在驱动开发中的分工与交互:
| 维度 | 设备树 | platform 总线 |
|---|---|---|
| 职责 | 描述硬件资源与拓扑 | 管理驱动与设备的匹配 |
| 数据来源 | .dts 文件 → DTB | 内核注册的 platform_driver |
| 匹配依据 | compatible 属性 | of_match_table 中的字符串 |
| 生命周期 | 启动时解析,运行时只读 | 模块加载/卸载时动态管理 |
| 调试手段 | dtc 反编译、/proc/device-tree | /sys/bus/platform/devices/ |
1.3 为什么需要同时掌握两者?
在实际开发中,设备树与 platform 总线是前后衔接的关系:
- 硬件描述阶段:编写 .dts 文件,定义设备节点、寄存器地址、中断等资源。
- 驱动开发阶段:编写 platform_driver,通过
of_match_table与设备树节点匹配。 - 调试验证阶段:检查设备树解析是否正确、驱动 probe 是否被调用、资源是否获取成功。
常见误区:初学者往往只关注驱动代码,忽略设备树配置。实际上,设备树中一个错误的 reg 属性或中断号,会导致驱动 probe 失败或运行时异常。调试时务必先确认设备树节点是否被正确解析。