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)。
EFI Stub 引导下 ARM64 设备树传递路径 设备树传递路径(四阶段) 阶段1: 固件准备 加载 DTB → 填充配置表 阶段2: Stub 入口 定位 DTB → 验证 FDT 魔数 阶段3: 内核接管 early_init_dt_scan 阶段4: 设备树展开 unflatten_device_tree 调试关键点 检查 FDT 魔数 (0xd00dfeed) | 验证 DTB 地址对齐 | 确认 chosen 节点存在

1.3 课程目标

本课程旨在帮助嵌入式系统开发者、UEFI 固件工程师以及 Linux 内核调试人员,系统掌握 EFI Stub 引导下 ARM64 设备树的完整传递路径与调试方法。完成本课程后,学员应能:

  1. 理解 EFI Stub 的启动流程:包括 Stub 入口、UEFI 配置表遍历、设备树地址获取与验证。
  2. 掌握设备树在内核中的解析机制:从 early_init_dt_scan 到 unflatten_device_tree 的完整链路。
  3. 熟练使用调试工具:包括 QEMU + GDB 断点调试、efi_debug 早期输出、设备树转储与反编译。
  4. 独立排查常见故障:如 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-6章 Stub原理/DT基础 传递路径篇 第7-14章 源码/加载/解析 调试工具篇 第15-22章 QEMU/GDB/转储 故障排查篇 第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 入口处设置断点。

1.6 本章小结