0. 这一节要解决什么
前面把两条构建链拆开讲清楚了,这一节把它们合起来走一遍:修改一个可见、可验证、低风险的设备树属性,完成「改 → 编译 → 定位 → 部署 → 验证」的完整闭环,并掌握「改了没生效」的六站排查法。
1. 闭环总览
修改 ──> 编译 ──> 定位 ──> 部署 ──> 启动 ──> 验证
(改哪层) (extboot)(产物路径)(boot 分区)(U-Boot 加载)(/proc/device-tree)
2. 实验目标:改 model 字符串
选 model 作为第一个目标,因为它最安全且天然可验证——/proc/device-tree/model 直接读出。目标:把板子上的 model 改成带个人标记的字符串,然后让它真的生效。
3. 第一步:修改
cd kernel/arch/arm64/boot/dts/rockchip/
cp rk3576-firefly-roc-rk3576-pc.dts rk3576-firefly-roc-rk3576-pc.dts.bak # 先备份
vim rk3576-firefly-roc-rk3576-pc.dts
把
model = "Firefly ROC-RK3576-PC Linux HDMI";
改为
model = "UESTC-ZS <你的学号或姓名缩写> ROC-RK3576-PC";
回滚手段:保留的 .bak、或 git checkout -- <文件>(SDK 是 git 仓库)。
4. 第二步与第三步:编译并定位产物
cd <SDK>
./build.sh lunch # 确认选中的是 firefly_rk3576_roc-rk3576-pc_ubuntu_defconfig
./build.sh extboot
编译完成后核对三处证据:
ls -l kernel/extboot.img # ① 镜像时间戳应为刚刚
ls -l kernel/extboot/ # ② 目录内的 Image 与 dtb
dtc -I dtb -O dts kernel/extboot/rk3576-firefly-roc-rk3576-pc.dtb | grep model
# ③ DTB 里 model 已是新字符串
第 ③ 条是关键:在产物层面确认改动已进入 DTB,再谈部署。
5. 第四步:部署
两种方式任选:
方式 A · 拷文件(推荐,快)——板子能进系统、网络或 U 盘可用时:
# PC → 板子(scp 示例,IP 以板子实际为准)
scp kernel/extboot/* firefly@<板子IP>:/tmp/extboot/
# 板子上
sudo cp /tmp/extboot/Image /tmp/extboot/*.dtb /boot/
sudo cp -r /tmp/extboot/extlinux /boot/
sudo reboot
方式 B · 烧写镜像(板子进不了系统时用)——板子进 Loader 模式(RECOVERY 键 + 复位),PC 上:
sudo upgrade_tool di -boot kernel/extboot.img
两种方式等价:boot 分区的三个组成物被更新即可。
6. 第五步与第六步:启动并验证
重启板子,进系统后:
cat /proc/device-tree/model
# 预期输出:UESTC-ZS <你的学号或姓名缩写> ROC-RK3576-PC
tr -d '\0' < /proc/device-tree/compatible
# 预期输出:rockchip,rk3576-firefly-roc-rk3576-pcrockchip,rk3576
model 变了 → 六站闭环走通:从这一刻起,本板的内核设备树是自己编的版本,后续所有设备树实验都在它之上进行。
7. 六站排查:改了没生效怎么办
| 站 | 问题 | 证据 |
|---|---|---|
| 1 源文件 | 改的是被目标 DTS include 的文件吗 | 目标 dts 的 include 列表 |
| 2 语法规则 | dtc 报错了吗(分号、括号、cells) | 编译日志末尾 DTC 输出 |
| 3 配置目标 | 编译选的是当前板卡的 DTS 吗 | defconfig 的 RK_KERNEL_DTS_NAME |
| 4 编译产物 | 目标 .dtb 时间戳更新了吗 |
ls -l kernel/extboot/ |
| 5 启动选择 | U-Boot 实际加载的是这个 DTB 吗 | extlinux.conf 的 fdt 行 |
| 6 运行结果 | model / compatible 变了吗 | /proc/device-tree |
第 5 站最容易漏:编译产物是新的,U-Boot 却仍加载旧文件(部署位置不对、extlinux 指向别处)。
8. 进阶:改 status 开关一个设备
model 只动了字符串。第二步实验动「设备是否存在」:
- 在 dts(或其 dtsi)中选一个本实验不需要的设备节点,如某个摄像头接口
status = "okay"↔"disabled"各编译部署一次- 对比
/sys/bus/下对应设备实例与dmesg的出现 / 消失
status 影响的是设备树条件——实例被创建与否。这是后续「某外设为什么不工作」类问题的第一查。
9. 本节小结
- 闭环六站:修改 → 编译 → 定位 → 部署 → 启动 → 验证,每站留证据
- 产物层面先验证(dtc 反编译 grep),再烧板——排错成本最低的顺序
- 部署两方式:拷
kernel/extboot/三件套,或upgrade_tool di -boot - 「没生效」沿六站查,第 5 站(启动选择)最容易漏
10. 本节思考
Q1:为什么把「在产物层面验证」放在部署之前?颠倒顺序的代价是什么?
查看答案
产物验证只需一条 dtc ... | grep 命令,秒级完成;若跳过它直接部署,编译侧的问题(改错文件、DTS 配置目标不对)要到重启后才发现,表现为「板子没变化」,此时需要在六站里回溯,还要重新走一遍部署。验证越靠前,单次定位成本越低——与第 1 课时「先确认输入再执行」的原则同源。
Q2:改动进入了 DTB,/proc/device-tree/model 却没变。最可能是哪一站出了问题?给出两条检查命令。
查看答案
第 5 站(启动选择)或部署不到位。检查:① U-Boot 侧读 extlinux.conf 确认 fdt 行指向的文件;② ls -l /boot/ 对比板上 dtb 的时间戳与编译产物是否一致。此外确认部署后确实重启过——/proc/device-tree 是启动时内存中的映射,不重启不会变。
Q3:直接改公共 dtsi 完成本实验可行吗?为什么实验仍建议改 dts 入口?
查看答案
可行,model 在根节点、改 dtsi 的根节点同样生效。但公共 dtsi 可能被多块板共用,改动的评估面更大;dts 入口文件改动只影响本板,风险最小。原则:优先改影响面最小的层——这也是工程上「板级配置收拢在板级文件」的用意。备份与 git 回滚同样不能省。