2、设备树基础语法:节点、属性、标签、引用、包含文件
设备树这东西,说白了就是一块板子的「硬件说明书」。你想想看,Linux 内核要跑起来,总得知道 CPU 接了什么外设、中断连到哪个引脚、时钟频率是多少吧?
我刚开始接触设备树时,觉得它就是个配置文件。后来踩了几个坑才明白——它其实是操作系统和硬件之间的「翻译官」。今天咱们就把设备树最核心的五个语法要素讲透。
2.1 节点——设备树的骨架
设备树里的每个硬件设备,都对应一个节点。节点用花括号 {} 包裹,格式长这样:
/dts-v1/;
/ {
model = "MyBoard";
compatible = "vendor,myboard";
cpu@0 {
compatible = "arm,cortex-a7";
reg = <0x00>;
};
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x40000000>;
};
};
根节点 / 是整个设备树的起点。每个子节点代表一个设备,比如 cpu@0 就是第一个 CPU 核心。
uart@1c20000,一看就知道是 UART,地址是 0x1c20000。这样后期维护时,不用翻手册就能定位。
2.2 属性——描述设备的「形容词」
属性就是节点的特征。常见的属性类型有:
| 属性类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | compatible = "vendor,device"; |
用于匹配驱动 |
| 32位整数 | reg = <0x10000000 0x1000>; |
地址和大小 |
| 64位整数 | reg = <0x00000000 0x80000000 0x00000000 0x40000000>; |
高32位在前 |
| 布尔值 | status = "disabled"; |
控制设备启用/禁用 |
| 字节数组 | local-mac-address = [00 11 22 33 44 55]; |
MAC 地址等 |
我在项目中遇到过最坑的事:有人把 reg 属性的地址写反了,结果驱动死活读不到寄存器。后来查了两天才发现——地址和大小必须成对出现,顺序不能乱。
2.3 标签——给节点起个「外号」
标签就是节点的别名。用 标签名: 放在节点名前:
uart1: serial@1c20000 {
compatible = "snps,dw-apb-uart";
reg = <0x1c20000 0x1000>;
interrupts = <0 10 4>;
};
这里 uart1 就是标签。后面引用时,直接用 &uart1 就行。
serial@1c20000。你每次引用都写全名,手不酸吗?标签就是给节点起个短名,方便引用。
2.4 引用——把散落的节点「串起来」
引用用 &标签名 表示。最常见的场景是:
- 在板级 dts 文件中,引用 SoC 级 dtsi 里的节点
- 给已有节点添加属性或修改属性
举个例子:
// soc.dtsi 中定义了 uart1
uart1: serial@1c20000 {
compatible = "snps,dw-apb-uart";
status = "disabled";
};
// board.dts 中引用并启用
&uart1 {
status = "okay";
clock-frequency = <24000000>;
};
你看,引用之后可以追加属性,也可以覆盖已有属性。这招在项目里特别实用——SoC 厂商提供基础 dtsi,板级厂商只需要引用并修改少量属性就行。
2.5 包含文件——代码复用的「法宝」
设备树支持 #include 预处理指令,用法和 C 语言一样:
#include "soc.dtsi"
#include "myboard-pinctrl.dtsi"
/ {
model = "MyBoard v2";
compatible = "vendor,myboard-v2";
};
包含文件的好处很明显:
- SoC 级定义(如 CPU、中断控制器、时钟)放在
.dtsi文件中 - 板级差异(如外设引脚、内存大小)放在
.dts文件中 - 多个板子可以共用同一个
.dtsi,减少重复代码
我建议你按这个层次组织文件:
- soc.dtsi:定义 SoC 内部所有外设,默认
status = "disabled" - myboard.dtsi:定义板级通用配置(如内存、时钟)
- myboard-v1.dts / myboard-v2.dts:具体板型的差异化配置
这样分层后,维护起来特别清爽。我参与的一个项目有 8 款板子,全靠这套分层结构,每次改版只需要改一个 .dts 文件。
2.6 知识体系总览
下面这张图,把设备树语法的核心逻辑串起来了:
嗯,这张图把今天讲的内容都串起来了。从根节点出发,到子节点,再到属性、标签、引用,最后通过包含文件组织成完整的设备树,编译成 .dtb 供内核使用。
设备树语法其实不复杂,核心就是这五个要素。你只要把节点、属性、标签、引用、包含文件这五样东西搞明白,剩下的就是多写多练了。
可可精品资料库