3. dtc 工具介绍:安装、基本用法与常用选项

dtc(Device Tree Compiler)是设备树开发中最核心的工具,负责将设备树源文件(.dts)编译为二进制设备树(.dtb),也支持反向反编译操作。掌握 dtc 的安装与常用选项,是进行设备树调试的第一步。

dtc 在设备树开发流程中的位置 .dts 源文件 文本格式 dtc 编译 -I dts -O dtb .dtb 二进制 内核加载 dtc -I dtb -O dts 反编译 调试常用场景 验证语法错误 检查节点结构 对比修改前后

3.1 dtc 的安装

dtc 通常包含在设备树编译器包中,不同发行版的包名略有差异。以下为常见 Linux 发行版的安装命令:

发行版 包名 安装命令
Ubuntu / Debian device-tree-compiler sudo apt install device-tree-compiler
Fedora / RHEL / CentOS dtc sudo dnf install dtc
Arch Linux dtc sudo pacman -S dtc
openSUSE dtc sudo zypper install dtc
源码编译 — git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git
cd dtc && make && sudo make install
💡 提示: 建议优先使用发行版官方仓库安装。若需最新特性(如插件支持、YAML 输出),可从内核官方仓库克隆源码编译。编译依赖 flex、bison 和 libyaml-dev。

3.2 基本用法

dtc 的基本调用格式为:

dtc [选项] [输入文件]

以下为最常用的三种操作模式:

  • 编译(.dts → .dtb): 将设备树源文件编译为内核可加载的二进制格式。
  • 反编译(.dtb → .dts): 将二进制设备树还原为可读的源文件,用于调试或逆向分析。
  • 格式转换与检查: 在 .dts、.dtb、.dtbo(叠加层)之间转换,同时进行语法和结构校验。

典型示例:

# 编译 .dts 为 .dtb
dtc -I dts -O dtb -o my_board.dtb my_board.dts

# 反编译 .dtb 为 .dts
dtc -I dtb -O dts -o my_board_decompiled.dts my_board.dtb

# 直接输出到终端(不生成文件)
dtc -I dtb -O dts my_board.dtb

3.3 常用选项详解

dtc 提供了丰富的命令行选项,以下为调试过程中最常用的选项:

选项 全称 说明 典型值
-I —Input format 指定输入文件格式 dts、dtb、fs(文件系统)
-O —Output format 指定输出文件格式 dts、dtb、dtbo、yaml
-o —Output file 指定输出文件名 output.dtb
-S —Size 指定 .dtb 文件最小大小(字节),不足时填充零 8192
-@ —Symbols 生成符号节点,支持设备树叠加层(overlay) 无参数
-H —Phandle 指定 phandle 格式(legacy/epapr/both) epapr
-V —Version 显示 dtc 版本信息 无参数
-W —Warning 启用指定警告 unit_address_vs_reg
-E —Error 将指定警告升级为错误 graph_child_address

3.4 关键选项深入解析

3.4.1 -I 与 -O:输入输出格式控制

这两个选项是 dtc 最核心的参数。-I 指定输入格式,-O 指定输出格式。支持以下格式:

  • dts: 设备树源文件(文本格式,人类可读)。
  • dtb: 设备树二进制文件(内核加载格式)。
  • dtbo: 设备树叠加层二进制(用于动态加载)。
  • fs: 从 /proc/device-tree 文件系统读取(仅输入)。
  • yaml: YAML 格式输出(需编译时启用 YAML 支持)。
🔍 调试技巧: 使用 -I fs 可以直接从运行中的内核导出当前设备树结构,无需重启或访问原始 .dtb 文件:
dtc -I fs -O dts /proc/device-tree

3.4.2 -S:指定输出大小

某些 bootloader 要求 .dtb 文件具有固定大小,-S 选项可强制输出文件至少为指定字节数,不足部分用零填充。这在为特定硬件平台生成设备树时非常有用。

# 生成至少 8KB 的 .dtb 文件
dtc -I dts -O dtb -S 8192 -o fixed_size.dtb my_board.dts

3.4.3 -@:启用叠加层支持

-@ 选项在编译时生成 __symbols__ 节点,记录所有带标签的节点和 phandle 信息。这是设备树叠加层(overlay)工作的基础。若计划使用 configfs 或 libfdt 动态加载设备树片段,必须使用此选项。

# 编译支持叠加层的 .dtb
dtc -I dts -O dtb -@ -o overlay_support.dtb my_board.dts
⚠️ 注意: 使用 -@ 会增加 .dtb 文件大小(约 10%~20%),且可能暴露内部符号信息。生产环境中如无需叠加层支持,建议省略此选项。

3.4.4 -W 与 -E:警告与错误控制

dtc 内置了多种检查规则,可通过 -W 启用特定警告,或通过 -E 将警告升级为错误,强制修正问题。

常用检查项:

检查项 说明 推荐场景
unit_address_vs_reg 检查节点地址与 reg 属性是否匹配 所有设备树
graph_child_address 检查图形子节点地址格式 DRM/GPU 设备树
avoid_unnecessary_addr_size 检查不必要的地址/大小单元 代码审查
unique_unit_address 检查同一层级节点地址是否唯一 复杂设备树
# 启用所有警告,并将 unit_address_vs_reg 升级为错误
dtc -I dts -O dtb -W all -E unit_address_vs_reg -o check.dtb my_board.dts
dtc 常用选项工作流程 输入文件 .dts / .dtb dtc 选项 -I dts / dtb / fs -O dts / dtb / yaml -S 指定最小大小 -@ 叠加层符号 -W / -E 检查控制 -H phandle 格式 输出文件 .dtb / .dts 调试建议 先 -W all 检查 再 -E 关键项 最后 -@ 叠加层

3.5 综合调试示例

以下是一个完整的设备树调试流程,展示如何组合使用 dtc 选项:

# 步骤1:编译源文件,启用所有警告
dtc -I dts -O dtb -W all -o debug.dtb my_board.dts

# 步骤2:若步骤1通过,反编译验证结构
dtc -I dtb -O dts debug.dtb

# 步骤3:检查特定问题(如地址不匹配),升级为错误
dtc -I dts -O dtb -W all -E unit_address_vs_reg -o strict.dtb my_board.dts

# 步骤4:生成支持叠加层的版本
dtc -I dts -O dtb -@ -o overlay.dtb my_board.dts

# 步骤5:从运行系统导出设备树进行对比
dtc -I fs -O dts /proc/device-tree > running.dts
📌 最佳实践: 在提交设备树代码前,始终使用 -W all -E unit_address_vs_reg 进行严格检查。这可以捕获大多数常见的节点结构错误,避免在内核启动时出现“无法找到节点”或“地址不匹配”等问题。

3.6 常见错误与排查

错误信息 原因 解决方案
FATAL ERROR: Unable to parse input tree .dts 文件语法错误 检查分号、花括号、引号是否匹配
WARNING: unit_address_vs_reg 节点地址与 reg 属性不匹配 确保节点名中的 @ 地址与 reg 第一个值一致
Error: phandle is not valid 引用了一个不存在的标签 检查 &label 是否正确定义
Error: overlay requires -@ option 编译叠加层时未使用 -@ 添加 -@ 选项重新编译
💡 提示: 使用 dtc -V 查看当前版本。如果遇到未知选项,请升级到最新版本。内核 5.10+ 推荐使用 dtc 1.6.0 以上版本。