3. DTC 工具入门:安装、基本用法与常用命令行选项

设备树编译器(Device Tree Compiler,DTC)是处理 .dts / .dtsi 源文件与 .dtb / .dtbo 二进制文件的官方工具。掌握 DTC 是调试设备树的第一步,本章将系统讲解其安装、基本用法及核心命令行选项。

核心概念: DTC 不仅用于编译,更常用于反编译(将 .dtb 还原为 .dts)和校验,是设备树调试的“瑞士军刀”。

3.1 DTC 的安装

DTC 通常作为独立工具或内核源码的一部分提供。以下是三种主流安装方式:

安装方式 适用场景 命令
包管理器安装 快速使用,版本稳定 sudo apt-get install device-tree-compiler (Debian/Ubuntu)
sudo yum install dtc (RHEL/CentOS)
内核源码编译 需要最新特性或交叉编译 make scripts/dtc (在内核源码根目录执行)
源码手动编译 定制化需求或离线环境 git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git
cd dtc && make
版本注意: 建议使用 DTC 1.5.0 及以上版本,以支持 -@ 选项(生成 overlays 符号)和更完善的校验功能。使用 dtc --version 检查当前版本。

3.2 基本用法:编译与反编译

DTC 的核心操作是编译(.dts → .dtb)和反编译(.dtb → .dts)。

3.2.1 编译设备树

# 基本编译:将 .dts 编译为 .dtb
dtc -I dts -O dtb -o my_board.dtb my_board.dts

# 编译时包含所有 .dtsi 头文件(自动处理)
dtc -I dts -O dtb -o output.dtb -@ input.dts

3.2.2 反编译设备树

# 反编译:将 .dtb 还原为可读的 .dts
dtc -I dtb -O dts -o decompiled.dts boot.dtb

# 反编译并保留所有标签(label)
dtc -I dtb -O dts -o full.dts -H epapr boot.dtb
调试技巧: 反编译是调试内核加载的 .dtb 的常用手段。例如,从 /sys/firmware/fdt 或 /proc/device-tree 获取运行时设备树后,用 DTC 反编译查看实际生效的配置。
DTC 编译与反编译流程 .dts / .dtsi 源文件 DTC 编译器 .dtb 二进制文件 .dtb 二进制文件 DTC 反编译器 .dts 可读源文件 编译:-I dts -O dtb | 反编译:-I dtb -O dts

3.3 常用命令行选项详解

DTC 提供了丰富的选项来控制输入/输出格式、符号生成、校验级别等。以下是最常用的选项:

选项 全称 功能说明 示例
-I Input format 指定输入文件格式:dts(源文件)、dtb(二进制)、fs(文件系统目录) -I dts
-O Output format 指定输出文件格式:dts、dtb、yaml、dtbo(overlay 二进制) -O dtb
-o Output file 指定输出文件名 -o output.dtb
-@ Symbols for overlays 在 .dtb 中生成 __symbols__ 节点,支持设备树覆盖(overlay) -@
-H Header format 指定反编译时的头部格式:epapr(PowerPC)、be(大端)等 -H epapr
-V Version 指定 .dtb 格式版本(如 16、17) -V 17
-W Warning 启用特定警告检查(如 -W no-unit_address_vs_reg 关闭地址检查) -W no-unit_address_vs_reg
-E Error 将特定警告升级为错误(如 -E graph_child_address) -E graph_child_address
-v Verbose 输出详细编译信息,用于调试编译过程 -v

3.4 核心选项深度解析

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

这两个选项是 DTC 最基础的参数,决定了数据流的转换方向。除了 dts 和 dtb,-I fs 允许从 /proc/device-tree 等文件系统目录直接读取设备树结构,非常适用于运行时调试。

# 从 /proc/device-tree 目录反编译设备树
dtc -I fs -O dts -o runtime.dts /proc/device-tree

3.4.2 -@:设备树覆盖支持

-@ 选项在编译时生成 __symbols__ 节点,记录所有带标签(label)的节点路径。这是设备树覆盖(Device Tree Overlay)的基础,允许在运行时动态添加或修改设备节点。

# 编译支持 overlay 的 .dtb
dtc -I dts -O dtb -@ -o base.dtb base.dts

# 编译 overlay 片段
dtc -I dts -O dtbo -o overlay.dtbo overlay.dts
实战场景: 在 FPGA 动态重配置或外设热插拔场景中,-@ 生成的符号表是 overlay 能够正确“挂载”到基树上的关键。没有 -@,overlay 将无法定位目标节点。

3.4.3 -W 与 -E:编译质量检查

DTC 内置了丰富的检查器,用于发现设备树中的常见错误。使用 -W 启用检查,-E 将检查结果升级为错误(编译失败)。

# 启用所有警告,并将地址格式错误视为编译错误
dtc -I dts -O dtb -o output.dtb -W all -E unit_address_vs_reg input.dts

常用检查项列表:

检查项 说明
unit_address_vs_reg 检查节点地址与 reg 属性是否匹配
graph_child_address 检查图形绑定中子节点地址格式
avoid_unnecessary_addr_size 检查不必要的 #address-cells / #size-cells
unique_unit_address 检查同一层级下节点地址是否唯一
DTC 命令行选项工作流程 输入文件 -I 指定格式 -@ 生成符号 -W / -E 检查 -v 详细输出 DTC 核心 解析 + 校验 + 生成 输出文件 选项组合示例:dtc -I dts -O dtb -@ -W all -o output.dtb input.dts -@ 用于 overlay 支持,-W all 启用全部检查,-v 可查看详细编译过程

3.5 实战示例:完整编译与校验流程

以下是一个完整的 DTC 使用流程,涵盖编译、反编译和校验:

  1. 编译设备树(带 overlay 支持):
    dtc -I dts -O dtb -@ -o board.dtb board.dts -W all -E unit_address_vs_reg
  2. 反编译验证:
    dtc -I dtb -O dts -o board_decompiled.dts board.dtb
  3. 对比差异:
    diff board.dts board_decompiled.dts

    正常情况下,反编译结果应与源文件一致(仅格式和注释可能不同)。

  4. 检查符号表:
    dtc -I dtb -O dts board.dtb | grep -A 20 "__symbols__"

    确认 -@ 选项正确生成了所有标签的符号映射。

效率提升: 将常用 DTC 命令封装为 Makefile 目标或 shell 脚本,例如:
dtc_compile: dtc -I dts -O dtb -@ -o $(BOARD).dtb $(BOARD).dts -W all

3.6 常见错误与排查

错误信息 原因 解决方案
FATAL ERROR: Unable to parse input tree .dts 文件语法错误 检查分号、花括号、属性值格式
Warning (unit_address_vs_reg): ... 节点地址与 reg 属性不匹配 确保节点名中的地址与 reg 的第一个地址一致
Error: no such file or directory 缺少 .dtsi 头文件 使用 -i 选项指定包含路径,或确保文件在搜索路径中
__symbols__ not found 编译时未使用 -@ 选项 重新编译时添加 -@

通过本章的学习,你已经掌握了 DTC 的安装、基本编译/反编译操作以及核心命令行选项。这些技能是后续使用内核日志和 of_dump 工具进行设备树调试的基础。