2. Android系统架构与启动流程

理解 Android 的安全模型,不能只看应用层的权限弹窗,更要看设备从上电到桌面出现之间,究竟有哪些代码被加载、哪些分区被挂载、哪些校验被触发。Android 的启动链路是一条严格分层的信任链:每一级都负责验证下一级,并把控制权交给下一级。分区与文件系统正是这条链路的物理载体——BootROM 固化在芯片里,Bootloader 位于 bootloader 分区,内核与 ramdisk 打包在 boot 分区,系统框架在 system 分区,厂商定制在 vendor 分区,用户数据在 data 分区。下面这张图展示了从 BootROM 到 Android Framework 的完整启动链路与各阶段对应的分区。

Android 启动链路:从 BootROM 到 Android Framework ① BootROM 芯片固化代码 验证 Bootloader 签名 不可修改 · 信任根 ② Bootloader bootloader 分区 初始化 DDR · 校验 boot fastboot / ABL ③ Kernel boot 分区 (kernel) 挂载 ramdisk 驱动 · SELinux 初始化 ④ init ramdisk 中 解析 init.rc 启动 servicemanager ⑤ Zygote system 分区 预加载类与资源 fork 应用进程 ⑥ SystemServer system 分区 AMS / PMS / WMS 核心系统服务 ⑦ Android Framework system 分区 Launcher 启动 桌面可见 ⑧ data 分区 用户数据 应用私有目录 加密挂载 分区与文件系统映射 bootloader boot (kernel+ramdisk) system (ext4/erofs) vendor (ext4) data (f2fs/ext4) misc / metadata 关键校验点 BootROM 验证 Bootloader 签名(信任根) Bootloader 验证 boot 分区 AVB 哈希 dm-verity 校验 system/vendor 只读分区

核心原理:信任链与分区职责

Android 启动的本质是一条信任链(Chain of Trust)。BootROM 是芯片出厂时固化的只读代码,它包含公钥,用于验证 Bootloader 的签名。如果签名不匹配,设备会拒绝启动或进入恢复模式。Bootloader 通过后,会初始化 DDR 内存、加载 boot 分区中的内核与 ramdisk,并利用 Android Verified Boot(AVB)校验内核的哈希值。内核启动后挂载 ramdisk,执行 init 进程,由它解析 init.rc 并启动 servicemanager、zygote 等关键服务。Zygote 预加载 Android 框架类与资源,随后 fork 出 SystemServer,SystemServer 再启动 ActivityManagerService、PackageManagerService 等核心服务,最终拉起 Launcher,用户看到桌面。

每个阶段都对应明确的分区。BootROM 不在任何可写分区中,它是硬件信任根;Bootloader 位于 bootloader 分区;内核与 ramdisk 打包在 boot 分区;系统框架代码位于 system 分区;厂商驱动与 HAL 位于 vendor 分区;用户数据位于 data 分区。这种划分不仅是为了模块化,更是为了安全隔离:system 和 vendor 通常是只读的,并通过 dm-verity 做块级完整性校验;data 可写,但默认启用文件级加密(FBE)。

方法流程:启动阶段与分区挂载顺序

  1. BootROM 阶段:上电后 CPU 从固定地址取指,执行芯片内固化的 BootROM 代码,验证 Bootloader 签名,加载并跳转。
  2. Bootloader 阶段:初始化内存、时钟、存储控制器,读取 boot 分区,校验 AVB 元数据,加载内核。
  3. Kernel 阶段:内核解压并初始化,挂载 ramdisk 作为临时根文件系统,启动 init 进程。
  4. init 阶段:解析 init.rc,挂载 system、vendor、data 等分区,启动 servicemanager、hwservicemanager、zygote。
  5. Zygote 阶段:预加载常用类与资源,创建 Socket 等待 AMS 请求,fork 应用进程。
  6. SystemServer 阶段:启动 AMS、PMS、WMS 等系统服务,注册 Binder 服务,最终启动 Launcher。

关键命令:查看启动阶段与分区挂载

# 查看当前挂载的分区与文件系统类型
adb shell mount | grep -E "system|vendor|data"

# 查看 AVB 校验状态
adb shell avbctl get-verity

# 查看 dm-verity 设备映射
adb shell dmctl list devices

# 查看 init.rc 中的挂载动作
adb shell cat /system/etc/init/hw/init.rc | grep mount

案例场景:一次开机卡在 Bootloader 的排查

某定制设备刷入新 boot 镜像后无法开机,屏幕停留在厂商 Logo。通过串口日志发现 Bootloader 输出 AVB: hash mismatch for boot。这说明 boot 分区的哈希与 AVB 元数据中记录的值不一致。原因是刷机时只替换了 boot 分区,没有同步更新 vbmeta 分区中的哈希描述符。解决方法是使用 fastboot flash vbmeta vbmeta.img 重新刷入与 boot 匹配的 vbmeta 镜像,或使用 fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img 关闭校验(仅限调试)。这个案例说明:启动链路上的每个分区都不是孤立的,AVB 把 boot、system、vendor 的哈希集中记录在 vbmeta 中,任何一处改动都会导致校验失败。

误区与复盘

常见误区一:认为 system 分区可随意修改。在启用 AVB 和 dm-verity 的设备上,system 是只读且块级校验的,直接写入会导致下次启动校验失败。正确做法是通过 OTA 或重新签名 vbmeta。

常见误区二:把 data 分区当成普通可写目录。data 分区默认启用文件级加密,应用私有目录受 SELinux 和加密密钥保护,直接 adb pull 可能拿到密文。

常见误区三:忽略 vendor 与 system 的接口边界。Android 8.0 以后引入 Treble,vendor 与 system 通过 HIDL/AIDL 交互,跨分区直接调用私有库会导致兼容性问题。

启动阶段与分区对照清单

启动阶段 执行主体 所在分区 文件系统/格式 安全机制
① BootROM 芯片固化代码 无(芯片内) ROM 公钥验证 Bootloader
② Bootloader ABL / LK bootloader raw / ext4 AVB 校验 boot
③ Kernel Linux 内核 boot gzip + dtb AVB 哈希校验
④ init init 进程 ramdisk cpio + gzip SELinux 策略加载
⑤ Zygote app_process system ext4 / erofs dm-verity
⑥ SystemServer system_server system ext4 / erofs dm-verity + SELinux
⑦ Framework Launcher system + data ext4 / f2fs FBE 文件级加密