3. 设备树常用属性详解:compatible、reg、interrupts、status、phandle 等核心属性
设备树(Device Tree)通过节点(node)和属性(property)来描述硬件拓扑。属性是设备树中最基本的“键-值”对,每个属性承载一种硬件特征或配置参数。本章深入剖析 compatible、reg、interrupts、status、phandle 等最常用的核心属性,帮助你在编写或修改设备树时准确表达硬件信息。
3.1 compatible 属性:驱动匹配的“身份证”
compatible 是设备树中最重要的属性之一,它指定了设备与驱动之间的匹配关系。内核通过该属性查找对应的驱动程序。
3.1.1 语法与规范
compatible = "manufacturer,model";
推荐格式为 "厂商,型号",例如:
compatible = "ti,am335x-uart", "ns16550";
多个字符串表示兼容性列表,内核按顺序匹配,优先使用第一个匹配成功的驱动。
3.1.2 匹配优先级
| 匹配顺序 | compatible 值 | 说明 |
|---|---|---|
| 1 | "ti,am335x-uart" | 最精确的芯片型号匹配 |
| 2 | "ns16550" | 通用兼容型号匹配 |
3.1.3 驱动匹配流程 SVG
3.2 reg 属性:描述设备地址空间
reg 属性用于描述设备在总线上的地址范围,包括起始地址和长度。它是内存映射设备、SPI/I2C 设备等硬件资源定位的核心依据。
3.2.1 基本语法
reg = <address1 length1 [address2 length2 ...]>;
每个 address,length 对描述一段连续的地址空间。例如:
uart@44e09000 {
compatible = "ti,am335x-uart", "ns16550";
reg = <0x44e09000 0x2000>;
};
表示 UART 设备从物理地址 0x44e09000 开始,占用 0x2000 字节的地址空间。
3.2.2 多段地址空间
当设备需要多个不连续的地址区域时,可以包含多组地址:
reg = <0x40000000 0x10000
0x50000000 0x20000>;
第一段:0x40000000 起始,0x10000 长度;第二段:0x50000000 起始,0x20000 长度。
3.2.3 #address-cells 与 #size-cells
reg 的解析依赖于父节点的 #address-cells 和 #size-cells 属性:
| 属性 | 含义 | 常见值 |
|---|---|---|
| #address-cells | 地址字段占用的 32 位单元数 | 1(32位地址)或 2(64位地址) |
| #size-cells | 长度字段占用的 32 位单元数 | 1(32位长度)或 2(64位长度) |
#address-cells = <1>; #size-cells = <1>;,则 reg = <0x44e09000 0x2000> 表示地址 0x44e09000,长度 0x2000。
3.2.4 reg 属性结构 SVG
3.3 interrupts 属性:中断资源描述
interrupts 属性描述设备使用的中断资源,包括中断号、触发类型等信息。它是设备与中断控制器之间的桥梁。
3.3.1 基本语法
interrupts = <interrupt-specifier>;
中断描述符的格式由父节点的 #interrupt-cells 决定。常见 ARM GIC 中断控制器使用 3 个 cell:
interrupts = <0 30 4>;
| Cell 位置 | 含义 | 常见值 |
|---|---|---|
| Cell 0 | 中断类型 | 0 = SPI(共享外设中断),1 = PPI(私有外设中断) |
| Cell 1 | 中断号 | SPI 中断号(32~1019),PPI 中断号(16~31) |
| Cell 2 | 触发类型 | 1 = 上升沿触发,4 = 高电平触发 |
3.3.2 interrupt-parent 属性
当设备的中断控制器不是其父节点时,需要使用 interrupt-parent 显式指定中断控制器:
device@1000 {
compatible = "my,device";
reg = <0x1000 0x100>;
interrupt-parent = <&gic>;
interrupts = <0 42 4>;
};
3.3.3 中断映射关系 SVG
3.4 status 属性:设备状态控制
status 属性用于控制设备是否启用。它是设备树覆盖和动态加载中最常用的属性之一。
3.4.1 可选值
| 值 | 含义 | 说明 |
|---|---|---|
| "okay" | 设备启用 | 驱动正常 probe,设备可用 |
| "disabled" | 设备禁用 | 驱动不会 probe,设备不可用 |
| "reserved" | 保留状态 | 设备被固件保留,操作系统不应使用 |
| "fail" | 设备故障 | 设备检测到错误,驱动不应 probe |
3.4.2 覆盖场景示例
// 基础设备树中禁用
&uart0 {
status = "disabled";
};
// 设备树覆盖中启用
&uart0 {
status = "okay";
};
3.5 phandle 属性:节点引用机制
phandle(指针句柄)是设备树中实现节点间引用的核心机制。每个节点可以有一个唯一的 phandle 值,其他节点通过该值引用它。
3.5.1 隐式 phandle 与显式 phandle
现代设备树通常使用 隐式 phandle,由 DTC 编译器自动分配:
// DTS 源文件
gic: interrupt-controller@f0001000 {
compatible = "arm,gic-400";
reg = <0xf0001000 0x1000>;
interrupt-controller;
#interrupt-cells = <3>;
};
// 引用方式
device@1000 {
interrupt-parent = <&gic>;
interrupts = <0 42 4>;
};
编译后,DTC 自动为 gic 节点生成唯一的 phandle 值,&gic 被替换为对应的数值。
3.5.2 显式 phandle 定义
my_node: node@100 {
phandle = <0x1234>;
compatible = "my,device";
};
3.5.3 phandle 引用关系 SVG
3.6 其他常用属性速查
| 属性名 | 用途 | 示例 |
|---|---|---|
| clock-names | 时钟名称列表,与 clocks 属性对应 | clock-names = "uart_clk", "baud_clk"; |
| clocks | 时钟 phandle 列表 | clocks = <&clk_uart &clk_baud>; |
| pinctrl-names | 引脚控制状态名称列表 | pinctrl-names = "default", "sleep"; |
| pinctrl-0 | 引脚控制配置 phandle | pinctrl-0 = <&uart0_pins>; |
| dma-names | DMA 通道名称列表 | dma-names = "rx", "tx"; |
| dmas | DMA 通道 phandle 列表 | dmas = <&edma0 2 &edma0 3>; |
| power-domains | 电源域 phandle | power-domains = <&pd_core>; |
| resets | 复位控制器 phandle | resets = <&rst 10>; |
3.7 属性组合实战案例
以下是一个完整的 UART 设备节点,综合运用了本章介绍的核心属性:
uart0: serial@44e09000 {
compatible = "ti,am335x-uart", "ns16550";
reg = <0x44e09000 0x2000>;
interrupts = <0 72 4>;
interrupt-parent = <&gic>;
status = "okay";
clock-names = "uart_clk", "baud_clk";
clocks = <&clk_uart &clk_baud>;
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
dma-names = "rx", "tx";
dmas = <&edma 2 &edma 3>;
};
- compatible:驱动匹配的唯一标识,精确在前,通用在后
- reg:描述设备地址空间,受 #address-cells / #size-cells 影响
- interrupts:中断资源描述,格式由中断控制器的 #interrupt-cells 决定
- status:设备启用/禁用控制,覆盖操作中最常用的属性
- phandle:节点引用机制,实现设备树内部的资源关联