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。
设备树文件格式关系图 .dtsi SoC公共定义 .dts 单板源文件 .dtb 二进制Blob #include 编译 反编译 关键说明 • .dtsi 通常由芯片厂商提供,描述CPU、中断控制器、时钟等 • .dts 由板级开发者编写,包含GPIO、外设、内存分区等板级信息 • .dtb 是最终加载到内核的二进制数据,大小通常为几KB到几十KB

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 编译与反编译流程

DTC编译与反编译流程 myboard.dts 文本源文件 DTC 编译器 dtc -I dts -O dtb myboard.dtb 二进制Blob 反编译 编译命令示例 dtc -I dts -O dtb -o myboard.dtb myboard.dts

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用于详细模式