4. Fastboot 刷写固件:全量固件与增量固件、刷写流程、常见错误处理
Fastboot 是嵌入式 Linux 开发与量产中最核心的刷写协议之一。本章深入剖析全量固件与增量固件的设计差异、标准刷写流程、分区表对齐策略,以及高频错误的根因与解决方案。掌握这些内容,你将能够独立设计刷写脚本、诊断刷写失败,并优化产线效率。
4.1 全量固件 vs 增量固件
固件包的设计直接决定刷写时间、存储占用与 OTA 升级的灵活性。下表从多个维度对比两种固件类型:
| 对比维度 | 全量固件 | 增量固件 |
|---|---|---|
| 定义 | 包含所有分区的完整镜像,刷写时覆盖整个存储 | 仅包含与基线版本之间的差异数据块 |
| 刷写时间 | 较长(通常 3–10 分钟,取决于存储大小与 USB 速度) | 较短(通常 30 秒–2 分钟) |
| 可靠性 | 高,不依赖基线版本,可修复任意分区损坏 | 中等,依赖基线版本完整性,基线损坏则升级失败 |
| 存储占用 | 大(与存储容量成正比) | 小(通常为全量的 10%–30%) |
| 适用场景 | 首次刷写、救砖、量产烧录 | OTA 远程升级、小版本迭代 |
工程建议: 量产线优先使用全量固件 + 稀疏镜像(sparse image)以降低 USB 传输量;OTA 通道则使用 bsdiff/imgdiff 生成的增量包,配合 AB 分区方案实现无缝升级。
4.2 标准刷写流程
一次完整的 Fastboot 刷写遵循“解锁 → 擦除 → 刷写 → 验证 → 重启”五步流程。下图展示了典型的分区刷写顺序与依赖关系:
4.2.1 刷写脚本示例
以下是一个生产环境可用的全量刷写脚本片段,包含分区表对齐检查与错误重试逻辑:
#!/bin/bash
# fastboot_flash_full.sh — 全量固件刷写脚本
set -e
PARTITIONS="boot system vendor dtbo"
RETRY_COUNT=3
echo "[INFO] 解锁 bootloader..."
fastboot oem unlock || true
for part in $PARTITIONS; do
retry=0
while [ $retry -lt $RETRY_COUNT ]; do
echo "[INFO] 刷写 ${part}.img (尝试 $((retry+1))/${RETRY_COUNT})"
if fastboot flash ${part} ${part}.img --slot=all; then
echo "[OK] ${part} 刷写成功"
break
else
echo "[WARN] ${part} 刷写失败,重试..."
retry=$((retry+1))
sleep 1
fi
done
if [ $retry -eq $RETRY_COUNT ]; then
echo "[ERROR] ${part} 刷写失败,请检查 USB 连接或镜像文件"
exit 1
fi
done
echo "[INFO] 校验分区哈希..."
fastboot oem check-hash || echo "[WARN] 设备不支持哈希校验"
echo "[INFO] 重启设备..."
fastboot reboot
4.3 常见错误处理
Fastboot 刷写失败通常由驱动、分区表、镜像损坏或存储坏块引起。下表整理了 6 个高频错误及其根因与修复方案:
| 错误现象 | 根因分析 | 解决方案 |
|---|---|---|
FAILED (remote: 'unknown command') |
Bootloader 版本过旧,不支持该 Fastboot 命令 | 升级 bootloader 或使用兼容的 fastboot 版本(推荐 v34+) |
FAILED (remote: 'size too large') |
镜像大小超过分区容量,或稀疏镜像未正确解压 | 检查分区表(fastboot getvar partition-size:system),使用 simg2img 转换稀疏镜像 |
FAILED (remote: 'flash write failure') |
eMMC/NAND 坏块或分区表被锁定 | 执行 fastboot oem unlock 解锁,或使用 mmc 命令标记坏块 |
FAILED (data transfer failure) |
USB 线缆质量差、供电不足或驱动异常 | 更换 USB 线缆,使用独立 USB 端口,重新安装驱动 |
FAILED (remote: 'partition table doesn't exist') |
设备未进入 Fastboot 模式,或 GPT 表损坏 | 强制进入 Fastboot(组合键),重新烧录 GPT 分区表 |
FAILED (remote: 'hash mismatch') |
镜像文件在传输过程中损坏 | 重新下载固件,校验 MD5/SHA256,使用 fastboot flash --force 跳过校验(仅调试) |
重要提醒: 切勿在生产环境中使用
--force 跳过哈希校验。如果遇到“hash mismatch”,应优先排查 USB 稳定性与镜像完整性,而非强制刷写,否则可能导致设备变砖。
4.4 分区表对齐与稀疏镜像
嵌入式设备的存储介质(eMMC、UFS)对写入对齐有严格要求。分区起始地址必须与擦除块大小(通常为 512 字节或 4 KiB)对齐,否则会触发读-改-写操作,导致性能下降与寿命缩短。
稀疏镜像(sparse image)是 Android 与嵌入式 Linux 中广泛使用的镜像格式,它通过描述数据块偏移与长度来减少传输量。Fastboot 在刷写稀疏镜像时会自动解压并写入,无需手动转换。
# 检查分区对齐情况
fastboot getvar partition-size:boot
fastboot getvar partition-type:boot
# 将原始镜像转换为稀疏镜像(Android 工具链)
img2simg system_raw.img system_sparse.img 4096
# 刷写稀疏镜像(Fastboot 自动识别)
fastboot flash system system_sparse.img
4.5 刷写策略选择矩阵
根据设备状态与场景,选择合适的刷写策略可以大幅提升成功率与效率:
| 设备状态 | 推荐策略 | 关键参数 |
|---|---|---|
| 全新设备(首次烧录) | 全量固件 + 稀疏镜像 | --slot=all 双槽位刷写 |
| 系统崩溃(救砖) | 全量固件 + 强制刷写 | 先擦除 fastboot erase system 再刷写 |
| OTA 升级 | 增量固件 + AB 分区 | 使用 update_engine 或 applypatch |
| 产线量产 | 全量固件 + 多线程刷写 | 使用 fastboot flashall 或工厂脚本 |
核心要点: 全量固件是救砖与量产的基础保障,增量固件是 OTA 效率的关键。刷写前务必验证分区表对齐与镜像完整性,刷写中监控 USB 传输稳定性,刷写后执行哈希校验与功能自检。掌握这些原则,你就能在嵌入式 Linux 开发中构建可靠的刷写流水线。