3、设备树编译器(DTC):安装、编译、反编译与输出格式

设备树编译器(Device Tree Compiler,DTC)是设备树工具链的核心组件,负责将人类可读的 .dts 源文件转换为内核可解析的二进制 .dtb 文件,也支持反向操作。掌握 DTC 的安装、编译、反编译及输出格式,是进行设备树调试与内核故障定位的基础。

3.1 DTC 的安装

DTC 通常作为独立工具包或内核源码的一部分提供。推荐使用以下方式安装:

安装方式 命令/步骤 适用场景
包管理器安装(推荐) sudo apt-get install device-tree-compiler (Debian/Ubuntu)
sudo yum install dtc (CentOS/RHEL)
快速搭建开发环境,版本稳定
从内核源码编译 make scripts 或 make dtc (在内核根目录) 需要与内核版本严格对齐时
从 GitHub 源码编译 git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git
cd dtc && make && sudo make install
需要最新特性或修复补丁时
验证安装: 执行 dtc --version,若输出类似 Version: DTC 1.7.0 的信息,则安装成功。

3.2 编译:从 DTS 到 DTB

编译是将 .dts 源文件转换为内核可加载的二进制 .dtb 文件的过程。基本命令格式如下:

dtc -I dts -O dtb -o <输出文件.dtb> <输入文件.dts>

常用编译选项:

  • -I dts:指定输入格式为 DTS 源文件。
  • -O dtb:指定输出格式为 DTB 二进制文件。
  • -o <file>:指定输出文件名。
  • -@:生成可叠加的 DTB(支持 __symbols__ 节点,用于设备树叠加)。
  • -H epapr:指定生成的 DTB 使用 ePAPR 标准(默认)。
  • -W no-unit_address_vs_reg:关闭特定警告,用于兼容老旧 DTS。
实战示例:
# 将 myboard.dts 编译为 myboard.dtb,并启用叠加支持
dtc -I dts -O dtb -@ -o myboard.dtb myboard.dts

3.3 反编译:从 DTB 到 DTS

反编译用于将二进制 DTB 还原为可读的 DTS 源文件,是调试内核启动时实际加载的设备树配置的关键手段。

dtc -I dtb -O dts -o <输出文件.dts> <输入文件.dtb>

常用反编译选项:

  • -I dtb:指定输入格式为 DTB 二进制文件。
  • -O dts:指定输出格式为 DTS 源文件。
  • -s:在输出中保留原始偏移量信息,便于对比分析。
  • -f:强制覆盖输出文件。
注意: 反编译得到的 DTS 文件会丢失原始 DTS 中的注释和宏定义(如 #include 展开后的内容),但保留了完整的节点结构和属性值,足以用于故障定位。

3.4 输出格式详解

DTC 支持三种核心输出格式,理解其差异对调试至关重要:

格式 扩展名 类型 用途 可读性
DTS .dts 文本源文件 人类编辑、版本管理、代码审查 高
DTB .dtb 二进制文件 内核引导加载、Bootloader 传递、生产烧录 低
DTBO .dtbo 二进制叠加文件 运行时动态修改设备树(如外设模块热插拔) 低

3.5 设备树叠加(DTBO)编译

设备树叠加允许在不修改主 DTB 的情况下,动态添加或修改节点。编译叠加文件需使用 -@ 选项生成带符号的主 DTB,然后编译叠加 DTS:

# 1. 编译主 DTB(必须带 -@ 符号)
dtc -I dts -O dtb -@ -o main.dtb main.dts

# 2. 编译叠加 DTS 为 DTBO
dtc -I dts -O dtb -@ -o overlay.dtbo overlay.dts

加载 DTBO 通常由 Bootloader(如 U-Boot)或内核的 configfs 接口完成。

3.6 DTC 工作流程与数据流

下图展示了 DTC 在设备树开发与调试中的核心位置,以及三种输出格式之间的转换关系:

DTC 工作流程与输出格式转换 DTS 源文件 .dts (文本) DTC 编译器 dtc -I dts -O dtb DTB 二进制 .dtb (二进制) 反编译 DTS dtc -I dtb -O dts 叠加 DTS .dts (带 fragment) DTC 叠加编译 dtc -I dts -O dtb -@ DTBO 叠加文件 .dtbo (二进制) 调试关键路径 反编译 DTB → 分析实际配置

3.7 常用选项速查表

选项 功能 典型用法
-I <格式> 指定输入格式(dts/dtb/fs) -I dts
-O <格式> 指定输出格式(dts/dtb/asm) -O dtb
-o <文件> 指定输出文件路径 -o output.dtb
-@ 生成符号节点(支持叠加) -@ -o main.dtb
-s 反编译时保留偏移信息 -s -O dts
-W <警告> 启用特定警告 -W no-unit_address_vs_reg
-E <错误> 将警告视为错误 -E unit_address_vs_reg
-v 显示详细编译信息 -v -O dtb
-H <格式> 指定 DTB 头部格式 -H epapr

3.8 调试故障定位中的典型用法

案例:内核启动时外设未识别
  1. 提取实际加载的 DTB: 从 /sys/firmware/devicetree/base 复制或使用 dtc -I fs -O dtb -o captured.dtb /sys/firmware/devicetree/base。
  2. 反编译分析: dtc -I dtb -O dts -o captured.dts captured.dtb。
  3. 对比预期 DTS: 使用 diff 比较 captured.dts 与原始 .dts 文件,定位缺失或错误的节点/属性。
  4. 验证修复: 修改 DTS 后重新编译 dtc -I dts -O dtb -o fixed.dtb fixed.dts,替换内核使用的 DTB 并重启测试。
提示: 使用 dtc -O dts -I dtb -s 反编译时,-s 选项会输出每个节点在 DTB 中的偏移地址,有助于分析 DTB 结构是否被 Bootloader 修改过。