1. 课程导论:EFI Stub 与设备树传递的背景、课程目标与学习路径
1.1 背景:为什么需要 EFI Stub 与设备树传递?
在 ARM64 服务器与嵌入式领域,UEFI(统一可扩展固件接口)已成为标准固件层。传统上,Linux 内核通过 UEFI 运行时服务获取硬件拓扑信息,但 ARM64 平台依赖设备树(Device Tree, DT)来描述非枚举型硬件。EFI Stub 机制允许内核镜像自身充当 UEFI 应用程序,在引导阶段直接与固件交互,并完成设备树的加载与传递。
这一机制解决了三个核心痛点:
- 固件与内核的解耦:设备树由 bootloader 或 UEFI 固件准备,内核无需内置硬件描述。
- 引导流程简化:EFI Stub 消除了对传统 bootloader(如 GRUB)的依赖,内核可直接从 UEFI 启动。
- 调试复杂性:设备树传递路径涉及多个阶段(固件 → Stub → 内核),任何环节出错都会导致引导失败。
关键概念:EFI Stub 是嵌入 Linux 内核镜像中的一段 UEFI 兼容代码,它在 UEFI 固件与内核主程序之间充当“胶水层”,负责解析 UEFI 配置表、加载设备树、设置页表并最终跳转到内核入口。
1.2 设备树传递路径概览
设备树从固件到内核的完整传递路径可分为四个阶段,每个阶段都有明确的接口与数据结构:
| 阶段 | 执行者 | 关键操作 | 输出 |
|---|---|---|---|
| 1. 固件准备 | UEFI 固件 / Bootloader | 从存储介质加载 DTB,填充 UEFI 配置表 | EFI_DTB_TABLE 配置表项 |
| 2. Stub 入口 | EFI Stub (efi_stub_entry) | 定位配置表,获取 DTB 地址,验证 FDT 魔数 | 设备树物理地址 |
| 3. 内核接管 | early_init_dt_scan | 解析 FDT 头部,扫描 chosen/memory 节点 | 内存布局、启动参数 |
| 4. 设备树展开 | unflatten_device_tree | 将扁平设备树转换为内核 device_node 树 | 完整的设备树结构 |
调试切入点:阶段 2 是 EFI Stub 调试的核心区域。如果内核在引导早期崩溃且无控制台输出,应优先检查 Stub 是否成功获取了 DTB 地址以及 FDT 魔数是否正确(应为 0xd00dfeed)。
1.3 课程目标
本课程旨在帮助嵌入式系统开发者、UEFI 固件工程师以及 Linux 内核调试人员,系统掌握 EFI Stub 引导下 ARM64 设备树的完整传递路径与调试方法。完成本课程后,学员应能:
- 理解 EFI Stub 的启动流程:包括 Stub 入口、UEFI 配置表遍历、设备树地址获取与验证。
- 掌握设备树在内核中的解析机制:从 early_init_dt_scan 到 unflatten_device_tree 的完整链路。
- 熟练使用调试工具:包括 QEMU + GDB 断点调试、efi_debug 早期输出、设备树转储与反编译。
- 独立排查常见故障:如 DTB 地址无效、FDT 魔数错误、chosen 节点缺失、内存映射冲突等。
前置要求:学员应具备 ARM64 汇编基础、UEFI 协议基本概念以及 Linux 内核编译与设备树语法(DTS)的初步了解。本课程不从头讲解设备树语法或 UEFI 规范,而是聚焦于传递路径与调试实践。
1.4 学习路径与章节规划
课程共分为 30 章,按递进关系组织为五个模块:
| 模块 | 章节范围 | 核心内容 |
|---|---|---|
| 基础篇 | 第 1–6 章 | EFI Stub 原理、设备树基础、UEFI 配置表、启动协议 |
| 传递路径篇 | 第 7–14 章 | Stub 源码分析、DTB 加载、内核早期解析、内存映射 |
| 调试工具篇 | 第 15–22 章 | QEMU 仿真、GDB 断点、efi_debug、设备树转储与反编译 |
| 故障排查篇 | 第 23–27 章 | 常见引导失败模式、日志分析、补丁与修复 |
| 实战与进阶 | 第 28–30 章 | 自定义 DTB 注入、安全启动影响、ACPI 与设备树共存 |
1.5 实验环境准备
为完成本课程的调试实验,建议准备以下环境:
- 硬件:ARM64 开发板(如 Raspberry Pi 4B、Jetson Nano)或 x86 主机配合 QEMU 模拟。
- 软件:Linux 内核源码(v6.x 以上)、UEFI 固件(EDK II 或 U-Boot UEFI)、设备树编译器(dtc)。
- 调试工具:GDB(支持 ARM64 交叉调试)、QEMU(带 -s 与 -S 选项)、串口终端(minicom/picocom)。
快速启动命令(QEMU 模拟):
qemu-system-aarch64 -M virt -cpu cortex-a72 -m 2G \
-bios QEMU_EFI.fd -kernel arch/arm64/boot/Image \
-append "console=ttyAMA0 earlycon" -nographic \
-s -S
该命令启动 QEMU 并暂停等待 GDB 连接,便于在 EFI Stub 入口处设置断点。