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 刷写遵循“解锁 → 擦除 → 刷写 → 验证 → 重启”五步流程。下图展示了典型的分区刷写顺序与依赖关系:

Fastboot 标准刷写流程 1. 解锁 Bootloader 2. 擦除目标分区 3. 刷写分区镜像 4. 校验哈希值 5. 重启设备 校验通过 → 继续 校验失败 → 重刷 关键命令 fastboot flash boot boot.img fastboot flash system system.img fastboot reboot

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 开发中构建可靠的刷写流水线。