3. 双系统启动流程与引导链
高通骁龙平台的双系统设备,其启动过程并不是“上电后直接进 Android 或 Linux”这么简单。它是一条严格分阶段、逐级验签、逐级移交控制权的引导链。理解这条链,是排查“卡在开机 Logo”“第二系统起不来”“切系统后黑屏”等问题的前提。本节按真实启动顺序,把 PBL、SBL、ABL、Hypervisor 以及双系统加载这几段串起来讲清楚。
一、引导链的整体分层
骁龙平台的启动可以概括为“固化代码 → 可加载引导 → 应用引导 → 虚拟化层 → 操作系统”。每一级只信任下一级的签名,验签通过才移交执行权,这就是所谓的信任链(Chain of Trust)。
- PBL(Primary Boot Loader):固化在芯片 ROM 中,不可修改。上电后最先运行,负责初始化最基础的时钟、DDR 的一部分,并从启动介质(UFS/eMMC)读取 SBL。
- SBL(Secondary Boot Loader):通常由 XBL(eXtensible Boot Loader)承担,运行在 TEE 之外的 EL3/EL2 环境,负责更完整的 DDR 初始化、加载并验签后续镜像。
- ABL(Application Boot Loader):基于 UEFI 框架,负责加载内核、设备树、启动参数,并决定“启动哪个系统”。
- Hypervisor:在 ABL 之后、操作系统之前介入,负责创建虚拟机、分配内存与外设,是双系统能同时/分时运行的关键。
- Guest OS:Android 与 Linux(或其他第二系统)作为两个 Guest 被 Hypervisor 管理。
下面这张图展示了从 PBL 到双系统加载的完整信号与控制流,注意每一级的“验签—移交”关系,以及 Hypervisor 在其中的分叉位置。
二、PBL 与 SBL:最底层发生了什么
PBL 是芯片出厂就固化好的,开发者无法改动。它做三件事:初始化最小可用的时钟与电源、从启动介质读取 SBL 镜像头、用芯片内固化的公钥验证 SBL 签名。验证通过后,PBL 把控制权交给 SBL。
SBL(在多数骁龙平台上就是 XBL)承担更重的初始化:完整的 DDR 训练与初始化、USB/存储控制器初始化、加载 TEE(如 QSEE)与后续镜像。SBL 会读取 GPT 分区表,找到 abl_a / abl_b 分区,验签后跳转。如果这一步失败,设备通常表现为“连上电脑只识别为 9008 端口”,也就是进入了 EDL 模式。
三、ABL:决定“启动哪个系统”的关键一级
ABL 基于 UEFI,是开发者最常接触的一级。它负责:
- 读取
boot_a/boot_b分区中的内核与 ramdisk; - 读取
dtbo、vbmeta完成设备树与验证启动校验; - 解析启动参数(cmdline),例如
androidboot.slot_suffix、androidboot.force_normal_boot; - 根据启动选择标志决定加载 Android 还是第二系统。
双系统设备通常会在 misc 分区或某个自定义分区中写入一个“启动目标”标志。ABL 读取该标志后,选择对应的 boot 分区。例如约定:
misc 分区偏移 0x2000 处 4 字节:
0x00000001 → 启动 Android(slot_a)
0x00000002 → 启动 Linux(slot_b)
0x00000000 → 默认启动 Android
这个标志由上层系统在“切换系统”时写入,重启后由 ABL 读取。理解这一点,就能明白为什么“切系统后必须重启”以及“切系统失败往往是 misc 写入没生效”。
四、Hypervisor 的介入与双系统加载
如果设备采用虚拟化方案实现双系统,ABL 在加载内核之前会先加载 Hypervisor 镜像(通常放在 hyp 或独立分区)。Hypervisor 运行在 EL2,负责:
- 创建两个 VM(Android 与 Linux),为每个 VM 分配独立的内存区域;
- 把外设(GPU、显示、USB、存储)按需分配给不同 VM,或做分时复用;
- 提供虚拟中断控制器与虚拟定时器;
- 根据 ABL 传入的启动标志,决定先启动哪个 VM、另一个 VM 是并行启动还是按需启动。
以典型配置为例,假设设备有 8GB 内存,可以这样划分(示例参数,非实测):
| 区域 | 起始地址 | 大小 | 用途 |
|---|---|---|---|
| Hypervisor | 0x80000000 | 256MB | 虚拟化层自身 |
| VM1 (Android) | 0x90000000 | 4GB | Android 系统 |
| VM2 (Linux) | 0x190000000 | 2GB | 第二系统 |
| 共享区 | 0x210000000 | 512MB | 跨系统数据交换 |
Hypervisor 启动后,先初始化 VM1 的 vCPU 并跳转到 Android 内核入口;Android 起来后,再通过 hypercall 或预设策略启动 VM2。两个系统通过共享内存或 virtio 设备通信。
五、完整启动路径的观察与判断
实际调试时,可以通过串口日志观察每一级的输出。典型日志顺序如下:
[PBL] Booting SBL from UFS LUN0...
[SBL] DDR init done, loading ABL...
[ABL] Loading boot_a, dtbo, vbmeta...
[ABL] Boot target = 0x00000002 (Linux)
[HYP] Hypervisor init, creating VM1/VM2...
[HYP] Starting VM2 (Linux)...
[Linux] Booting Linux kernel...
如果日志停在 [ABL] 之后没有 [HYP],说明 Hypervisor 镜像加载或验签失败;如果 [HYP] 出现但 VM2 没起来,则要检查 Linux 内核镜像、dtb 是否与分区匹配,以及内存分配是否冲突。掌握这条链的每一级职责,就能把“黑屏”“卡 Logo”“第二系统起不来”快速定位到具体阶段。