第1章:UEFI启动阶段总览与ABL介入点
1.1 本章概要
UEFI引导生态将固件启动分解为6个连续阶段:SEC → PEI → DXE → BDS → TSL → RT。ABL(Android Bootloader)作为OS Loader的一种实现,严格定义在BDS阶段加载并接管控制权。理解每个阶段的边界、职责和数据结构,是后续章节分析ABL入口、初始化、设备枚举与启动策略的基础。
1.2 UEFI六阶段职责速览
| 阶段 | 缩写 | 核心任务 | 主要输出 |
|---|---|---|---|
| 安全验证 | SEC | CPU/芯片组最低级初始化,建立临时内存(Cache-As-RAM) | 临时栈、引导向量表 |
| 前置EFI初始化 | PEI | 检测内存控制器、焊接内存参数,恢复平台核心状态 | 内存描述符 HOB 列表 |
| 驱动执行环境 | DXE | 加载并执行固件驱动(PCI、USB、SATA、NVMe、网络栈) | 完整的协议数据库(Protocol Database) |
| 启动设备选择 | BDS | 扫描启动选项,加载Boot Manager/OS Loader | 加载的启动映像(如ABL.efi) |
| 临时系统加载 | TSL | OS Loader执行,准备OS内核与硬件抽象 | ExitBootServices() 调用后的系统表 |
| 运行时服务 | RT | OS接管,UEFI进入只读运行时模式 | SetVirtualAddressMap() 后的GUID映射 |
1.3 ABL在BDS阶段的具体介入路径
ABL作为UEFI兼容的PE32+映像(.efi),被固化在boot分区(或ESP分区)并通过Boot Manager注册为启动项。当BDS遍历 EFI_GLOBAL_VARIABLE_BOOT_ORDER 中的路径时,遇到ABL入口则加载并执行其 efi_main()。该入口函数必须接收 EFI_HANDLE ImageHandle 和 EFI_SYSTEM_TABLE *SystemTable 两个参数——这是UEFI定义的标准Loader入口规范。
// ABL入口函数签名(EDK2风格)
EFI_STATUS
EFIAPI
efi_main (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
// 典型的Boot Manager启动项键值(NVRAM中存储)
BootOrder: 0001,0003,0000
Boot0000: "Windows Boot Manager" ... \EFI\Microsoft\Boot\bootmgfw.efi
Boot0001: "ABL Bootloader" ... \EFI\ABL\abl.efi
Boot0003: "UEFI Shell" ... \EFI\tools\Shell.efi
1.4 阶段边界与ABL的关键数据流
ABL从BDS接管时的运行时环境包含:
- 全局系统表(gST)——提供Boot Services、Runtime Services、控制台输出句柄和配置表。
- 启动服务表(gBS)——允许分配内存、加载协议、创建事件、操作句柄库;ABL在启动内核前通常调用
ExitBootServices()将控制权转移给OS。 - 当前加载的设备路径——表示ABL映像在Firmware File System或块设备中的位置。
关键指标:从SEC复位向量到ABL入口执行,典型现代平台耗时在300ms~800ms之间。其中DXE阶段的PCI枚举与USB栈初始化占据40%~60%的时间;BDS阶段(含ABL加载)通常控制在50ms以内。
调试提示:在EDK2的
DEBUG() 宏中可以插入断点日志来验证ABL被加载的时间点:
DEBUG((EFI_D_INFO, "ABL: Entered efi_main — ImageHandle=0x%p, SystemTable=0x%p\n", ImageHandle, SystemTable));
日志输出通过UART或帧缓冲区控制台可见,用于确认阶段切换是否成功。
常见陷阱:某些平台(尤其是ARM64)的
ExitBootServices() 必须在ABL的最终跳转前调用,而且只能调用一次。如果在ABL中对Boot Services分配了内存但未释放就调用 ExitBootServices(),会导致后续OS内核的内存映射出现空洞。
1.5 UEFI六阶段与ABL介入流程SVG
下图展示从SEC复位向量至ABL接管再到OS运行的完整阶段流,以及各阶段间传递的关键数据结构:
1.6 章节要点总结
- UEFI阶段从SEC到RT共6个,ABL在BDS阶段作为Boot Manager的启动映像被加载;
- ABL的入口必须与UEFI标准Loader规范兼容,接收
EFI_HANDLE和EFI_SYSTEM_TABLE; - DXE阶段耗时最久,适合在ABL早期打印启动计时来定位性能瓶颈;
ExitBootServices()只能在TSL阶段调用一次,调用后Boot Services全部失效;- 通过UART或串口日志可以在BDS/ABL边界插入
DEBUG()宏来验证阶段切换是否正常。