3. dtc 工具介绍:安装、基本用法与常用选项
dtc(Device Tree Compiler)是设备树开发中最核心的工具,负责将设备树源文件(.dts)编译为二进制设备树(.dtb),也支持反向反编译操作。掌握 dtc 的安装与常用选项,是进行设备树调试的第一步。
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.gitcd 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
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 以上版本。