Device Tree Overlay(DT Overlay)是 Linux 内核提供的一种运行时动态修改设备树的机制。它允许在不重新编译整个 DTB 的情况下,增量式地添加、修改或覆盖设备树节点和属性,极大地提升了硬件描述的灵活性。
一、基本概念
1.1 Device Tree 回顾
Device Tree(设备树)是一种描述硬件拓扑的数据结构,内核启动时解析 DTB(Device Tree Blob)来识别和配置硬件。
术语 | 说明 |
DTS | Device Tree Source,文本格式的设备树源文件 |
DTC | Device Tree Compiler,将 DTS 编译为 DTB |
DTB | Device Tree Blob,二进制格式,内核直接加载 |
DTBO | Device Tree Blob Overlay,Overlay 的二进制格式 |
FDT | Flattened Device Tree,DTB 在内存中的表示 |
1.2 为什么需要 Overlay
传统方式下,修改硬件配置需要重新编译整个 DTB 并重启。Overlay 解决了以下痛点:
- 动态外设管理 — 运行时加载/卸载扩展板(如 BeagleBone Cape、Raspberry Pi HAT)的硬件描述
- 减少 DTB 碎片化 — 基础 DTB 保持简洁,功能差异通过 Overlay 叠加
- 开发调试效率 — 修改单个外设绑定无需重编译完整设备树
- 产品线复用 — 同一基础 DTB + 不同 Overlay 组合覆盖多个 SKU
1.3 Overlay 与 Base DT 的关系
Overlay 通过
fragment 和 target 指定要修改的 Base DT 节点,然后将 __overlay__ 中的内容合并到目标节点。二、机制流程
2.1 Overlay DTS 结构
Overlay 源文件使用
/plugin/; 声明,核心由 fragment 构成:关键字段:
target— 通过 phandle(<&label>)定位 Base DT 中的目标节点
target-path— 通过绝对路径定位目标节点(二选一)
__overlay__— 要合并到目标节点的内容
2.2 编译流程
-@参数是关键:它让 DTC 生成__symbols__和__fixups__节点,使得 Overlay 能在加载时解析 phandle 引用。
2.3 内核加载机制
内核侧 Overlay 的核心 API 位于
drivers/of/overlay.c:API | 功能 | of_overlay_fdt_apply() | 将 DTBO 应用到 Live DT,返回 overlay_id |
of_overlay_remove() | 通过 overlay_id 移除已应用的 Overlay | __symbols__ | Base DTB 中的符号表,提供 label → path 映射 |
__fixups__ | DTBO 中待修正的 phandle 引用列表 | __local_fixups__ | DTBO 内部 phandle 的偏移修正表 |
加载时序:
- 用户空间将 DTBO 写入 ConfigFS 或通过内核模块调用 API
- 内核解析 DTBO,根据
__fixups__修正 phandle
- 将
__overlay__内容合并到 Live DT 对应节点
- 触发
OF_RECONFIG_*通知链,驱动 probe 自动执行
- 返回
overlay_id供后续移除使用
2.4 Overlay 移除
Overlay 遵循 LIFO(后进先出) 栈模型:
- 只能按加载的逆序移除
- 移除时触发对应驱动的
remove回调
- 恢复被覆盖的原始属性值
三、操作指南
3.1 编译 DTBO
Base DTB 必须带
-@ 编译,否则不会生成 __symbols__ 节点,Overlay 中的 phandle 引用将无法解析。3.2 通过 ConfigFS 加载(推荐)
3.3 通过 U-Boot 加载(启动阶段)
3.4 QEMU 环境验证
针对 QEMU sabrelite(i.MX6)开发环境的验证步骤:
3.5 调试与排错
现象 | 排查方向 |
status 显示 unapplied | 检查 dmesg 中 of_overlay 相关错误;确认 Base DTB 有 __symbols__ |
phandle 解析失败 | 确认 DTBO 用 -@ 编译;检查 target label 在 Base DT 中存在 |
驱动未 probe | 检查 compatible 字符串匹配;确认总线控制器 status = "okay" |
移除失败 | 确认按 LIFO 顺序移除;检查是否有用户空间进程持有设备文件 |
属性值未生效 | Overlay 只能追加或覆盖,不能删除已有属性 |
四、最佳实践
- Base DTB 保持最小化 — 只包含 SoC 核心和共用外设,差异化通过 Overlay 叠加
- 使用 label 而非路径 —
target = <&i2c1>比target-path更健壮,不受节点路径重构影响
- 每个外设独立一个 DTBO — 便于组合和独立调试
- 版本化管理 Overlay — 将 DTS 源文件纳入 Git,与驱动代码同仓管理
- CI 中加入 DT 校验 — 使用
dt-validate和dtc -W检查绑定合规性
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/linux_device_tree_overlay
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!







