2. Android分区基础

Android 设备启动时,引导程序并不会直接加载一个“完整系统”,而是按照分区表逐块读取不同镜像,再把它们挂载到不同目录。理解分区,是理解 Android 系统集成、OTA 升级、Vendor 适配和 Treble 机制的第一道门槛。本节从分区作用、分区表与镜像格式、挂载流程三个层面展开,并给出实际排查思路。

一、核心分区及其职责

Android 的分区可以按“启动链”和“系统组成”两条线索来理解。启动链上的分区负责把系统拉起来,系统组成分区则决定 Android 框架、厂商定制和产品配置如何拼装。

  • boot / init_boot:包含 Linux 内核与通用 RAMDisk(或仅内核)。Android 12 起,通用 RAMDisk 从 boot 拆到 init_boot,boot 只保留内核,便于 GKI 与厂商模块解耦。
  • system:AOSP 核心框架、系统应用、系统库,是 Android 平台的主体,通常由 Google 或芯片厂商提供。
  • vendor:芯片平台与硬件相关的 HAL、固件、驱动、厂商守护进程,是 SoC 适配的核心区域。
  • product:产品差异化配置,如运营商定制、区域语言、预装应用、产品属性覆盖。
  • odm:ODM 厂商对 vendor 的进一步定制,常见于同一芯片平台的不同整机项目。
  • system_ext:从 system 拆出的可独立升级部分,承载部分系统扩展与框架服务。
  • vbmeta:存放 AVB 校验元数据,用于验证 boot、system、vendor 等镜像的完整性与签名。
  • userdata / metadata:用户数据与加密元数据,通常不参与系统镜像打包,但参与挂载与加密流程。

关键理解:system、vendor、product、odm、system_ext 共同构成 Android 的“分区化系统”。Treble 之后,system 与 vendor 通过稳定接口解耦,vendor 可以独立升级,这正是分区划分带来的工程价值。

二、分区表与镜像格式

分区表描述“磁盘上每个分区从哪里开始、到哪里结束、叫什么名字”。Android 常见分区表格式有 MBR、GPT,以及高通平台常见的 GPT + 专用分区表。分区表通常由引导程序解析,决定后续加载哪个分区。

镜像格式方面,常见的有以下几类:

格式 典型用途 特点
raw ext4 / f2fs system、vendor、userdata 可直接挂载,读写性能好,但镜像体积大
sparse image fastboot 刷写、OTA 包 对空洞做压缩,体积小,刷写时展开
super.img(动态分区) system、vendor、product、odm 等 多个逻辑分区共享一个物理分区,由 dm-linear 映射
boot.img / init_boot.img 内核与 RAMDisk 含 header、kernel、ramdisk、dtb 等段
vbmeta.img AVB 校验 存放哈希与签名,供 bootloader 验证

动态分区是 Android 10 之后的重要变化。物理上只有一个 super 分区,逻辑上通过 liblp 元数据把 system、vendor、product、odm 等映射为独立块设备。这样分区大小可以在 OTA 时动态调整,不必为每个分区预留固定空间。

# 查看设备分区表(需 root 或 adb shell)
adb shell ls -l /dev/block/by-name/
adb shell cat /proc/partitions

# 查看动态分区映射
adb shell dmctl list
adb shell lpdump

# 查看挂载情况
adb shell mount | grep -E "system|vendor|product|odm"

三、分区挂载流程

Android 启动时,分区挂载并不是一步到位,而是分阶段完成。第一阶段由 bootloader 和 init 完成,第二阶段由 init 的 mount 与 fs_mgr 完成,最终形成 /system、/vendor、/product、/odm 等目录。

  1. Bootloader 阶段:读取分区表,加载 boot / init_boot,校验 vbmeta,跳转到内核。
  2. 内核与 init 第一阶段:挂载 /system、/vendor 等必要分区,加载 fstab 中的条目。
  3. init 第二阶段:解析 init.rc,启动 vold、servicemanager、zygote 等核心服务。
  4. 动态分区映射:若使用 super 分区,fs_mgr 通过 dm-linear 把逻辑分区映射为块设备,再挂载到目标目录。
  5. AVB 校验:挂载前或挂载时校验分区哈希与签名,失败则进入 dm-verity 错误处理或重启到 recovery。
  6. 挂载完成:各分区以只读方式挂载,userdata 以加密方式挂载,系统进入正常启动流程。

