基于iMX8MP的定制板:何时选用设备树覆盖而非多DTB?
问题背景与困惑
我有一块基于iMX8MP处理器的定制板,该板具备3种不同的硬件配置,核心差异在于ADC和**移位寄存器(shift registers)**的数量。我希望能在启动阶段根据真值表选择正确的DTB,已编写U-Boot脚本从/boot/目录选取对应DTB。
目前我通过dtc命令生成所有DTBs,再从这些DTBs反向生成DTS以去除所有dtsi,得到每种配置对应的紧凑DTS文件。我的Yocto配方如下:
SUMMARY = "U-boot script: auto select dtb for devboard" LICENSE = "CLOSED" LIC_FILES_CHKSUM = "" COMPATIBLE_MACHINE = "devboard" DEPENDS = "u-boot-mkimage-native dtc-native" SRC_URI = "file://autoselect-dtb.txt \ file://devboard-cirrus8.dts \ file://devboard-cirrus16.dts \ file://devboard-cirrus32.dts" do_compile() { mkimage -A arm64 -O linux -T script -C none -d "${WORKDIR}/autoselect-dtb.txt" boot.scr dtc -I dts -O dtb -o devboard-cirrus8.dtb ${WORKDIR}/devboard-cirrus8.dts dtc -I dts -O dtb -o devboard-cirrus16.dtb ${WORKDIR}/devboard-cirrus16.dts dtc -I dts -O dtb -o devboard-cirrus32.dtb ${WORKDIR}/devboard-cirrus32.dts } do_install() { install -d ${D}/boot/ install -m 0644 boot.scr ${D}/boot/ install -m 0644 devboard-cirrus8.dtb ${D}/boot/ install -m 0644 devboard-cirrus16.dtb ${D}/boot/ install -m 0644 devboard-cirrus32.dtb ${D}/boot/ } FILES:${PN} = "/boot/*"
我知晓当前方案并非最佳实践,现困惑的是:我应当创建适配各配置的多个dtsi,编译多个DTB并安装到/boot/,还是应采用设备树overlay方案?
方案分析与建议
1. 多DTSI+多DTB方案
优势
- 逻辑清晰易维护:把通用硬件部分放在主DTS,不同配置的差异(ADC、移位寄存器数量)拆成独立的dtsi文件,主DTS根据配置选择
#include对应的dtsi。后续修改某一配置的硬件描述时,只需要改动对应的dtsi,不会影响其他配置。 - 启动阶段兼容性好:U-Boot直接加载完整DTB,不需要处理overlay的应用逻辑,对U-Boot版本要求更低,能直接沿用你已实现的DTB自动选择脚本。
- 编译流程标准化:Yocto中可通过
KERNEL_DEVICETREE变量指定多个DTB目标,直接利用内核编译规则生成DTB,无需在配方里手动调用dtc,避免重复造轮子。
劣势
- 镜像体积略有增加:
/boot/下会存放多个DTB文件,但单个DTB体积通常仅几十KB,对存储的影响可忽略。
2. 设备树Overlay方案
优势
- 镜像更精简:只需要一个基础DTB,加上几个体积更小的overlay文件,节省少量
/boot/空间。 - 调试灵活性高:临时调整硬件配置(比如调试时修改ADC数量)时,可直接替换overlay文件,无需重新编译整个DTB。
劣势
- U-Boot逻辑更复杂:需要在U-Boot脚本中先加载基础DTB,再根据硬件配置应用对应的overlay,增加了启动阶段的出错概率,且需确保U-Boot支持overlay功能(部分旧版本U-Boot对overlay的支持不完善)。
- 维护成本更高:Overlay需要严格匹配基础DTB的节点结构,后续修改基础DTB时,可能需要同步更新所有相关overlay文件,容易出现节点不匹配问题。
最终建议
结合你已实现U-Boot自动选择DTB脚本的现状,优先选择多DTSI+多DTB方案:
- 重构DTS结构:编写主DTS(如
devboard-main.dts)包含所有通用硬件节点,为3种配置分别编写devboard-cirrus8.dtsi、devboard-cirrus16.dtsi、devboard-cirrus32.dtsi,仅保留ADC和移位寄存器的差异节点。 - 为每种配置创建独立顶层DTS,比如
devboard-cirrus8.dts只需包含主DTS和对应dtsi:
#include "devboard-main.dts" #include "devboard-cirrus8.dtsi"
- 修改Yocto配方,去掉手动调用
dtc的逻辑,通过KERNEL_DEVICETREE指定要编译的DTB,或让配方依赖内核包获取编译好的DTB,更符合Yocto标准流程。
这种方案既能解决你当前手动反向生成DTS的维护痛点,又能沿用现有U-Boot自动选择逻辑,后续硬件配置变更也更易管理。
内容的提问来源于stack exchange,提问作者void_brain
相关产品推荐
相关产品推荐

