3. 设备树编译器(DTC):工具安装、文件格式与编译命令
设备树编译器(Device Tree Compiler,DTC)是嵌入式Linux开发中处理设备树源文件的核心工具。它将人类可读的.dts源文件编译为二进制.dtb文件供内核解析,也能反向将.dtb反编译为.dts。本章系统讲解DTC的安装、三种文件格式的区别以及编译/反编译命令。
3.1 DTC工具安装
DTC通常包含在设备树编译工具包中,主流Linux发行版均可通过包管理器直接安装:
| 发行版 | 安装命令 | 安装后验证 |
|---|---|---|
| Ubuntu/Debian | sudo apt-get install device-tree-compiler |
dtc --version |
| Fedora/CentOS/RHEL | sudo dnf install dtc |
dtc --version |
| Arch Linux | sudo pacman -S dtc |
dtc --version |
| Buildroot/Yocto | 默认包含在host-dtc包中 |
dtc --version |
提示:如果使用交叉编译环境,建议从内核源码的
scripts/dtc/ 目录编译本地版本:make scripts/dtc,确保与内核版本匹配。
3.2 dts / dtb / dtsi 文件格式区别
设备树涉及三种核心文件格式,它们各自承担不同的角色:
| 格式 | 全称 | 文件类型 | 可读性 | 用途 |
|---|---|---|---|---|
.dts |
Device Tree Source | 文本源文件 | 人类可读 | 描述单板硬件拓扑,是编译的输入 |
.dtb |
Device Tree Blob | 二进制文件 | 机器可读 | 内核/U-Boot直接加载解析的二进制数据 |
.dtsi |
Device Tree Source Include | 文本头文件 | 人类可读 | 公共定义、SoC通用部分,被.dts包含 |
核心关系:
.dtsi 通过 #include 被 .dts 引用,.dts 通过 DTC 编译生成 .dtb。反编译则将 .dtb 还原为 .dts。
3.3 编译与反编译命令
3.3.1 基本编译命令
将.dts源文件编译为.dtb二进制文件:
# 基本编译
dtc -I dts -O dtb -o output.dtb input.dts
# 常用参数说明
# -I dts : 指定输入格式为dts(默认)
# -O dtb : 指定输出格式为dtb
# -o output.dtb : 指定输出文件名
# -@ : 生成符号节点(用于overlay)
# -H epapr : 生成epapr头部(某些PowerPC平台需要)
实践示例:编译一个简单的设备树源文件
# 假设当前目录有 myboard.dts
dtc -I dts -O dtb -o myboard.dtb myboard.dts
# 编译并输出详细信息(显示包含的文件、节点数等)
dtc -I dts -O dtb -o myboard.dtb myboard.dts -V
# 编译时保留所有符号(用于设备树overlay)
dtc -I dts -O dtb -o myboard.dtb myboard.dts -@
3.3.2 基本反编译命令
将.dtb二进制文件反编译为可读的.dts源文件:
# 基本反编译
dtc -I dtb -O dts -o output.dts input.dtb
# 常用参数说明
# -I dtb : 指定输入格式为dtb
# -O dts : 指定输出格式为dts
# -o output.dts : 指定输出文件名
# -s : 输出排序后的节点(便于对比差异)
调试技巧:反编译是验证
.dtb内容是否正确的最直接方法。如果内核启动时设备树解析异常,先反编译.dtb检查节点结构。
3.3.3 常用编译选项汇总
| 选项 | 说明 | 使用场景 |
|---|---|---|
-I dts |
输入格式为dts文本 | 编译源文件 |
-I dtb |
输入格式为dtb二进制 | 反编译 |
-O dtb |
输出格式为dtb二进制 | 编译 |
-O dts |
输出格式为dts文本 | 反编译 |
-o <file> |
指定输出文件名 | 所有场景 |
-@ |
生成__symbols__节点 | 设备树overlay |
-s |
输出排序后的节点 | 反编译对比 |
-V |
显示详细编译信息 | 调试 |
-H epapr |
使用epapr头部格式 | PowerPC平台 |
3.3.4 编译与反编译流程
3.4 实战:完整编译与反编译示例
以下是一个完整的操作流程,从编写.dts到编译、反编译验证:
# 1. 创建一个简单的设备树源文件
cat > example.dts << EOF
/dts-v1/;
/ {
compatible = "myboard,example";
#address-cells = <1>;
#size-cells = <1>;
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x10000000>;
};
chosen {
bootargs = "console=ttyS0,115200";
};
uart0: serial@10000000 {
compatible = "ns16550";
reg = <0x10000000 0x1000>;
interrupts = <0 33 4>;
};
};
EOF
# 2. 编译为dtb
dtc -I dts -O dtb -o example.dtb example.dts
# 3. 查看编译后的二进制大小
ls -lh example.dtb
# 4. 反编译验证
dtc -I dtb -O dts -o example_decompiled.dts example.dtb
# 5. 对比原始与反编译文件(应完全一致)
diff example.dts example_decompiled.dts
常见错误:如果
.dts文件中缺少/dts-v1/;版本声明,DTC会报错并拒绝编译。务必在所有.dts文件第一行添加此声明。
3.5 本章小结
- DTC安装:通过包管理器或内核源码编译,验证命令
dtc --version - 文件格式:
.dts(源文件)、.dtb(二进制)、.dtsi(头文件)三者分工明确 - 编译命令:
dtc -I dts -O dtb -o output.dtb input.dts - 反编译命令:
dtc -I dtb -O dts -o output.dts input.dtb - 常用选项:
-@用于overlay,-s用于排序输出,-V用于详细模式