fastboot刷写与嵌入式Linux启动优化实战 - 第3节
3.1 分区表概念与嵌入式布局
在嵌入式 Linux 系统中,存储介质(eMMC / NAND / UFS)通常被划分为多个固定大小的区域,称为分区。分区表记录了每个分区的起始地址、大小、属性和用途。Fastboot 刷写的本质就是按照分区表将镜像写入对应的物理区域。
3.1.1 分区表的核心要素
| 要素 | 说明 | 典型值 |
|---|---|---|
| 分区名称 | Fastboot 命令中使用的逻辑标识 | boot、system、vendor |
| 起始地址 | 分区在存储介质上的偏移量(LBA 或字节) | 0x00008000 |
| 分区大小 | 分配给该分区的最大容量 | 64 MiB、2 GiB |
| 分区类型 | 文件系统或裸数据标识 | ext4、raw、gpt |
| 属性标志 | 可引导、只读、隐藏等 | bootable、read-only |
实践要点:嵌入式设备通常使用 GPT(GUID Partition Table)或 MBR(Master Boot Record)两种分区表格式。GPT 支持更多分区(128+)和更大容量,是当前主流选择。
3.1.2 典型嵌入式分区布局
以下是一个基于 eMMC 的典型 Android / Linux 嵌入式分区布局示意:
常见陷阱:分区大小不匹配是刷写失败的首要原因。如果镜像文件大于目标分区,Fastboot 会报
FAILED (remote: 'size too large')。刷写前务必使用 fastboot getvar all 确认分区容量。
3.2 boot / system / vendor 分区刷写实战
这三个分区是嵌入式 Linux 启动的核心:boot 包含内核与 ramdisk,system 包含系统服务与框架,vendor 包含硬件抽象层(HAL)与专有库。刷写顺序和参数直接影响设备能否正常启动。
3.2.1 刷写命令与参数详解
| 分区 | Fastboot 命令 | 镜像格式 | 关键参数 |
|---|---|---|---|
| boot | fastboot flash boot boot.img |
boot image (内核 + dtb + ramdisk) | 必须包含 kernel 和 ramdisk |
| system | fastboot flash system system.img |
ext4 / sparse image | 支持 sparse 格式节省传输时间 |
| vendor | fastboot flash vendor vendor.img |
ext4 / sparse image | 与 system 版本必须匹配 |
3.2.2 刷写流程与状态检查
- 进入 Fastboot 模式:设备上电时按住特定按键(如音量减 + 电源),或通过
adb reboot bootloader进入。 - 确认连接:执行
fastboot devices,应返回设备序列号。 - 擦除旧分区(可选):
fastboot erase boot清除分区内容,避免残留数据干扰。 - 刷写 boot 分区:
fastboot flash boot boot.img,等待OKAY状态。 - 刷写 system 分区:
fastboot flash system system.img,大镜像可能需要数分钟。 - 刷写 vendor 分区:
fastboot flash vendor vendor.img。 - 验证刷写:
fastboot getvar all检查分区版本哈希。
刷写状态码解读:
OKAY [0.123s]— 刷写成功,耗时 123 毫秒。FAILED (remote: 'partition table doesn't exist')— 分区表未烧录或损坏。FAILED (remote: 'flash write failure')— 存储介质写入错误,可能硬件故障。
3.3 刷写脚本编写与自动化
手动逐条输入 Fastboot 命令效率低且容易出错。通过编写刷写脚本,可以将整个流程自动化,支持批量生产场景。以下分别给出 Windows(批处理)和 Linux(Shell)两种脚本示例。
3.3.1 Windows 批处理脚本(flash.bat)
@echo off
echo ========================================
echo Fastboot 刷写脚本 - 嵌入式 Linux
echo ========================================
:: 检查 Fastboot 连接
fastboot devices >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] 未检测到 Fastboot 设备,请检查连接。
pause
exit /b 1
)
:: 擦除分区(可选)
echo [INFO] 正在擦除 boot/system/vendor 分区...
fastboot erase boot
fastboot erase system
fastboot erase vendor
:: 刷写分区
echo [INFO] 正在刷写 boot.img...
fastboot flash boot boot.img
if %errorlevel% neq 0 (
echo [ERROR] boot 分区刷写失败!
pause
exit /b 1
)
echo [INFO] 正在刷写 system.img...
fastboot flash system system.img
if %errorlevel% neq 0 (
echo [ERROR] system 分区刷写失败!
pause
exit /b 1
)
echo [INFO] 正在刷写 vendor.img...
fastboot flash vendor vendor.img
if %errorlevel% neq 0 (
echo [ERROR] vendor 分区刷写失败!
pause
exit /b 1
)
:: 验证刷写
echo [INFO] 验证分区版本...
fastboot getvar all | findstr "partition-size"
echo [SUCCESS] 所有分区刷写完成!
pause
3.3.2 Linux Shell 脚本(flash.sh)
#!/bin/bash
# Fastboot 刷写脚本 - 嵌入式 Linux
# 用法: ./flash.sh [镜像目录路径]
set -e
IMAGE_DIR="${1:-.}"
echo "========================================"
echo " Fastboot 刷写脚本 - 嵌入式 Linux"
echo " 镜像目录: $IMAGE_DIR"
echo "========================================"
# 检查 fastboot 命令
if ! command -v fastboot &> /dev/null; then
echo "[ERROR] fastboot 命令未找到,请安装 Android SDK 平台工具。"
exit 1
fi
# 检查设备
fastboot devices 2>&1 | grep -q "fastboot"
if [ $? -ne 0 ]; then
echo "[ERROR] 未检测到 Fastboot 设备。"
exit 1
fi
# 定义分区列表
PARTITIONS=("boot" "system" "vendor")
# 擦除并刷写
for part in "${PARTITIONS[@]}"; do
img_file="${IMAGE_DIR}/${part}.img"
if [ ! -f "$img_file" ]; then
echo "[WARNING] 镜像文件 $img_file 不存在,跳过 $part 分区。"
continue
fi
echo "[INFO] 正在擦除 $part 分区..."
fastboot erase "$part" || true
echo "[INFO] 正在刷写 $part 分区 ($img_file)..."
fastboot flash "$part" "$img_file"
echo "[INFO] $part 分区刷写完成。"
done
# 验证
echo "[INFO] 验证分区刷写结果..."
fastboot getvar all 2>&1 | grep -E "partition-size:|version"
echo "[SUCCESS] 所有分区刷写完成!"
3.3.3 脚本关键设计原则
| 原则 | 说明 | 脚本实现示例 |
|---|---|---|
| 幂等性 | 多次执行脚本结果一致,不会因重复刷写导致状态异常 | 每次刷写前先 erase 分区 |
| 错误处理 | 任一分区刷写失败时立即停止,避免部分更新导致设备变砖 | Shell 脚本使用 set -e,批处理检查 %errorlevel% |
| 可配置性 | 镜像路径、分区列表可通过参数或环境变量调整 | Shell 脚本接受 $1 作为镜像目录 |
| 日志输出 | 清晰显示当前步骤、成功/失败状态,便于排查 | 使用 [INFO]、[ERROR] 前缀标记 |
生产环境建议:在批量烧录场景中,建议在脚本中加入 CRC 校验步骤:刷写完成后读取分区内容并计算哈希,与原始镜像对比,确保数据完整性。例如:
fastboot get_staged boot.img 配合本地 sha256sum 比对。
3.4 刷写常见问题与排错
- 问题:
FAILED (remote: 'not supported in locked device')
原因:设备 bootloader 处于锁定状态。
解决:执行fastboot flashing unlock解锁(注意:会清除用户数据)。 - 问题:
FAILED (remote: 'size too large')
原因:镜像文件大于分区容量。
解决:使用fastboot getvar partition-size:boot查看分区大小,重新编译或裁剪镜像。 - 问题:刷写后设备卡在启动 logo
原因:boot 分区内核与 system 分区版本不匹配,或 vendor 分区缺少关键驱动。
解决:确保三个镜像来自同一构建版本,重新刷写全部三个分区。 - 问题:
fastboot devices无输出
原因:USB 驱动未安装或设备未进入 Fastboot 模式。
解决:在 Linux 下检查lsusb,Windows 下安装设备厂商驱动。
重要提醒:刷写操作具有高风险。在量产或开发板上操作前,务必确认拥有完整的原始固件备份。错误的刷写可能导致设备无法恢复,需要硬件烧录器才能修复。