3. 设备树语法基础:节点、属性、标签、路径的语法规则
设备树(Device Tree)是一种描述硬件资源的树形数据结构,其语法简洁、层次分明。掌握节点(node)、属性(property)、标签(label)和路径(path)的语法规则,是编写和解析设备树源文件(.dts)的基础。本章将逐一拆解这四个核心要素,并通过对比表格和可视化 SVG 图帮助理解。
核心要点:设备树的本质是一个“硬件描述语言”,它通过树状结构将板级硬件信息(CPU、内存、外设、中断、GPIO 等)传递给 Linux 内核,实现驱动与硬件的解耦。
3.1 节点(Node)—— 树形结构的骨架
节点是设备树的基本组成单元,代表一个硬件设备或总线。每个节点可以包含子节点,形成从根到叶的层次关系。
3.1.1 节点定义语法
node-name {
property1 = <value>;
property2 = "string";
child-node {
...
};
};
- 节点名称:由字母、数字、连字符(
-)、下划线(_)组成,必须以字母开头。 - 节点体:用花括号
{ }包裹,内部包含属性和子节点。 - 结束符:每个节点定义后必须加分号
;。
3.1.2 根节点与特殊节点
| 节点类型 | 名称 | 说明 |
|---|---|---|
| 根节点 | / |
设备树的顶层节点,所有其他节点都是它的子节点。 |
| CPU 节点 | cpus |
描述处理器核心,通常包含多个子节点(每个 CPU 核心一个)。 |
| 内存节点 | memory |
描述系统物理内存的起始地址和大小。 |
| 别名节点 | aliases |
为其他节点定义简短的别名,方便引用。 |
| 选择节点 | chosen |
传递内核启动参数(如 bootargs),不描述具体硬件。 |
实战提示:根节点
/ 是设备树的入口,所有硬件描述都从根节点开始展开。在 .dts 文件中,根节点通常位于文件开头,且只能有一个。
3.2 属性(Property)—— 节点的数据载体
属性是节点内部用于描述硬件特性的键值对。属性值可以是整数、字符串、字节数组或它们的组合。
3.2.1 属性值类型与语法
| 值类型 | 语法示例 | 说明 |
|---|---|---|
| 32 位整数 | reg = <0x10000000 0x1000>; |
尖括号 <> 包裹,多个值用空格分隔。 |
| 64 位整数 | reg = <0x00000000 0x80000000>; |
用两个 32 位整数拼接表示高 32 位和低 32 位。 |
| 字符串 | compatible = "arm,cortex-a9"; |
双引号包裹,用于匹配驱动。 |
| 字符串列表 | compatible = "ti,am335x", "ti,omap3"; |
多个字符串用逗号分隔。 |
| 字节数组 | local-mac-address = [00 11 22 33 44 55]; |
方括号 [] 包裹,十六进制字节。 |
| 布尔值 | status = "disabled"; |
通过字符串表示,常用 "okay" 或 "disabled"。 |
| 混合类型 | reg = <0x1000 0x100>, [00 11]; |
用逗号分隔不同类型值。 |
3.2.2 标准属性速查
compatible:驱动匹配的关键,格式为"厂商,设备型号"。reg:描述设备地址空间,格式为<地址 长度>。interrupts:描述中断号、触发类型。clocks:引用时钟源。status:设备状态,可选"okay"、"disabled"、"reserved"。
常见错误:属性值末尾忘记加分号
; 是初学者最常犯的语法错误。设备树编译器(DTC)会报错并停止编译,务必检查每个属性行结尾。
3.3 标签(Label)—— 节点的引用别名
标签是附加在节点名称前面的标识符,用于在其他位置引用或覆盖该节点。标签可以显著提高设备树的可维护性。
3.3.1 标签定义语法
uart0: serial@44e09000 {
compatible = "ti,am3352-uart";
reg = <0x44e09000 0x2000>;
interrupts = <72>;
};
在上例中,uart0 就是标签。通过标签,可以在其他 .dtsi 或 .dts 文件中直接引用该节点:
&uart0 {
status = "okay";
pinctrl-0 = <&uart0_pins>;
};
3.3.2 标签的三大用途
| 用途 | 语法 | 示例 |
|---|---|---|
| 节点引用 | &label |
&uart0 { ... }; 引用并扩展 uart0 节点。 |
| 属性引用 | &label 作为属性值 |
clocks = <&clk_uart0>; 引用时钟节点。 |
| 路径别名 | aliases { ... }; |
aliases { serial0 = &uart0; }; 定义别名。 |
最佳实践:在编写
.dtsi(设备树包含文件)时,为所有关键外设节点添加标签(如 i2c0、spi1、mmc0),这样板级 .dts 文件可以通过 &label 轻松覆盖或启用这些设备,无需重复编写完整路径。
3.4 路径(Path)—— 节点的唯一地址
路径是从根节点到目标节点的完整字符串表示,类似于文件系统中的绝对路径。路径用于在设备树中唯一标识一个节点。
3.4.1 路径语法规则
- 以根节点
/开头。 - 各级节点名称用斜杠
/分隔。 - 节点名称可以包含
@后的地址部分(如serial@44e09000)。 - 路径末尾不加斜杠。
示例路径:
/soc/serial@44e09000
/cpus/cpu@0
/aliases
/chosen
3.4.2 路径与标签的对比
| 特性 | 路径(Path) | 标签(Label) |
|---|---|---|
| 表示方式 | 字符串,如 /soc/i2c@48020000 |
标识符,如 i2c0 |
| 唯一性 | 全局唯一,由树结构决定 | 全局唯一,由开发者定义 |
| 可读性 | 较长,但结构清晰 | 简短,便于记忆和引用 |
| 使用场景 | 在 dts 文件中直接定义节点 |
跨文件引用、覆盖节点属性 |
| 是否必须 | 每个节点都有唯一路径 | 可选,但强烈建议为关键节点添加 |
3.5 四要素关系 SVG 图
下图展示了节点、属性、标签、路径在设备树中的组织关系:
3.6 综合语法示例
以下是一个完整的设备树片段,综合展示了节点、属性、标签和路径的用法:
/dts-v1/;
/ {
model = "TI AM335x BeagleBone Black";
compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
cpus {
cpu@0 {
compatible = "arm,cortex-a8";
device_type = "cpu";
reg = <0x0>;
};
};
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256 MB */
};
chosen {
bootargs = "console=ttyO0,115200 root=/dev/mmcblk0p2 rw";
};
aliases {
serial0 = &uart0;
i2c0 = &i2c0;
};
soc {
uart0: serial@44e09000 {
compatible = "ti,am3352-uart";
reg = <0x44e09000 0x2000>;
interrupts = <72>;
status = "okay";
};
i2c0: i2c@48020000 {
compatible = "ti,omap4-i2c";
reg = <0x48020000 0x1000>;
interrupts = <70>;
status = "okay";
clock-frequency = <400000>;
};
};
};
关键解读:
- 根节点
/包含model、compatible等全局属性。 - 标签
uart0和i2c0定义在节点名称前,便于在aliases或其他位置引用。 - 路径
/soc/serial@44e09000是uart0节点的完整路径。 - 属性
reg、interrupts、status描述了设备的硬件资源。
3.7 常见语法错误与避坑指南
| 错误类型 | 错误示例 | 正确写法 |
|---|---|---|
| 缺少分号 | reg = <0x1000 0x100> |
reg = <0x1000 0x100>; |
| 花括号不匹配 | node { prop = "val"; }(缺少分号) |
node { prop = "val"; }; |
| 标签重复 | 两个节点使用相同标签 uart0 |
确保每个标签全局唯一 |
| 路径拼写错误 | &uart0 但实际标签为 uart1 |
使用 &uart1 或修正标签名 |
| 属性值类型错误 | reg = 0x1000;(缺少尖括号) |
reg = <0x1000>; |
编译检查:始终使用
dtc -I dts -O dtb -o output.dtb input.dts 命令编译设备树源文件,编译器会提示所有语法错误。不要手动“目测”检查,DTC 是最可靠的语法验证工具。
3.8 本章小结
- 节点是设备树的骨架,通过嵌套结构描述硬件层次。
- 属性是节点的数据内容,支持整数、字符串、字节数组等多种类型。
- 标签是节点的引用别名,用于跨文件覆盖和扩展节点。
- 路径是节点的唯一地址,从根节点开始逐级定位。
- 四要素协同工作,构成了设备树描述硬件的基础语法体系。