1. 设备树基础概念
1.1 什么是设备树
设备树(Device Tree)是一种描述硬件资源的数据结构,它使用树形节点来记录系统中所有可访问的设备、总线、中断控制器、时钟、GPIO 控制器等硬件信息。设备树源文件(.dts)经过设备树编译器(DTC)编译为二进制设备树 Blob(.dtb),在系统启动时由 Bootloader 传递给内核。
核心定义:设备树是一个与体系结构无关的、描述硬件拓扑和资源配置的静态数据块,它替代了传统 ARM Linux 中大量硬编码的
board-*.c 文件。
| 术语 | 全称 | 说明 |
|---|---|---|
| DTS | Device Tree Source | 设备树源文件,人类可读的文本格式 |
| DTC | Device Tree Compiler | 将 DTS 编译为 DTB 的工具 |
| DTB | Device Tree Blob | 二进制设备树,内核直接解析的格式 |
| DTSI | Device Tree Source Include | 设备树头文件,用于复用公共定义 |
1.2 设备树的作用
设备树在嵌入式 Linux 系统中承担三个核心作用:
- 硬件描述标准化:将板级硬件信息从内核源码中剥离,形成独立的数据文件,避免为每块开发板修改内核代码。
- 驱动与设备解耦:驱动通过
compatible属性匹配设备节点,同一驱动可支持不同硬件平台。 - 资源动态传递:Bootloader 可根据实际硬件配置修改 DTB(如内存大小、MAC 地址),再传递给内核。
关键变化:在引入设备树之前,ARM Linux 内核的
arch/arm/mach-xxx 目录下充斥着大量板级文件;设备树统一了硬件描述接口,使主线内核能够支持更多开发板。
| 对比维度 | 传统板级文件方式 | 设备树方式 |
|---|---|---|
| 硬件描述位置 | 内核源码 board-*.c |
独立 .dts 文件 |
| 新增开发板成本 | 需新增 C 文件并重新编译内核 | 只需编写 DTS 文件 |
| 驱动可移植性 | 依赖特定板级宏定义 | 通过 compatible 匹配,跨平台 |
| 运行时修改 | 不支持 | Bootloader 可覆盖 DTB 属性 |
1.3 设备树与硬件描述的关系
设备树本质上是硬件资源的“静态快照”,它描述的是硬件在系统启动时的拓扑结构和资源配置,而不是硬件的行为或时序。每个设备节点对应一个硬件外设或总线,节点内的属性定义了该硬件的寄存器地址、中断号、时钟频率、GPIO 引脚等关键参数。
设备树中的每个节点通过以下属性与硬件建立对应关系:
compatible:指定设备兼容的驱动名称,内核据此查找匹配的驱动。reg:描述设备在总线上的地址空间,包括基地址和长度。interrupts:指定设备使用的中断号、触发类型。clocks:引用设备所需的时钟源。gpios/led-gpios:描述 GPIO 引脚绑定关系,本课程后续将重点讲解。
注意事项:设备树只描述硬件“有什么”和“在哪里”,不描述硬件“怎么用”。驱动需要根据设备树提供的资源信息,自行完成寄存器读写、中断处理等操作。设备树不是硬件抽象层(HAL),而是硬件资源清单。
1.4 设备树在 LED 驱动中的角色
在本课程关注的 gpio-leds 驱动场景中,设备树承担了以下关键职责:
- 定义 LED 设备节点及其子节点,每个子节点对应一个物理 LED。
- 通过
gpios属性指定 LED 连接的 GPIO 引脚。 - 通过
label属性设置 LED 的名称(如heartbeat、mmc0)。 - 通过
linux,default-trigger属性指定默认触发模式(如心跳、定时器)。 - 通过
default-state属性设置 LED 的初始状态(on/off/keep)。