搞懂MTK设备树镜像:DTB与DTBO到底由哪些DTS文件生成?(附mkdtimg工具使用指南)
MTK设备树镜像构建全解析从DTS到DTB/DTBO的完整链路在Android内核开发领域设备树(Device Tree)作为硬件描述的核心机制其构建流程一直是系统工程师必须掌握的技能。特别是对于MTK平台设备树镜像的生成涉及多个配置文件和工具链理解这个过程中的细节对于定制内核、调试硬件兼容性问题至关重要。1. MTK平台设备树架构基础MTK芯片组的设备树管理采用了一套独特的双轨制架构。与高通等平台不同MTK保留了传统的DWS(Digital Wiring System)配置工具同时兼容标准的设备树工作流。这种设计既照顾了老用户的习惯又满足了新内核版本的要求。核心文件类型解析DWS文件图形化硬件配置界面生成的文件位于drivers/misc/mediatek/dws/目录下DTS/DTSI文件标准设备树源文件及其包含文件DTB文件编译后的设备树二进制文件DTBO文件设备树叠加层(Overlay)二进制文件MTK典型的设备树文件结构如下arch/arm64/boot/dts/mediatek/ ├── mt6752.dts # 基础设备树 ├── mt6752_64.dts # 叠加层设备树 ├── mt6752_64.dtsi # 公共包含文件 └── cust_dtsi/ # DWS生成的定制配置注意MT6752和mt6752_64的区别不仅仅是字面差异前者用于生成基础DTB后者专用于DTBO2. DWS到DTSI的转换机制MTK平台通过drvgen工具链实现DWS到DTSI的自动转换这个流程隐藏在常规编译过程中很多开发者甚至意识不到它的存在。转换过程关键点输入文件定位主DWS文件drivers/misc/mediatek/dws/mt6752/mt6752_64.dws备选DWS文件vendor/mediatek/proprietary/custom/mt6752_64/kernel/dct/dct/codegen.dws通常不使用转换工具调用 核心转换逻辑由kernel-4.14/scripts/drvgen/drvgen.mk中的Makefile规则实现.PHONY: drvgen drvgen: $(DRVGEN_FILE_LIST) $(DRVGEN_FILE_LIST): $(DRVGEN_TOOL) $(DWS_FILE) $(DRVGEN_FIG) $(PROJ_DTS_FILES) for i in $(PROJ_DTS_FILES); do \ base_prjgrep -m 1 #include [lt;\]... $$i | sed s/#include...; \ prj_path$(DRVGEN_OUT)/$$base_prj ;\ dws_path$(srctree)/$(DRVGEN_PATH)/$$base_prj.dws ;\ if [ -f $$dws_path ] ; then \ mkdir -p $$prj_path ;\ $(python) $(DRVGEN_TOOL) $$dws_path $$prj_path $$prj_path cust_dtsi;\ fi \ done输出文件位置 生成的DTSI文件最终存放在obj/KERNEL_OBJ/arch/arm64/boot/dts/mt6752_64/cust_dtsi目录下转换过程常见问题排查如果GPIO配置未生效首先检查DWS文件中对应引脚的配置状态确保DWS文件版本与内核版本匹配避免兼容性问题转换失败时查看drvgen工具的日志输出通常会有具体错误提示3. DTBO镜像生成全流程设备树叠加层(DTBO)是Android动态硬件支持的关键MTK平台通过一套自动化流程生成最终的dtbo.img。3.1 配置文件生成DTBO构建的第一步是生成dtboimg.cfg配置文件这个过程由内核构建系统自动完成define mk_dtboimg_cfg echo $(1) $(2);\ echo id$(my_dtbo_id) $(2);\ $(eval my_dtbo_id:$(shell echo $$(($(my_dtbo_id)1)))) endef dtbs: $(objtree)/dtboimg.cfg $(objtree)/dtboimg.cfg: FORCE rm -f $.tmp $(foreach f,$(ABS_DTB_FILES),$(call mk_dtboimg_cfg,$(f),$.tmp)) if ! cmp -s $.tmp $; then \ mv $.tmp $; \ else \ rm $.tmp; \ fi生成的配置文件位于obj/KERNEL_OBJ/dtboimg.cfg内容示例arch/arm64/boot/dts/mediatek/mt6752_64.dtb id03.2 镜像打包配置文件生成后使用mkdtimg工具进行最终打包$(BOARD_PREBUILT_DTBOIMAGE): PRIVATE_TOOL : $(HOST_OUT_EXECUTABLES)/mkdtimg $(BOARD_PREBUILT_DTBOIMAGE): PRIVATE_CFG : $(KERNEL_OUT)/dtboimg.cfg $(BOARD_PREBUILT_DTBOIMAGE): $(HOST_OUT_EXECUTABLES)/mkdtimg $(BOARD_PREBUILT_DTBOIMAGE): $(KERNEL_OUT)/dtboimg.cfg $(hide) mkdir -p $(dir $) $(PRIVATE_TOOL) cfg_create $ $(PRIVATE_CFG)关键参数说明参数说明cfg_create根据配置文件创建镜像$输出文件路径(BOARD_PREBUILT_DTBOIMAGE)$(PRIVATE_CFG)输入的dtboimg.cfg路径3.3 版本兼容处理MTK平台针对不同Android版本做了差异化处理ifeq ($(strip $(MTK_DTBO_UPGRADE_FROM_ANDROID_O)), yes) droidcore: $(PRODUCT_OUT)/$(notdir $(BOARD_PREBUILT_DTBOIMAGE)) odmdtboimage: $(PRODUCT_OUT)/$(notdir $(BOARD_PREBUILT_DTBOIMAGE)) else droidcore: $(PRODUCT_OUT)/dtbo.img dtboimage: $(PRODUCT_OUT)/dtbo.img endif4. DTB镜像生成机制基础DTB镜像的生成流程与DTBO类似但又有重要区别这是MTK平台设备树管理的关键所在。4.1 配置项解析内核配置中两个关键参数决定了DTB的生成CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMESmediatek/mt6752 CONFIG_BUILD_ARM64_DTB_OVERLAY_IMAGE_NAMESmediatek/mt6752_64这些配置在drvgen.mk中被解析使用ifeq ($(strip $(CONFIG_ARM64)), y) MAIN_DT_NAMES : $(subst $\,,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES)) else MAIN_DT_NAMES : $(subst $\,,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES)) endif ifeq ($(strip $(CONFIG_ARM64)), y) PROJ_DT_NAMES : $(subst $\,,$(CONFIG_BUILD_ARM64_DTB_OVERLAY_IMAGE_NAMES)) else PROJ_DT_NAMES : $(subst $\,,$(CONFIG_BUILD_ARM_DTB_OVERLAY_IMAGE_NAMES)) endif4.2 mtk.dtb的生成之谜很多开发者困惑于最终生成的mtk.dtb与原始DTS文件的关系其实这是MTK构建系统的特殊设计ABS_DTB_FILES : $(abspath $(addsuffix .dtb,$(addprefix $(objtree)/arch/$(SRCARCH)/boot/dts/,$(PROJ_DT_NAMES)))) ABS_DTB2_FILES : $(abspath $(addprefix $(objtree)/arch/$(SRCARCH)/boot/,mtk.dtb)) $(objtree)/dtbimg.cfg: FORCE rm -f $.tmp $(foreach f,$(ABS_DTB2_FILES),$(call mk_dtbimg_cfg,$(f),$.tmp)) if ! cmp -s $.tmp $; then \ mv $.tmp $; \ else \ rm $.tmp; \ fi实际mtk.dtb是通过合并多个DTB文件生成的DTB_NAMES : $(subst $\,,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES)) ifneq ($(DTB_NAMES),) DTB_LIST : $(addsuffix .dtb,$(DTB_NAMES)) else DTB_LIST : $(dtb-y) endif DTB_OBJS : $(addprefix $(obj)/dts/,$(DTB_LIST)) $(obj)/mtk.dtb: $(DTB_OBJS) FORCE $(call if_changed,cat)4.3 最终镜像路径构建系统生成的DTB相关文件最终存放在以下位置out/target/product/mt6752_64/obj/KERNEL_OBJ/dtbimg.cfgout/target/product/mt6752_64/obj/PACKAGING/dtb/mtk.dtb5. 高级调试技巧与实战案例理解构建流程后我们可以利用这些知识解决实际开发中的各种问题。5.1 手动调试DTBO生成当自动生成的DTBO出现问题时可以手动验证流程# 生成单个DTB文件 ./scripts/dtc/dtc -I dts -O dtb -o test.dtb arch/arm64/boot/dts/mediatek/mt6752_64.dts # 使用mkdtimg创建镜像 mkdtimg cfg_create dtbo.img dtboimg.cfg # 查看镜像内容 mkdtimg dump dtbo.img5.2 常见问题解决方案问题1DWS修改后配置未生效解决方案确认修改的是正确的DWS文件检查drvgen工具是否成功执行验证生成的cust_dtsi文件是否包含预期修改问题2DTBO加载失败排查步骤检查dtboimg.cfg中的路径是否正确确认使用的mkdtimg工具版本匹配验证板级配置是否正确定义了BOARD_PREBUILT_DTBOIMAGE问题3设备树版本冲突解决方法# 在BoardConfig.mk中明确指定版本 BOARD_KERNEL_BASE : 0x40000000 BOARD_KERNEL_TAGS_OFFSET : 0x07A00000 BOARD_KERNEL_OFFSET : 0x000800005.3 性能优化建议对于大型项目设备树构建可能成为编译瓶颈可以考虑以下优化增量编译合理设置.KATI_RESTAT规则避免不必要的重新生成缓存利用对稳定的DTS文件生成结果进行缓存并行处理调整Makefile中的依赖关系最大化并行度6. 工具链深度解析MTK设备树构建的核心工具是mkdtimg这个来自AOSP的工具经过MTK定制后功能更加强大。6.1 mkdtimg高级用法除了基础的cfg_create命令外mkdtimg还支持# 创建带版本信息的DTBO mkdtimg cfg_create dtbo.img dtboimg.cfg --version2 # 添加自定义标志 mkdtimg cfg_create dtbo.img dtboimg.cfg --flags0x0001 # 压缩DTBO镜像 mkdtimg cfg_create dtbo.img dtboimg.cfg --compress6.2 自定义构建流程对于需要特殊处理的场景可以修改构建规则$(BOARD_PREBUILT_DTBOIMAGE): $(HOST_OUT_EXECUTABLES)/mkdtimg $(BOARD_PREBUILT_DTBOIMAGE): $(KERNEL_OUT)/dtboimg.cfg $(hide) mkdir -p $(dir $) # 添加自定义预处理步骤 $(PRE_DTBO_HOOK) # 标准打包命令 $(PRIVATE_TOOL) cfg_create $ $(PRIVATE_CFG) \ --page_size$(BOARD_KERNEL_PAGESIZE) \ --version$(PLATFORM_DTBO_VERSION) # 添加后处理验证 $(VERIFY_DTBO_HOOK)6.3 设备树验证技巧构建完成后验证设备树镜像的正确性# 检查DTB兼容性 fdtdump dtbo.img | grep compatible # 比较两个版本的差异 diff (fdtdump v1.dtb) (fdtdump v2.dtb) # 提取特定版本的设备树 mkdtimg dump dtbo.img -b 0 -o extracted.dtb在实际项目中我们发现MT6752平台设备树的GPIO配置特别容易出错通过分析DWS到DTSI的转换日志可以快速定位大多数硬件兼容性问题。