用usb_burning_tool玩转双分区烧录:从零开始的实战指南
你有没有遇到过这样的场景?
新到一批开发板,要刷固件。以前是插SD卡、进系统、一条条敲命令,反复重启,一不小心就把bootloader写错了版本,设备直接“变砖”。更别提小批量试产时,每台机器都要手动操作一遍——效率低不说,还容易出错。
如果你正在基于 Amlogic 平台(比如 S905X、A311D 或 S928X)做嵌入式开发,那么今天我们要聊的这个工具,可能会彻底改变你的工作流:usb_burning_tool。
它不靠操作系统,不用SD卡,只要一根USB线,就能把多个镜像一次性写入eMMC,而且原生支持A/B双分区架构—— 这正是实现无缝OTA升级和自动回滚的关键基础。
下面,我就带你一步步走完整个流程:从原理讲起,到配置文件怎么写,再到实际烧录中的坑点与避坑秘籍。目标只有一个:让你看完就能上手,一次成功。
为什么我们需要usb_burning_tool?
在说“怎么做”之前,先搞清楚“为什么”。
当代嵌入式系统的复杂性
现在的智能盒子、工业网关、边缘计算终端,早已不是只跑一个Linux内核那么简单。典型的系统结构至少包括:
- Bootloader(如U-Boot)
- DTB(设备树)
- Kernel
- Rootfs / System 分区
- Logo 开机画面
- UserData 用户数据
如果要做高可用设计,还得加上:
-recovery 分区
-misc 控制元数据
- 以及最关键的:两套 system 和 boot 的副本(即 A/B Slot)
这么多镜像,传统方式怎么刷?
逐个来?adb push?fastboot flash?
可以,但太慢了,而且每一步都有失败风险。尤其在硬件刚 bring-up 阶段,连网络都没通,你怎么adb?
这时候,就需要一种脱离操作系统、直连芯片底层的烧录手段。
MaskROM 模式:真正的“裸机级”访问
Amlogic SoC 提供了一种特殊的启动模式叫MaskROM Mode。简单来说,就是当你短接某个引脚再上电时,芯片不会去加载任何外部存储的内容,而是运行固化在ROM里的一段代码,这段代码会初始化USB控制器,并等待PC端发送指令。
此时,PC上的usb_burning_tool就能通过专用协议,直接往 eMMC 或 SPI NAND 写数据 —— 完全不需要设备有系统、不需要驱动、甚至不需要供电稳定(只要能开机就行)。
这就像给设备打了一针“强心剂”,哪怕它是“死”的,也能被救回来。
usb_burning_tool到底是什么?
你可以把它理解为一个图形化烧录前端 + 配置驱动引擎的组合体。
它本身不做复杂的逻辑处理,但它的行为完全由一个名为burning-config.ini的配置文件控制。你告诉它:“哪个镜像写到哪个分区”,它就照做。
更重要的是,它支持:
✅ 多分区并发写入
✅ 自动校验(VerifyWrite)
✅ 错误重试机制
✅ 支持 eMMC / SPI NAND
✅ 原生识别_a/_b双槽命名规则
✅ 烧录后自动重启
这些特性让它成为研发初期和小批量生产的首选工具。
核心玩法:双分区架构下的完整烧录方案
我们以最常见的 A/B 架构为例,说明如何用usb_burning_tool实现双系统部署。
典型双分区布局示意
| 分区名 | 对应物理分区 | 用途说明 |
|---|---|---|
| boot_a | p8 | Slot A 启动引导 |
| boot_b | p9 | Slot B 启动引导 |
| system_a | p10 | Slot A 根文件系统 |
| system_b | p11 | Slot B 根文件系统 |
| dtb | p6 | 设备树(通常共用) |
| logo | p7 | 开机LOGO(可共用) |
注:这里的
pX是指/dev/mmcblk0pX,也就是 eMMC 的逻辑分区编号。
这套结构意味着:无论当前运行的是 A 还是 B,另一套都可以安全地接收更新。下次启动时切换过去即可完成升级。
关键配置文件:burning-config.ini
这是整个烧录过程的灵魂。下面是一个经过验证的双分区配置示例:
[PARTITION] Count = 6 ; ---------------- Slot A ---------------- Index = 0 Name = boot_a ImageFile = ./images/boot_a.img FlashType = emmc PartitionNum = 8 VerifyWrite = 1 Index = 1 Name = system_a ImageFile = ./images/system_a.img FlashType = emmc PartitionNum = 10 VerifyWrite = 1 ; ---------------- Slot B ---------------- Index = 2 Name = boot_b ImageFile = ./images/boot_b.img FlashType = emmc PartitionNum = 9 VerifyWrite = 1 Index = 3 Name = system_b ImageFile = ./images/system_b.img FlashType = emmc PartitionNum = 11 VerifyWrite = 1 ; ---------------- 公共分区 ---------------- Index = 4 Name = logo ImageFile = ./images/logo.img FlashType = emmc PartitionNum = 7 VerifyWrite = 1 Index = 5 Name = dtb ImageFile = ./images/dtb.img FlashType = emmc PartitionNum = 6 VerifyWrite = 1 [GLOBAL] AutoReboot = 1 StopOnError = 1 ShowProgress = 1配置要点解读:
PartitionNum必须严格对应目标设备的实际分区表!错了会导致无法启动。- 所有
.img文件路径建议使用相对路径,并确保都在./images/目录下。 VerifyWrite = 1表示写入后自动读回比对,强烈建议开启。AutoReboot = 1让设备烧完自动重启,省去手动干预。- 名称中带
_a/_b是标准做法,后续 U-Boot 和内核都会据此判断启动槽位。
⚠️ 特别提醒:不同主板的分区表可能不同!务必确认你的设备是否真的把
system_a映射到了 p10。可以用fdisk -l /dev/mmcblk0查看。
工作流程实操:六步完成烧录
第一步:准备镜像文件
你需要提前编译好以下文件并放入./images/目录:
boot_a.img—— 包含 U-Boot 和启动参数boot_b.img—— 同上,用于B槽system_a.img—— 完整根文件系统A版system_b.img—— 完整根文件系统B版dtb.img—— 设备树(一般共用)logo.img—— 开机图片(RGB565格式)
建议生成每个镜像的同时输出 SHA256 校验值,便于后期验证完整性。
sha256sum *.img > manifest.sha256第二步:设置设备进入 MaskROM 模式
方法因板子而异,常见方式有:
- 短接主板上的
RECOVERY引脚到地 - 使用特定按键组合(如 power + reset)
- 某些开发板提供专用跳线帽
断电 → 接线 → 上电,顺序不能错!
一旦成功,PC会识别到一个名为 “AML-SMSC USB Device” 或类似名称的未知设备(无需安装驱动),说明已进入MaskROM状态。
第三步:启动 usb_burning_tool
打开usb_burning_tool.exe(Windows平台),点击左上角“Load Config”加载你的burning-config.ini。
界面会列出所有待烧录的分区及其状态。
此时连接USB线,工具会自动检测到设备,状态变为“Connected”。
第四步:开始烧录
点击 “Start” 按钮,工具将按配置顺序依次写入各分区。
过程中你会看到:
- 实时进度条
- 当前写入的分区名称
- 数据传输速率(通常可达 8~12 MB/s,取决于USB版本)
- CRC校验结果
整个过程大约持续 2~5 分钟(视镜像大小而定)。
第五步:自动重启与首次启动验证
若配置了AutoReboot=1,烧录完成后设备将自动重启。
通过串口调试器(波特率通常为 115200)观察输出日志:
Booting kernel from Partition 8 (boot_a)... Starting kernel ... androidboot.slot_suffix=_a关键点来了:检查内核命令行是否有androidboot.slot_suffix=_a或_b,这是判断当前启动槽位的核心标志。
还可以查看:
cat /proc/cmdline mount | grep system确认挂载的是system_a还是system_b。
第六步:测试双槽切换能力(可选)
如果你想验证未来OTA升级的可行性,可以在U-Boot中手动修改启动槽位。
例如,在U-Boot命令行输入:
setenv bootargs $bootargs androidboot.slot_suffix=_b saveenv reset看是否能顺利切到B槽启动。
更高级的做法是集成bootctrlHAL 层服务,让Android系统自己管理切换逻辑。
踩过的坑 & 实战经验分享
❌ 坑点1:PartitionNum 写错,导致系统无法启动
最常见错误!很多人复制别人的配置文件却不改分区号。
记住:你的设备分区表说了算。不要假设 p10 一定是 system_a。
解决办法:用mmc part命令查清目标设备的真实布局。
❌ 坑点2:镜像路径包含中文或空格,工具崩溃
usb_burning_tool对路径非常敏感。
✅ 正确做法:
D:\project\burning\ ├── usb_burning_tool.exe ├── burning-config.ini └── images/ ├── boot_a.img └── system_a.img❌ 错误路径:
D:\我的项目\烧录工具\images\system a.img❌ 坑点3:未启用 VerifyWrite,写入出错无感知
有些用户为了提速关闭校验,结果写进去的数据其实是坏的。
建议始终开启:
VerifyWrite = 1虽然多花几秒,但换来的是稳定性保障。
❌ 坑点4:权限不足导致访问USB失败
Windows 下常出现“Device not found”或“Access Denied”。
✅ 解决方案:
- 以管理员身份运行usb_burning_tool.exe
- 安装 Zadig 工具为 AML 设备安装 libusb-win32 驱动(仅首次需要)
✅ 秘籍1:批量烧录的小技巧
如果你要做小批量生产,可以把整个目录打包成模板:
project-burn/ ├── tool/ │ └── usb_burning_tool.exe ├── config/ │ └── burning-config.ini └── images/ ├── boot_a.img └── ...交给产线人员只需三步:插线 → 上电 → 点Start。
标准化程度越高,出错概率越低。
✅ 秘籍2:结合脚本做自动化预检
虽然usb_burning_tool是GUI程序,但我们可以通过批处理脚本做前期检查:
@echo off echo 正在检查镜像完整性... for %%f in (images\*.img) do ( if not exist "%%f" ( echo 缺失镜像:%%f pause exit /b 1 ) ) echo 所有镜像准备就绪,即将启动烧录工具... start "" "tool\usb_burning_tool.exe"提升专业感的同时也减少人为失误。
为什么这招值得掌握?
也许你会问:我都用 fastboot 了,为啥还要学这个?
因为它们根本不是一个量级的工具。
| 维度 | fastboot | usb_burning_tool |
|---|---|---|
| 是否依赖系统 | 是(需进入fastboot模式) | 否(MaskROM,裸机级) |
| 写入速度 | 中等(协议开销大) | 极快(接近USB理论带宽) |
| 成功率 | 中(受环境影响) | 高(几乎100%) |
| 是否支持双分区 | 支持但需手动处理 | 原生支持 A/B 命名 |
| 适用阶段 | 调试、OTA测试 | 硬件Bring-up、量产前准备 |
换句话说:
fastboot 是给“活”的设备用的;
usb_burning_tool是给“死”的设备续命的。
而且,只有在第一次烧录时就把双分区框架搭好,未来的 OTA 升级才有可能实现“无缝切换+自动回滚”。
否则,等到产品上市了才发现不能双系统切换?那就只能返厂重刷了。
结语:让每一次烧录都可靠可控
掌握usb_burning_tool的双分区烧录技术,不只是学会了一个工具的使用,更是建立起一套工程化思维:
- 如何保证多镜像协同部署的一致性?
- 如何为未来功能预留扩展空间?
- 如何降低量产阶段的人工干预成本?
这些问题的答案,往往就藏在一个小小的burning-config.ini文件里。
当你能把几十台设备都刷成完全一致的状态,当你的OTA升级能做到用户无感切换,你就真正迈入了高质量嵌入式开发的门槛。
💡延伸思考:
你现在的产品是否已经具备双分区能力?如果没有,能否在下一版中加入?
不妨现在就开始规划分区表,准备好两套镜像,试着用usb_burning_tool走一遍流程。
哪怕只是做个实验,也会为你未来的系统稳定性打下坚实基础。
如果你在实践中遇到了其他问题,欢迎留言交流,我们一起排坑。