保姆级教程:从零改造NXP MfgTool,打造专属i.MX6ULL开发板烧写工具
从零定制NXP MfgTool:打造i.MX6ULL开发板专属烧录工具体系
当一块全新的i.MX6ULL开发板从生产线完成硬件组装后,如何将精心编译的U-Boot、内核与文件系统精准部署到存储介质?官方提供的MfgTool虽然开箱即用,但面对定制化硬件时,其预设的烧录流程往往显得力不从心。本文将揭示如何从底层解构这套工具链,构建完全适配自家硬件的烧录解决方案。
1. 理解MfgTool的双阶段烧录架构
MfgTool的核心价值在于其分阶段处理机制。第一阶段通过USB将微型Linux系统(通常小于16MB)加载到开发板内存中运行,这个临时系统包含了格式化工具、分区工具和文件传输工具。第二阶段则在该临时系统环境下,执行实际的存储介质编程操作。
关键目录结构解析:
mfgtools/ ├── Profiles/ # 设备配置中枢 │ └── Linux/ │ ├── OS Firmware/ # 第一阶段镜像 │ └── ucl2.xml # 烧录指令集 ├── firmware/ # 第二阶段镜像仓库 └── files/ # 用户文件分发区注意:不同版本的MfgTool目录结构可能略有差异,建议先通过
tree命令查看完整布局
2. 硬件适配关键改造点
2.1 固件镜像定制化
官方提供的u-boot-imx6ull14x14evk.imx显然不适用于自定义板卡。替换步骤:
- 将编译好的U-Boot镜像(如
u-boot-custom-board.imx)放入firmware目录 - 修改
Profiles/Linux/OS Firmware/firmware.ini:[firmware] uboot = u-boot-custom-board.imx dtb = imx6ull-your-board.dtb - 更新内存加载地址参数(以512MB RAM为例):
<!-- ucl2.xml片段 --> <CMD state="Updater" type="load" file="firmware/u-boot-custom-board.imx" address="0x87800000" loadSection="OTH" setSection="OTH" />
2.2 设备树与内核匹配
常见问题排查表:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 卡在Starting Kernel | DTB不匹配 | 检查files/目录下的dtb文件是否与内核编译时使用的版本一致 |
| USB枚举失败 | 内核配置差异 | 在menuconfig中确认CONFIG_USB_CONFIGFS系列选项已启用 |
| 无法识别eMMC | 设备树引脚定义错误 | 对比硬件原理图验证pinctrl_hog配置 |
3. 烧录逻辑深度定制
3.1 ucl2.xml指令集解析
典型NAND烧写指令序列示例:
<LIST name="NAND Flash" desc="Choose NAND as storage medium"> <!-- 擦除NAND --> <CMD state="Updater" type="push" body="mtd erase /dev/mtd0"/> <!-- 写入UBI镜像 --> <CMD state="Updater" type="push" body="$ dd if=/dev/zero bs=1M count=2 | tr '\000' '\377' > /tmp/blankff"/> <CMD state="Updater" type="push" body="flash_erase /dev/mtd0 0 0"/> <CMD state="Updater" type="push" body="nandwrite -p /dev/mtd0 /tmp/blankff"/> <CMD state="Updater" type="push" body="ubiformat /dev/mtd0 -f %FILE%"/> </LIST>提示:使用
body="echo $?"可以检查上条命令执行结果,便于调试复杂脚本
3.2 多配置切换实现
通过环境变量实现动态配置选择:
' custom_flash.vbs Function GetBoardType() Dim board board = InputBox("请输入板卡型号 (1-标准版, 2-工业版)", "配置选择") Select Case board Case "1" GetBoardType = "standard" Case "2" GetBoardType = "industrial" Case Else GetBoardType = "abort" End Select End Function Sub Main Set profile = CreateObject("MxManufacturingCfg.Profile") profile.LoadProfile "Profiles\Linux\OS Firmware\firmware.ini" boardType = GetBoardType() If boardType = "standard" Then profile.SetVariable "UBOOT_IMG", "u-boot-std.imx" ElseIf boardType = "industrial" Then profile.SetVariable "UBOOT_IMG", "u-boot-ind.imx" End If End Sub4. 高级调试技巧
4.1 串口日志实时监控
在ucl2.xml中插入调试命令:
<CMD state="Updater" type="push" body="dmesg -n 8"/> <!-- 启用内核调试输出 --> <CMD state="Updater" type="push" body="cat /proc/kmsg > /dev/ttymxc0"/>4.2 烧录进度可视化改造
修改进度提示方式示例:
# progress_notifier.py import serial from tqdm import tqdm ser = serial.Serial('/dev/ttyUSB0', 115200) with open('flash.log', 'w') as f: for line in iter(ser.readline, b''): if 'Progress' in line: pct = int(line.split(':')[1].strip()) tqdm.write(f"烧录进度: {pct}%") f.write(line)实际项目中,我发现最耗时的往往不是技术实现,而是确保各环节的版本一致性——U-Boot的DDR初始化参数必须与硬件设计匹配,内核的设备树必须包含准确的Flash分区表,而文件系统镜像又需要与内核的MTD配置对齐。这种"三位一体"的版本管理,建议通过Git子模块或repo工具来维护。
