2. Android存储与分区基础
要理解 Android 动态分区与 Virtual A/B,必须先回到最底层的存储介质与分区布局。Android 设备上的所有镜像——boot、system、vendor、userdata——最终都落在同一块闪存芯片上。这块芯片是 eMMC 还是 UFS,决定了读写带宽、并发能力和随机 IO 性能;而分区表如何描述这些镜像的位置,决定了引导链能否找到它们。本节从物理介质讲到逻辑分区,为后续动态分区的“空间再分配”打基础。
一、物理介质:eMMC 与 UFS 的差异
eMMC(embedded MultiMediaCard)和 UFS(Universal Flash Storage)都是焊在主板上的闪存封装,但二者架构不同。eMMC 采用半双工并行接口,同一时刻只能读或写,命令队列深度有限;UFS 采用全双工串行接口(MIPI UniPro + M-PHY),支持命令队列(Command Queue),读写可并发,随机 IOPS 显著更高。
对 Android 而言,这个差异直接影响开机速度、应用安装耗时和 A/B 更新时的镜像写入效率。UFS 2.1 的顺序读可达约 800MB/s,而 eMMC 5.1 通常在 250~300MB/s。因此在中高端设备上,动态分区与 Virtual A/B 的收益更明显,因为快照(snapshot)和 COW 操作对随机写更敏感。
| 对比项 | eMMC 5.1 | UFS 2.1 / 3.1 |
|---|---|---|
| 接口 | 并行半双工 | 串行全双工 |
| 命令队列 | 有限 | 支持多队列 |
| 顺序读 | 约 250~300MB/s | 约 800MB/s~2GB/s |
| 随机读写 | 较弱 | 强,适合快照 |
| 典型定位 | 入门/中端 | 中高端/旗舰 |
二、GPT 分区表:分区的“地图”
Android 设备使用 GPT(GUID Partition Table)描述分区布局。GPT 位于存储起始位置,包含保护性 MBR、主 GPT 头和分区条目数组,每个分区条目记录起始 LBA、结束 LBA、分区名和 GUID。引导链(BootROM → SPL → ABL → kernel)正是通过读取 GPT 找到 boot、dtbo、vbmeta 等分区。
在传统 A/B 设备上,GPT 中会同时存在 boot_a、boot_b、system_a、system_b 等成对分区。而在动态分区方案中,GPT 不再为 system/vendor/product 单独划分物理分区,而是划分一个大的 super 分区,内部再用 LP(Logical Partition)元数据描述逻辑分区。这是理解动态分区的关键转折点。
# 查看设备分区表(需 root 或 fastboot 环境)
adb shell ls -l /dev/block/by-name/
# 典型输出片段
boot_a -> /dev/block/sda12
boot_b -> /dev/block/sda13
super -> /dev/block/sda14
userdata -> /dev/block/sda15
vbmeta_a -> /dev/block/sda10
vbmeta_b -> /dev/block/sda11
三、传统分区:boot、system、vendor 等
传统 Android 分区按职责划分,每个分区承载一类镜像:
- boot:包含 kernel 与 ramdisk(或 GKI 下的 generic ramdisk),负责早期初始化。
- dtbo:设备树叠加层,描述具体硬件配置。
- vbmeta:AVB(Android Verified Boot)元数据,校验各分区完整性。
- system:Android 框架与系统应用,只读。
- vendor:SoC 与硬件厂商驱动、HAL,只读。
- product:产品定制应用与配置,只读。
- userdata:用户数据,可读写,加密后挂载。
- metadata:加密元数据与部分系统状态,可读写。
这些分区在 GPT 中各自占据连续的 LBA 区间,大小在出厂时固定。system 分区一旦划分 2GB,即使实际镜像只有 1.2GB,剩余空间也无法被 vendor 使用——这正是动态分区要解决的浪费问题。
四、只读与可写分区概念
Android 将分区按挂载属性分为只读与可写两类。只读分区(system、vendor、product、boot 等)在正常启动时以 ro 挂载,受 AVB 校验保护,任何修改都会导致校验失败。可写分区(userdata、metadata、misc 等)以 rw 挂载,承载运行时状态和用户数据。
理解这一点对 Virtual A/B 至关重要:更新 system 时,系统不会直接覆盖 system_a,而是把变更写入 super 分区内的快照空间,待重启验证后再合并。只读属性保证了回滚能力。
五、案例与误区复盘
某中端设备采用 eMMC 5.1,system 分区固定 3GB,vendor 固定 1GB。OTA 升级时因 system 镜像增大 200MB 而失败,只能压缩镜像。若采用动态分区,super 分区内的空间可动态调整,system 可借用 vendor 的空闲空间,避免此类问题。
另一个误区是混淆“分区”与“文件系统”。分区是 GPT 描述的 LBA 区间,文件系统(ext4、f2fs、erofs)是在分区之上格式化的结构。只读分区常用 erofs 以节省空间,可写分区常用 f2fs 以优化闪存寿命。
小结:eMMC/UFS 决定物理性能,GPT 决定分区寻址,传统分区按职责固定划分,只读与可写属性由 AVB 与挂载策略共同约束。这些基础概念是理解动态分区“为什么要把 system/vendor 塞进 super”以及 Virtual A/B“为什么需要快照”的前提。