--- title: 系统烧写与量产 tags: [系统烧写, SD卡, 串口, USB, 量产, MfgTool, 嵌入式Linux] created: 2026-09-16 updated: 2026-09-17 pdf_ref: "【正点原子】I.MX6U嵌入式Linux驱动开发指南V2.0.1 - 第三十九章 系统烧写" --- # 系统烧写与量产 > **关联知识**: [[06-系统移植与启动/01-U-Boot基础与命令]] | [[06-系统移植与启动/04-根文件系统构建]] | [[06-系统移植与启动/02-Linux内核编译]] --- ## 一、烧写方式概述 系统移植完成后,需要将 U-Boot、Linux Kernel、设备树(`.dtb`)和根文件系统(`rootfs`)四个文件烧写到板载 EMMC、NAND Flash 或 QSPI Flash 等存储设备上,使产品脱离网络独立运行。 > ⚠️ **来源说明**:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识。第 39 章只讲解 **MfgTool + USB OTG** 一种烧写方式;SD 卡 dd、串口 loadb、网络烧写、uuu 等均为扩展内容。 ```mermaid flowchart LR accTitle: Embedded Linux System Flashing Methods accDescr: Four main methods for flashing embedded Linux systems: SD card, serial, USB OTG, and network sd[💾 SD卡烧写] --> target[🎯 目标存储] serial[📡 串口烧写] --> target usb[🔌 USB烧写] --> target net[🌐 网络烧写] --> target classDef method fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e3a5f classDef target fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d class sd,serial,usb,net method class target target ``` | 烧写方式 | 接口 | 速度 | 适用场景 | 工具 | | ------------ | ------------- | -------- | -------------------- | --------------- | | **SD卡烧写** | SD/MMC卡槽 | ~10MB/s | 开发调试、批量生产 | `dd`、`mkfs` | | **串口烧写** | UART (TTL) | ~115KB/s | 紧急恢复、无网络环境 | U-Boot `loadb` | | **USB烧写** | USB OTG | ~20MB/s | 量产首选、NXP推荐 | MfgTool / `uuu` | | **网络烧写** | Ethernet/WiFi | ~100MB/s | 大文件、远程部署 | TFTP + NFS | > 💡 **选择建议**: 开发阶段优先用 SD卡 或 USB 烧写;量产环境首选 USB OTG(MfgTool);紧急恢复可用串口;大批量部署用网络。 --- ## 二、SD卡烧写 > ⚠️ **来源说明**:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识。第 39 章未讲解 SD 卡烧写;书中 U-Boot 烧写到 SD 卡使用的是`imxdownload`(见第 30 章)。 ### 2.1 硬件准备 - 一张 MicroSD 卡(建议 8GB 以上 Class 10) - 读卡器连接电脑 - 开发板支持 SD 卡启动(拨码开关设置) ### 2.2 格式化 SD 卡 在 Linux 主机上执行,将 SD 卡分为两个分区: ```bash # 查看 SD 卡设备编号(以 /dev/sdb 为例) lsblk # 使用 parted 创建分区表 sudo parted /dev/sdb mklabel msdos # 创建 FAT32 分区(存放 U-Boot、内核、设备树) sudo parted /dev/sdb mkpart primary fat32 1MiB 128MiB # 创建 ext4 分区(存放根文件系统) sudo parted /dev/sdb mkpart primary ext4 128MiB 100% # 格式化分区 sudo mkfs.vfat -F 32 /dev/sdb1 sudo mkfs.ext4 /dev/sdb2 ``` ### 2.3 烧写 U-Boot 到 SD 卡 U-Boot 需要写入 SD 卡的特定偏移位置(IMX6ULL 为扇区 2,即 1KB 偏移): ```bash # 将 U-Boot 写入 SD 卡(跳过前 1KB) sudo dd if=u-boot.imx of=/dev/sdb bs=1k seek=1 conv=fsync # 验证写入 sudo dd if=/dev/sdb bs=1k skip=1 count=100 2>/dev/null | xxd | head -5 ``` ### 2.4 拷贝内核与设备树 将编译好的文件复制到 FAT32 分区: ```bash # 挂载分区 sudo mkdir -p /mnt/sdboot sudo mount /dev/sdb1 /mnt/sdboot # 拷贝内核和设备树 sudo cp zImage /mnt/sdboot/ sudo cp imx6ull-alientek-emmc.dtb /mnt/sdboot/ # 卸载 sudo umount /mnt/sdboot ``` ### 2.5 拷贝根文件系统 ```bash # 挂载 ext4 分区 sudo mkdir -p /mnt/sdrootfs sudo mount /dev/sdb2 /mnt/sdrootfs # 解压根文件系统 sudo tar -xvf rootfs.tar.bz2 -C /mnt/sdrootfs/ # 卸载 sudo umount /mnt/sdrootfs ``` ### 2.6 U-Boot 启动参数设置 插入 SD 卡后,设置 U-Boot 从 SD 卡启动: ```bash # 在 U-Boot 命令行中设置 setenv bootcmd 'mmc dev 0;fatload mmc 0:1 0x80800000 zImage;fatload mmc 0:1 0x83000000 imx6ull-alientek-emmc.dtb;bootz 0x80800000 - 0x83000000' setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk0p2 rootwait rw' saveenv boot ``` ### 2.7 启动验证 ```bash # 串口终端观察启动日志 # 成功标志:出现 Linux version 和 login 提示 # 登录后验证 uname -a # 确认内核版本 df -h # 确认文件系统挂载 ls / # 确认根文件系统内容 ``` > ⚠️ **注意**: 一旦 SD 卡启动测试通过,建议用 USB OTG(MfgTool)烧写 EMMC 进行最终部署。 --- ## 三、串口烧写 > ⚠️ **来源说明**:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识。第 39 章未讲解串口/Ymodem 烧写。 ### 3.1 适用场景 串口烧写主要用于紧急恢复场景——当 EMMC 中无有效系统、网络不可用、USB 也无法使用时,通过 UART 串口将固件传输到板载 DDR,再由 U-Boot 写入存储。 ### 3.2 工具准备 - 串口终端软件:SecureCRT、minicom 或 PuTTY - 波特率:115200, 8N1 - 连接线:USB 转 TTL 串口线 ### 3.3 U-Boot Kermit/Ymodem 烧写 在 U-Boot 命令行中使用 `loadb` 命令配合串口协议传输文件: ```bash # 1. 设置串口波特率(U-Boot 中执行) setenv baudrate 115200 saveenv # 2. 使用 loadb 命令接收文件(Ymodem 协议) loadb 0x80800000 # 3. 在终端软件中选择"发送文件" -> Ymodem 协议 # 选择 zImage 文件进行发送 # 4. 发送完成后,写入 EMMC mmc dev 1 mmc write 0x80800000 0x800 0x3000 ``` ### 3.4 串口烧写完整流程 ```bash # === 阶段一:传输 U-Boot === loadb 0x87800000 # 通过 Ymodem 发送 u-boot.imx mmc dev 1 mmc write 0x87800000 0x2 0x300 # === 阶段二:传输内核 === loadb 0x80800000 # 通过 Ymodem 发送 zImage mmc dev 1 mmc write 0x80800000 0x800 0x3000 # === 阶段三:传输设备树 === loadb 0x83000000 # 通过 Ymodem 发送 imx6ull-alientek-emmc.dtb mmc dev 1 mmc write 0x83000000 0x3800 0x200 # === 阶段四:传输根文件系统 === loadb 0x83800000 # 通过 Ymodem 发送 rootfs.tar.bz2 mmc dev 1 mmc write 0x83800000 0x4000 0x40000 ``` ### 3.5 优缺点分析 | 优点 | 缺点 | | ------------------------------ | ------------------------------- | | 不依赖任何外部接口(仅需串口) | 速度极慢(115200 bps ≈ 10KB/s) | | 可恢复任何状态的板子 | 大文件传输耗时长 | | 工具简单,几乎所有终端都支持 | 需要人工操作发送协议 | > 💡 **实用建议**: 串口烧写仅作为最后手段。对于 IMX6ULL 的量产恢复,建议保留一个最小 U-Boot 在 EMMC 中,通过 U-Boot 的 `usb烧写` 功能恢复系统。 --- ## 四、USB烧写 ### 4.1 MfgTool 工具简介 MfgTool 是 NXP 官方提供的系统烧写工具,专为 I.MX 系列芯片设计,运行在 Windows 平台。工具路径通常为: ``` 5、开发工具 -> 3、NXP官方原版MFG_TOOL烧写工具 -> L4.1.15_2.0.0-ga_mfg-tools.tar.gz ``` ### 4.2 工具目录结构 ``` mfgtools-with-rootfs/mfgtools/ ├── MfgTool2.exe # 烧写主程序 ├── mfgtool2-yocto-mx-evk-emmc.vbs # EMMC烧写脚本 ├── mfgtool2-yocto-mx-evk-nand.vbs # NAND烧写脚本 ├── cfg.ini # 配置文件 └── Profiles/Linux/OS Firmware/ ├── ucl2.xml # 烧写命令脚本 ├── firmware/ # 第一阶段文件(下载到DDR) │ ├── u-boot-imx6ull14x14evk_emmc.imx │ ├── zImage │ └── zImage-imx6ull-14x14-evk-emmc.dtb └── files/ # 第二阶段文件(写入EMMC) ├── u-boot-imx6ull14x14evk_emmc.imx ├── zImage ├── zImage-imx6ull-14x14-evk-emmc.dtb └── rootfs_nogpu.tar.bz2 ``` ### 4.3 MfgTool 工作原理 ```mermaid flowchart TD accTitle: MfgTool Two-Stage Flashing Process accDescr: MfgTool uses a two-stage process: first boot Linux in DDR via USB, then flash full system to EMMC connect["🔌 USB OTG连接"] --> bootstrap["📥 阶段一:BootStrap"] bootstrap --> ddr["💾 下载firmware到DDR"] ddr --> boot["🚀 DDR中启动Linux"] boot --> flash["📦 阶段二:烧写"] flash --> partition["🗂️ 格式化EMMC分区"] partition --> write["✏️ 写入files目录文件"] write --> done["✅ 烧写完成"] classDef stage1 fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e3a5f classDef stage2 fill:#fef9c3,stroke:#ca8a04,stroke-width:2px,color:#713f12 classDef done fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d class bootstrap,ddr,boot stage1 class flash,partition,write stage2 class done done ``` **阶段一(BootStrap)**:将 `firmware/` 目录中的 U-Boot、zImage 和设备树通过 USB OTG 下载到 DDR,启动临时 Linux 系统。 **阶段二(Updater)**:利用 DDR 中运行的 Linux 系统,将 `files/` 目录中的完整系统(含 rootfs)烧写到 EMMC。 ### 4.4 硬件连接与设置 1. **USB OTG 连接**:使用 USB 线连接开发板 `USB_OTG1` 接口到电脑 2. **拨码开关**:拨到 USB 下载模式 3. **弹出 TF 卡**:如已插入 TF 卡,先弹出,待识别后再插入 4. **按复位键**:进入 USB 模式,电脑识别出 HID 设备 > ⚠️ **V2.4 以上版本底板**:USB OTG 口已更换为 Type-C 接口。 ### 4.5 自制系统的文件替换 将自己编译的文件重命名后替换 MfgTool 中的原始文件: | 原始文件 | 重命名目标 | 所在目录 | | --------------------------- | ----------------------------------- | ---------------- | | `u-boot.imx` | `u-boot-imx6ull14x14evk_emmc.imx` | firmware + files | | `zImage` | `zImage`(不改名) | firmware + files | | `imx6ull-alientek-emmc.dtb` | `zImage-imx6ull-14x14-evk-emmc.dtb` | firmware + files | | `rootfs.tar.bz2` | `rootfs_nogpu.tar.bz2` | files | ### 4.6 烧写步骤 ```bash # 1. 准备根文件系统(在 Ubuntu 中打包) cd rootfs/ tar -vcjf rootfs.tar.bz2 * # 2. 将4个文件拷贝到 Windows 的 MfgTool 目录 # firmware/ 放 3 个文件(u-boot + zImage + dtb) # files/ 放 4 个文件(u-boot + zImage + dtb + rootfs) # 3. 双击 mfgtool2-yocto-mx-evk-emmc.vbs # 4. 确认界面显示"符合 HID 标准的供应商定义设备" # 5. 点击 Start 开始烧写 # 6. 等待显示 "Done" 后点击 Stop -> Exit # 7. 拨码开关拨回 EMMC 启动,重启开发板 ``` ### 4.7 网络开机自启动配置 烧写完成后,Linux 内核不会自动打开网卡。在 `/etc/init.d/rcS` 中添加: ```bash #!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib export PATH LD_LIBRARY_PATH runlevel # 网络开机自启动 ifconfig eth0 up ifconfig eth0 192.168.1.251 netmask 255.255.255.0 route add default gw 192.168.1.1 ``` ### 4.8 ucl2.xml 结构与识别原理 `ucl2.xml` 以``开始、``结束:`...`判断烧写哪款芯片,``针对不同存储介质(SDCard/eMMC/Nor Flash/NAND Flash…)定义烧写命令序列。 ``通过 VID/PID 识别芯片(节选): ```xml ``` 即 VID=0x15A2、PID=0x0080 时判定为 I.MX6ULL。 `mfgtool2-yocto-mx-evk-emmc.vbs` 内容: ```vbscript Set wshShell = CreateObject("WScript.shell") wshShell.run "mfgtool2.exe -c ""linux"" -l ""eMMC"" -s ""board=sabresd"" -s ""mmc=1"" -s ""6uluboot=14x14evk"" -s ""6uldtb=14x14-evk""" Set wshShell = Nothing ``` 参数含义:`board=sabresd`、`mmc=1`、`6uluboot=14x14evk`、`6uldtb=14x14-evk`;文件名`%lite%`取`l`、`%6uluboot%`取`14x14evk`(在`cfg.ini`中定义),故`firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx`展开为`u-boot-imx6ull14x14evk_emmc.imx`。第一阶段下载完 uboot/kernel/dtb 后输出`Jumping to OS image.`并跳转启动 Linux。 ### 4.9 改造 MfgTool 支持正点原子开发板 书中 39.5 节从三方面改造: 1. **确定系统文件命名**:如`u-boot-alientek-emmc.imx`、`zImage-alientek-emmc`、`imx6ull-alientek-emmc.dtb`、`rootfs-alientek-emmc.tar.bz2`。 2. **新建 .vbs**:复制`mfgtool2-yocto-mx-evk-emmc.vbs`并重命名为`mfgtool2-alientek-alpha-emmc.vbs`(内容不改)。 3. **修改 ucl2.xml**:备份原文件后只保留``,把文件路径改为上面的命名。烧写关键命令:用`dd ... of=/dev/mmcblk%mmc%boot0 bs=512 seek=2`写 U-Boot(偏移 1024 字节),`mmc bootpart enable 1 1`使能启动分区,`mkfs.vfat`建 FAT 分区放 zImage/dtb,`mkfs.ext3 -F -E nodiscard`建 rootfs 分区,`pipe tar -jxv -C /mnt/...`解压 rootfs。 改造过后,`firmware/`放 3 个文件(uboot+zImage+dtb),`files/`放 4 个文件(再加 rootfs),双击新`.vbs`即可烧写。**注意**:一旦改造后的工具能正常烧写,`firmware/`目录下的文件以后不要再改,否则可能烧写失败。 ### 4.10 解决 “Starting kernel ...” 卡死 现象:烧写自研系统后 U-Boot 输出`Starting kernel ...`便无任何信息。原因是 U-Boot 默认`findfdt`取`imx6ull-14x14-evk.dtb`,而 EMMC 分区 1 中的设备树名为`imx6ull-alientek-emmc.dtb`(`mmc dev 1`+`ls mmc 1:1`可确认)。两种解决: 1. 在 U-Boot 中临时修改: ```bash setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000' setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' saveenv ``` 2. 永久修改 U-Boot 源码`include/configs/mx6ull_alientek_emmc.h`中`CONFIG_EXTRA_ENV_SETTINGS`的`findfdt`: ```c "findfdt="\ "if test $fdt_file = undefined; then " \ "setenv fdt_file imx6ull-alientek-emmc.dtb; " \ "fi;\0" \ ``` 改完重新编译 U-Boot 并烧写即可。 --- ## 五、量产方案 > ⚠️ **来源说明**:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识(uuu、批量脚本、质量检查等书中未涉及)。 ### 5.1 量产工具对比 | 工具 | 平台 | 速度 | 适用规模 | 特点 | | ---------------------------------- | ------- | ---------- | -------- | ---------------------- | | **MfgTool** | Windows | ~20MB/s | 小批量 | NXP 官方,配置灵活 | | **uuu (Universal Update Utility)** | 跨平台 | ~20MB/s | 中批量 | NXP 新工具,命令行友好 | | **SD卡量产** | 任意 | ~10MB/s | 中批量 | 无需电脑,可预烧写 | | **OTA远程升级** | 云端 | 受限于带宽 | 大规模 | 远程部署,需网络 | | **自动化脚本** | Linux | 可并行 | 大批量 | 灵活定制,可多设备并行 | ### 5.2 uuu 工具使用 uuu 是 NXP 推荐的新一代跨平台烧写工具,替代 MfgTool: ```bash # 安装 uuu(Linux/Mac/Windows) # Ubuntu: sudo apt install uuu # 编写烧写脚本 uuu.lst SDPS: boot -f firmware/u-boot-imx6ull14x14evk_emmc.imx FB: flash -raw2sparse all firmware/image.img FB: done # 执行烧写 sudo uuu uuu.lst ``` ### 5.3 SD卡批量量产流程 适用于需要大量预烧写 SD 卡的生产场景: ```bash #!/bin/bash # sdcard_flash.sh - SD卡批量烧写脚本 SD_DEV=$1 # 如 /dev/sdb echo "=== 格式化 SD 卡 ===" sudo parted ${SD_DEV} mklabel msdos sudo parted ${SD_DEV} mkpart primary fat32 1MiB 128MiB sudo parted ${SD_DEV} mkpart primary ext4 128MiB 100% sudo mkfs.vfat -F 32 ${SD_DEV}1 sudo mkfs.ext4 ${SD_DEV}2 echo "=== 烧写 U-Boot ===" sudo dd if=u-boot.imx of=${SD_DEV} bs=1k seek=1 conv=fsync echo "=== 拷贝内核与设备树 ===" sudo mount ${SD_DEV}1 /mnt/sdboot sudo cp zImage /mnt/sdboot/ sudo cp imx6ull-alientek-emmc.dtb /mnt/sdboot/ sudo umount /mnt/sdboot echo "=== 拷贝根文件系统 ===" sudo mount ${SD_DEV}2 /mnt/sdrootfs sudo tar -xvf rootfs.tar.bz2 -C /mnt/sdrootfs/ sudo umount /mnt/sdrootfs echo "=== 烧写完成 ===" ``` ### 5.4 自动化烧写脚本(USB 多设备并行) ```bash #!/bin/bash # usb_mass_flash.sh - USB多设备并行烧写 IMAGE_DIR="./firmware" FLASH_SCRIPT="./uuu.lst" # 监控新设备接入 watch_usb_device() { while true; do DEVICE_COUNT=$(lsusb | grep "15a2:0080" | wc -l) echo "检测到 ${DEVICE_COUNT} 个待烧写设备" sleep 2 done } # 主流程 echo "等待设备连接..." watch_usb_device & # 为每个设备启动烧写进程 for dev in $(uuu_list 2>/dev/null); do echo "烧写设备: ${dev}" sudo uuu -d ${dev} ${FLASH_SCRIPT} & done wait echo "所有设备烧写完成" ``` ### 5.5 量产质量检查 ```bash # 烧写后自动化验证脚本 #!/bin/bash # verify_flash.sh BOARD_IP=$1 # 1. 启动检测(等待设备上线) timeout 60 bash -c "until ping -c 1 ${BOARD_IP}; do sleep 2; done" echo "✅ 设备启动成功" # 2. 版本验证 VERSION=$(ssh root@${BOARD_IP} "cat /etc/version") echo "固件版本: ${VERSION}" # 3. 内存测试 ssh root@${BOARD_IP} "free -m" # 4. 存储测试 ssh root@${BOARD_IP} "df -h" # 5. 网络测试 ssh root@${BOARD_IP} "ping -c 3 8.8.8.8" echo "✅ 验证通过" ``` --- ## 六、烧写问题排查 ### 6.1 MfgTool 常见错误 > ⚠️ **来源说明**:本小节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识。6.2 节的“Starting kernel 卡死”与改`findfdt`属书中 39.5.3 内容。 | 错误现象 | 可能原因 | 解决方案 | | ---------------------------- | -------------------------- | ---------------------------------------- | | 无法识别 HID 设备 | USB 线未连接或拨码开关错误 | 检查 USB 线连接;确认拨码开关在 USB 模式 | | "No device connected" | TF 卡未弹出 | 弹出 TF 卡后重新插拔 USB | | 烧写过程中断 | USB 供电不足 | 使用独立供电 USB Hub 或更换 USB 口 | | "Jumping to OS image" 后卡住 | firmware 文件错误 | 检查 firmware 目录文件是否正确替换 | | "Done" 但无法启动 | 设备树或 U-Boot 名称不匹配 | 确认文件重命名与 ucl2.xml 一致 | ### 6.2 内核启动失败排查 **现象**: 串口输出 "Starting kernel ..." 后无任何信息。 ```bash # 在 U-Boot 命令行中检查 mmc dev 1 # 切换到 EMMC ls mmc 1:1 # 查看分区 1 文件列表 # 确认设备树文件名是否正确 # 检查 bootcmd 中的设备树文件名 printenv bootcmd # 确保设备树文件名与实际烧写的一致 ``` **解决方案**: ```bash # 方法一:在 U-Boot 中临时修改 setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000' setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' saveenv boot # 方法二:修改 U-Boot 源码(永久方案) # 文件:include/configs/mx6ull_alientek_emmc.h # 修改 findfdt 环境变量,将设备树文件名改为 imx6ull-alientek-emmc.dtb ``` ### 6.3 调试技巧 ```bash # 1. 查看 U-Boot 环境变量 printenv # 2. 查看 EMMC 分区信息 mmc part # 3. 手动读取文件验证 mmc dev 1 fatload mmc 1:1 0x80800000 zImage # 无报错说明文件读取正常 # 4. 查看设备树内容 fdt addr 0x83000000 fdt print / # 5. 串口日志抓取(SecureCRT) # 启用日志记录,保存完整启动日志用于分析 ``` --- ## 七、跨平台对比 > ⚠️ **来源说明**:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识。 ### 7.1 IMX6ULL vs STM32MP1 vs RK3568 烧写差异 | 特性 | IMX6ULL | STM32MP1 | RK3568 | | -------------- | ------------- | ------------------- | ------------------------ | | **官方工具** | MfgTool / uuu | STM32CubeProgrammer | RKDevTool / upgrade_tool | | **烧写接口** | USB OTG | USB DFU / UART | USB OTG / SD 卡 | | **启动模式** | 拨码开关 | BOOT0 引脚 | 按住 Recovery + 上电 | | **分区格式** | 固定脚本定义 | XML 配置文件 | parameter.txt + 分区表 | | **设备树支持** | `.dtb` 文件 | `.dtb` 文件 | `.dtb` 文件 | | **量产推荐** | uuu 工具 | CubeProgrammer 脚本 | upgrade_tool 批量 | | **OTA 支持** | 自行实现 | 自行实现 | A/B 分区原生支持 | ### 7.2 烧写流程对比 ```mermaid flowchart LR accTitle: Cross-Platform Flashing Workflow Comparison accDescr: Comparison of flashing workflows for three popular embedded Linux SoC platforms subgraph IMX6ULL a1[USB OTG] --> a2[MfgTool/uuu] a2 --> a3[DDR运行临时系统] a3 --> a4[写入EMMC] end subgraph STM32MP1 b1[USB DFU] --> b2[CubeProgrammer] b2 --> b3[直接写入Flash] end subgraph RK3568 c1[USB OTG] --> c2[RKDevTool] c2 --> c3[loader模式写入] end ``` --- ## 八、面试精选 > ⚠️ **来源说明**:本节不属于《I.MX6U嵌入式Linux驱动开发指南》内容,为扩展知识(答案基于书中事实整理)。 ### 题目 1:嵌入式系统烧写的核心流程是什么? **考察点**: 系统烧写原理理解 **参考答案**: 嵌入式 Linux 系统烧写通常分为两个阶段: 1. **引导阶段**:通过 USB/串口等方式将最小引导系统(U-Boot + 内核 + 设备树)下载到 DDR 中并运行,建立一个临时的 Linux 运行环境 2. **烧写阶段**:利用临时系统对目标存储(EMMC/NAND)进行分区、格式化,然后将完整系统(含 rootfs)写入存储 这种"借鸡生蛋"的设计思路使得烧写工具不需要直接操作存储芯片的底层驱动,而是利用 Linux 内核已有的文件系统和块设备驱动来完成写入操作。 ### 题目 2:MfgTool 中 ucl2.xml 的作用是什么?如何自定义? **考察点**: 工具配置能力 **参考答案**: ucl2.xml 是 MfgTool 的核心配置文件,负责: - **芯片识别**:通过 `` 段定义各芯片的 VID/PID,自动识别处理器型号 - **烧写命令**:通过 `` 段定义不同存储介质(EMMC/NAND/SD)的烧写命令序列 - **文件映射**:定义 firmware 和 files 目录中文件与目标芯片的对应关系 自定义时需修改三个地方:新建 `.vbs` 启动脚本、修改 `ucl2.xml` 中的烧写命令、替换 firmware/files 中的文件。关键是确保文件命名与 ucl2.xml 中的路径一致。 ### 题目 3:SD 卡烧写和 USB OTG 烧写的主要区别? **考察点**: 烧写方式选型 **参考答案**: | 维度 | SD卡烧写 | USB OTG 烧写 | | ------------ | --------------------- | --------------------------- | | **原理** | 直接 `dd` 写入块设备 | 通过 USB 传输到 DDR,再烧写 | | **速度** | ~10MB/s(取决于卡速) | ~20MB/s | | **依赖** | 需要读卡器 + 主机 | 仅需 USB 线 | | **量产性** | 可并行多卡 | 通常单设备烧写 | | **灵活性** | 每次需物理插拔 | 可远程/脚本控制 | | **恢复能力** | 可修复任何状态的板子 | 需要 ROM 中有 USB 启动代码 | ### 题目 4:量产中如何保证烧写的一致性和可靠性? **考察点**: 量产工程能力 **参考答案**: 1. **固件版本管理**:每次烧写使用确定版本的固件包,建立版本号与 MD5 校验的映射表 2. **烧写后验证**:自动检查关键文件(U-Boot、内核、设备树)的完整性,运行基本功能测试 3. **日志记录**:记录每台设备的烧写时间、固件版本、校验结果,便于追溯 4. **A/B 分区**:对 OTA 场景,采用 A/B 分区方案,支持回滚 5. **自动化脚本**:减少人工操作,批量烧写 + 批量验证 6. **环境隔离**:烧写主机与生产网络隔离,防止固件被篡改 ### 题目 5:Linux 内核启动后输出 "Starting kernel ..." 卡住,如何排查? **考察点**: 调试能力 **参考答案**: 这种现象说明 U-Boot 已正常工作,但 Linux 内核启动失败。排查步骤: 1. **设备树检查**:在 U-Boot 中 `ls mmc 1:1` 确认设备树文件是否存在且名称正确 2. **启动参数检查**:`printenv bootargs` 确认 `console` 参数(串口号和波特率)与硬件一致 3. **内核调试输出**:在 bootargs 中添加 `earlycon` 和 `ignore_loglevel` 获取更多日志 4. **设备树调试**:在 U-Boot 中 `fdt addr` + `fdt print` 验证设备树内容 5. **DDR 检查**:确认内核加载地址和设备树地址没有重叠 ```bash # 增强调试的 bootargs 示例 setenv bootargs 'console=ttymxc0,115200 earlycon=imxuart,0x02020000,115200 ignore_loglevel root=/dev/mmcblk1p2 rootwait rw' ``` --- **内容来源**: 《I.MX6U嵌入式Linux驱动开发指南》第39章 系统烧写 **最后更新**: 2026-09-17