2. Android分区基础
在理解 A/B 分区与无缝升级之前,必须先回到 Android 存储布局的起点:设备上的 eMMC/UFS 并不是一整块“随便写”的空间,而是被划分为多个具有明确职责的分区。每个分区承担启动、系统、厂商适配、用户数据等不同任务,升级机制本质上就是对这些分区的读写与切换。本节从传统分区结构讲起,重点说明 boot、system、vendor 等核心分区的作用,并介绍分区表与镜像格式的基本概念。
一、传统分区结构:从 GPT 到分区条目
现代 Android 设备普遍使用 GPT(GUID Partition Table)描述存储布局。GPT 位于磁盘头部,记录每个分区的名称、起始 LBA、结束 LBA、属性标志和唯一 GUID。Bootloader 在启动早期读取 GPT,找到 boot、system、vendor 等分区的位置,然后按顺序加载。传统(非 A/B)设备通常只有一套分区,升级时直接覆盖原分区内容,因此升级过程中设备无法正常启动,必须进入 Recovery 模式完成写入。
典型传统分区布局如下表所示:
| 分区名 | 主要作用 | 是否可被 OTA 覆盖 |
|---|---|---|
| boot | 内核 + ramdisk,负责挂载 system/vendor | 是 |
| system | Android 框架、系统应用、运行时库 | 是 |
| vendor | SoC/外设相关的 HAL、固件、配置 | 是 |
| product | 产品定制应用与资源 | 是 |
| userdata | 用户数据、应用数据、缓存 | 否(升级时保留) |
| misc | 启动命令、Recovery 指令、BCB | 否(仅写命令) |
| recovery | 恢复模式内核与 ramdisk | 是 |
可以看到,传统分区是“单份”的:boot 只有一份,system 只有一份。升级时如果写入过程中断电,设备可能无法启动,这就是传统 OTA 需要进入 Recovery、且升级期间不可用的根本原因。
二、boot、system、vendor 分区的作用
boot 分区包含 Linux 内核(kernel)和 ramdisk。Bootloader 校验并加载 boot 后,内核启动,ramdisk 中的 init 进程负责解析 fstab,挂载 system、vendor 等分区,最终启动 Android 用户空间。boot 分区是启动链的关键一环,一旦损坏,设备通常只能进入 fastboot 或黑屏。
system 分区存放 Android 框架层内容:/system/framework、系统应用、JNI 库、权限配置等。它通常以只读方式挂载,是 OTA 升级中体积最大、改动最频繁的分区。Android 10 之后,system 与 product 常被合并为 super 动态分区,但逻辑职责不变。
vendor 分区存放与具体硬件相关的实现:Camera HAL、Audio HAL、显示驱动、传感器固件、vendor/etc 配置等。它由 SoC 厂商和 ODM 维护,与 system 的版本必须匹配。Android 8.0 引入 Treble 后,system 与 vendor 通过稳定的 HIDL/AIDL 接口通信,使两者可以独立升级,这也是后续 A/B 与无缝升级能够成立的重要前提。
三、分区表与镜像格式入门
分区表描述“分区在哪里”,镜像格式描述“分区里装什么”。Android 常见的镜像格式包括:
- raw ext4:直接可挂载的 ext4 文件系统镜像,传统 system/vendor 常用。
- sparse image:稀疏镜像,用较小的文件表示大量空洞,fastboot 刷写时再展开,节省传输体积。
- Android sparse format:由
img2simg生成,头部含 magic0xED26FF3A。 - boot image:包含 kernel、ramdisk、second stage、dtb 及头部信息,Android 10 后使用 boot header v3/v4。
- super image:动态分区容器,内部通过 LP metadata 描述 system/vendor/product 等逻辑分区。
查看分区与镜像的常用命令如下:
# 查看设备分区表(需 root 或 adb shell)
adb shell ls -l /dev/block/by-name/
# 查看 GPT 分区条目
adb shell sgdisk --print /dev/block/sda
# 查看镜像类型
file system.img
simg2img system.img system_raw.img
# 查看 boot 镜像头部
unpackbootimg -i boot.img -o boot_out/
下面用一张图概括传统分区结构、启动链与镜像格式之间的关系:
四、案例与误区复盘
某项目在 Android 9 传统分区设备上做 OTA,升级包同时更新 boot 与 system。测试时发现:升级到 60% 断电后,设备无法开机,只能进 Recovery 重刷。复盘结论是:传统分区只有一份 boot,写入过程中被破坏后启动链断裂。这正是 A/B 分区要解决的问题——保留两份可启动分区,升级在后台槽位完成,失败可回退。
另一个常见误区是把 vendor 当成“普通系统目录”随意修改。实际上 vendor 与 system 之间存在接口契约:如果只更新 system 而 vendor 仍是旧版本,HAL 接口不匹配会导致开机后服务反复重启。因此 OTA 包必须保证 system、vendor、boot 的版本组合经过验证,不能只刷其中一个。
小结:传统分区结构是理解 Android 升级机制的底座。GPT 决定分区位置,boot/system/vendor 决定启动与运行职责,镜像格式决定这些分区如何被写入与校验。掌握这三层关系后,再学习 A/B 分区、slot 切换与无缝升级,就能清楚每一步到底在操作哪个分区、为什么需要两份副本,以及升级失败时系统如何回退。