fstab 是挂载的核心配置。它通常位于 /vendor/etc/fstab.<hardware> 或 /odm/etc/fstab.<hardware>,描述每个分区的设备节点、挂载点、文件系统类型、挂载选项和 AVB 校验方式。修改 fstab 往往意味着修改分区挂载行为。

四、典型场景与误区复盘

场景一:设备卡在开机动画,adb shell 无法进入。此时应优先检查 dmesg 与 logcat 中是否有 fs_mgr 挂载失败、dm-verity 校验失败或 avb 错误。常见原因是 vendor 分区与 system 分区版本不匹配,或 vbmeta 未正确签名。

场景二:OTA 升级后 vendor 与 system 接口不兼容。Treble 要求 vendor 与 system 通过稳定 HAL 交互,若升级只更新 system 而 vendor 未同步,可能出现 HAL 服务找不到或 linker 报错。此时应检查 vendor 分区版本与 system 的 compatibility_matrix 是否匹配。

场景三:动态分区调整后设备无法启动。常见原因是 super 分区元数据与逻辑分区大小不一致,或 lpdump 显示分区未正确映射。应使用 fastboot 重新刷写 super.img,并确认 BoardConfig.mk 中的分区大小配置一致。

常见误区:把 vendor 当成“厂商随便放东西的地方”。实际上 vendor 分区有严格的接口约束和 AVB 校验,随意修改可能导致设备无法通过验证启动。另一个误区是认为 system 和 vendor 可以随意混用不同版本,Treble 之后二者必须通过稳定接口通信,版本错配是集成阶段的高频问题。

五、分区关系总览

下图把启动链、分区表、镜像格式与挂载结果放在同一张关系图中,帮助建立整体认知。

Android 分区、镜像格式与挂载关系 启动链 Bootloader 读分区表 / 校验 vbmeta boot / init_boot 内核 + RAMDisk init 第一阶段 解析 fstab / 挂载 init 第二阶段 启动 zygote / vold AVB 校验 dm-verity / vbmeta 挂载完成 进入系统启动 分区表与镜像格式 GPT / MBR 分区表 by-name 映射块设备 raw ext4 / f2fs 可直接挂载 sparse image OTA / fastboot 刷写 super.img 动态分区 / dm-linear boot.img / init_boot.img kernel + ramdisk vbmeta.img AVB 哈希与签名 fstab 配置 挂载点 / 选项 / 校验 分区职责与挂载结果 system AOSP 框架 / 系统应用 挂载到 /system vendor HAL / 固件 / 驱动 挂载到 /vendor product 产品定制 / 预装应用 挂载到 /product odm ODM 定制 / 覆盖配置 挂载到 /odm system_ext 系统扩展 / 可独立升级 挂载到 /system_ext super 动态分区 承载 system/vendor/ product/odm 逻辑分区 userdata 用户数据 / 加密存储 挂载到 /data vbmeta AVB 校验元数据 校验 boot/system/vendor 挂载顺序:bootloader → init → fstab → dm-linear → AVB → 只读挂载 system / vendor / product / odm / system_ext 共同构成 Android 系统 启动链 分区表/镜像 system vendor product odm / vbmeta super 动态分区 userdata

掌握分区基础后,后续的 Vendor 适配、OTA 升级、AVB 校验和动态分区调整都会变得有据可依。建议在实际设备上执行 ls -l /dev/block/by-name/、lpdump 和 mount,把图中的每个分区与真实设备对应起来,形成自己的分区地图。