4、设备树编译器:dtc 工具的使用与反编译技巧
设备树写好了,怎么变成内核能用的二进制文件?
答案就是 dtc——设备树编译器。
说实话,我刚接触设备树那会儿,以为这玩意儿多神秘。后来发现,它就是个翻译官,把 .dts 文本翻译成 .dtb 二进制。反过来也能干,把 .dtb 还原成 .dts。今天我就带你把它玩透。
4.1 dtc 是什么?
dtc 全称 Device Tree Compiler。它属于设备树工具链的核心。
它的工作很简单:
- 编译:.dts → .dtb(文本转二进制)
- 反编译:.dtb → .dts(二进制转文本)
- 转储:.dtb → .dts 带偏移信息
我在项目中遇到过一位同事,死活找不到设备树里的某个节点。我让他反编译一下 .dtb,他愣了半天:「还能反编译?」嗯,从那以后他再也不敢只发 .dtb 给别人了。
4.2 基本编译命令
先看最简单的用法:
dtc -I dts -O dtb -o output.dtb input.dts
参数说明:
-I dts:输入格式是 .dts-O dtb:输出格式是 .dtb-o output.dtb:指定输出文件名
我习惯把常用参数记成「I-O-O」:输入、输出、输出文件。好记。
如果你只想检查语法,不生成文件:
dtc -I dts -O dtb input.dts > /dev/null
没报错就说明语法没问题。我经常用这招快速验证。
4.3 反编译:把 .dtb 变回 .dts
反编译才是真正的宝藏技能。
你想想看,有时候拿到一块开发板,厂商只给了 .dtb。你想看看里面到底配了哪些外设?反编译一下全出来了。
dtc -I dtb -O dts -o output.dts input.dtb
就这么简单。
但有个坑——反编译出来的 .dts 会丢失注释。为什么?因为 .dtb 是二进制格式,注释在编译时就被扔掉了。所以,永远不要只靠反编译来维护设备树。源文件 .dts 才是真理。
#include 的头文件信息。从那以后,我再也不拿反编译结果当源文件用了。
4.4 常用选项详解
dtc 的选项不少,但常用的就这几个:
| 选项 | 说明 | 我常用的场景 |
|---|---|---|
-I |
指定输入格式 | dts、dtb、fs(文件系统) |
-O |
指定输出格式 | dts、dtb、asm(汇编) |
-o |
输出文件名 | 必填,除非你只想检查语法 |
-@ |
生成插件节点 | 做设备树叠加层时用 |
-H |
指定 phandle 格式 | 兼容旧内核时用 |
-V |
指定 .dtb 版本 | 默认用最新版,老内核需要降级 |
举个例子,生成带插件支持的 .dtb:
dtc -I dts -O dtb -@ -o output.dtb input.dts
这个 -@ 选项,我在做设备树叠加层(overlay)时几乎必用。不加的话,编译出来的 .dtb 没法动态加载。
4.5 反编译的高级技巧
反编译不只是 -I dtb -O dts 这么简单。有几个实用技巧:
- 保留偏移信息:加
-f选项,会输出每个节点的偏移地址。调试时很有用。 - 反编译成汇编:
-O asm可以生成汇编代码。我很少用,但做底层分析时能派上用场。 - 只反编译部分节点:用
-s选项可以指定起始节点。不过说实话,我更喜欢全量反编译然后用 grep 过滤。
# 带偏移信息的反编译
dtc -I dtb -O dts -f -o debug.dts input.dtb
# 反编译成汇编
dtc -I dtb -O asm -o output.S input.dtb
4.6 常见错误与避坑
用 dtc 时,我遇到过不少报错。挑几个典型的说说:
说白了就是语法有错。检查括号是否匹配、分号是否漏了、引号是否成对。
节点有 phandle 但没有 reg 属性。这通常是个警告,但最好补上 reg。
引用了不存在的节点或标签。检查 &xxx 是否拼写正确。
我个人习惯在编译时加 -Wno-error 选项,把警告降级。但注意,这只是临时方案,最终还是要消除所有警告。
4.7 实战:从 .dtb 反编译到调试
给你一个完整的实战流程:
- 拿到厂商的 .dtb 文件
- 反编译成 .dts:
dtc -I dtb -O dts -o board.dts board.dtb - 用文本编辑器打开 board.dts,查看节点配置
- 发现问题后,修改 board.dts
- 重新编译:
dtc -I dts -O dtb -o board_new.dtb board.dts - 用新的 .dtb 替换旧的,重启测试
嗯,这里要注意:第4步修改时,一定要保留原有的结构。我曾经手滑删了一个 status = "okay",结果某个外设死活不工作。查了半天才发现是这个问题。
4.8 知识体系图
下面这张图总结了 dtc 的核心用法:
alias dtc-dts='dtc -I dts -O dtb' 和 alias dtc-dtb='dtc -I dtb -O dts'。省得每次敲那么长一串。
好了,dtc 的基本用法就这些。说白了就是两个方向:编译和反编译。记住源文件 .dts 才是根本,.dtb 只是产物。下次拿到 .dtb 别慌,反编译一下,什么都清楚了。
公众号:蓝海资料掘金营,微信deep3321