修改设备树(Device Tree)是驱动开发中的必修课。你提到的修改源码法 (Full DTS Modification)和插件法(Device Tree Overlay / DTO)在本质上都是为了描述硬件,但在操作逻辑、应用场景和便利性上有显著区别。
我们可以用**"盖房子"**来做一个形象的比喻。
1. 修改设备树源码法(修改全量 DTS)
类比 :直接修改房子的建筑设计蓝图。
- 操作过程 :
- 找到内核源码中对应的
.dts或.dtsi文件。 - 在对应的 I2C 节点下直接添加 MPU6050 的子节点。
- 重新编译整个设备树(执行
make dtbs)。 - 得到一个新的
.dtb文件,将其拷贝到开发板的/boot目录下,替换掉原来的文件,然后重启。
- 找到内核源码中对应的
- 优点 :
- 结构清晰:所有的硬件描述都在一个文件或一组关联文件中,逻辑统一。
- 性能略高:内核在启动时一次性解析所有硬件,不涉及后续的合并操作。
- 缺点 :
- 笨重:哪怕只改一行代码,也要重新编译整个设备树。
- 风险高:如果不小心删掉了原有的关键配置,系统可能无法启动(比如串口没屏了,文件系统挂载不上了)。
- 不灵活 :如果你有 10 个不同的传感器要测试,你可能需要维护 10 个全量
.dtb文件。
2. 插件法(Device Tree Overlay / DTBO)
类比 :在已经盖好的房子上贴一张**"装修补丁"或外挂一个"集装箱房间"**。
- 操作过程 :
- 编写一个专门的
.dtso文件(Overlay 源码),只包含你要添加或修改的部分(比如 MPU6050 节点)。 - 使用
dtc工具将其编译成二进制的插件文件.dtbo。 - 在开发板运行时或启动引导阶段(通过
u-boot或系统配置文件),加载这个.dtbo。
- 编写一个专门的
- 优点 :
- 模块化:硬件改动是独立的。你要测 MPU6050 就加载它的插件,测别的就换另一个。
- 安全 :不破坏原始的系统蓝图(主
.dtb)。如果插件写错了,顶多这个外设不通,系统主功能通常还是稳的。 - 热插拔感:在某些系统中,甚至可以在不重启的情况下动态加载和卸载插件。
- 缺点 :
- 语法稍复杂 :由于是"外挂",需要使用
fragment和__overlay__这种特定语法,初学者容易写错路径(target)。 - 依赖主树:插件必须明确知道主设备树里某个节点的"标签"(Label)或"路径",如果主树变了,插件可能失效。
- 语法稍复杂 :由于是"外挂",需要使用
3. 核心区别对比表
| 特性 | 修改源码法 (Full DTS) | 插件法 (Overlay/DTBO) |
|---|---|---|
| 产出文件 | 一个庞大的 .dtb |
一个轻量的 .dtbo |
| 操作方式 | 替换主设备树 | 在主设备树基础上累加 |
| 重新编译 | 需要重新编译整棵树 | 只编译插件片段 |
| 影响范围 | 全局,可能影响系统启动 | 局部,只影响特定外设 |
| 系统升级 | 升级内核可能覆盖你的修改 | 插件通常可以跨内核版本保留 |
| 推荐场景 | 核心板设计、永久性硬件变更 | 外接传感器调试、扩展板/帽子开发 |
4. 在 Orange Pi 5 上的实际应用建议
在 Orange Pi 5(以及大多数 Armbian 架构系统)中:
- 官方推荐插件法 :你会发现系统中有一个
orangepi-config或armbian-config工具,里面有一个 Overlays 菜单。你可以通过勾选直接开启官方预设的插件(比如开启 I2C3)。 - 调试驱动的首选 :对于像 MPU6050 这种外接传感器,强烈建议使用插件法 。你只需要写一个几十行的
.dtso,编译成.dtbo扔进/boot/overlay-user(或类似目录),在配置文件里加一行名字,重启即可。
如果你现在要给 MPU6050 写设备树配置:
- 如果你打算直接改源码 ,你需要找到内核路径下对应的
rk3588s-orangepi-5.dts。 - 如果你打算用插件法 ,你需要写一个
mpu6050-overlay.dtso,利用&i2c3 { ... };这种语法去"寄生"在 I2C3 节点上。
你想看看这两种方法具体在代码写法上有什么不同吗?(比如如何定位到 &i2c3)