3. EDK II 目录结构解析:核心包的作用与关系
EDK II 的源码仓库(edk2)采用模块化、层次化的目录结构。理解根目录及各核心包的职责与依赖关系,是进行 UEFI 固件开发的基础。本章将逐一解析 edk2 根目录及最重要的几个核心包。
3.1 edk2 根目录结构概览
edk2 根目录下主要包含构建配置文件、工具链脚本、平台描述文件(.dsc)以及按功能划分的各个 Package(包)。一个典型的根目录结构如下:
| 目录/文件 | 作用 |
|---|---|
| edk2/ | 根目录,包含全局构建入口 |
| ├── Conf/ | 构建工具配置文件(target.txt, tools_def.txt) |
| ├── BaseTools/ | 编译工具链源码(GenFw, GenFds, Ecc 等) |
| ├── MdePkg/ | 基础数据类型、协议、PPI、GUID 定义(硬件无关层) |
| ├── MdeModulePkg/ | 核心模块实现(DXE 基础架构、UEFI 驱动模型、通用库) |
| ├── UefiCpuPkg/ | CPU 架构相关代码(SMM、MP 服务、CpuDxe) |
| ├── NetworkPkg/ | 网络协议栈实现(TCP/IP, HTTP Boot, iSCSI) |
| ├── PcAtChipsetPkg/ | 传统 PC 芯片组驱动(8259 PIC, 8254 Timer) |
| ├── ShellPkg/ | UEFI Shell 应用程序及命令实现 |
| ├── SecurityPkg/ | 安全功能(TPM, Secure Boot, Measured Boot) |
| ├── OvmfPkg/ | QEMU 虚拟平台固件(OVMF) |
| └── EmulatorPkg/ | Windows/Linux 模拟器平台(用于调试) |
提示:Package(包)是 EDK II 中代码组织的基本单元,每个包包含一个
.dec(声明文件)、一个 .dsc(包级构建文件)以及多个模块(Module)。包之间通过 .dec 文件导出的协议、PPI 和 GUID 进行依赖。
3.2 核心包的作用与依赖关系
在众多包中,MdePkg、MdeModulePkg、UefiCpuPkg 和 NetworkPkg 构成了 EDK II 框架的基石。它们之间的依赖关系呈现为典型的“金字塔”结构。
3.3 MdePkg:基础定义层
MdePkg(Module Development Environment Package)是整个 EDK II 框架的基石,它不依赖任何其他包。其核心职责包括:
- 基础数据类型:定义
UINTN、UINT64、EFI_STATUS、EFI_GUID等跨架构类型。 - UEFI 规范接口:声明所有 UEFI 协议(如
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL)、PPI(PEI 阶段接口)和 GUID。 - 库类(Library Class):定义库的接口原型,如
BaseLib、BaseMemoryLib、PrintLib。 - 头文件:提供
IndustryStandard/(行业标准寄存器定义)、Protocol/、Ppi/等子目录。
关键文件:
MdePkg.dec 声明了所有公开的协议、PPI、GUID 和库类;MdePkg.dsc 定义了包级别的构建选项。
3.4 MdeModulePkg:核心实现层
MdeModulePkg 是 EDK II 中最大的包,它实现了 UEFI 规范中的大部分核心功能。它依赖于 MdePkg,并为上层包提供运行时服务。
| 子模块/目录 | 功能说明 |
|---|---|
| Core/Dxe/ | DXE 基础架构核心(DXE Dispatcher、DXE Core、Global Coherency Domain) |
| Core/PiSmmCore/ | SMM(系统管理模式)核心 |
| Bus/ | 总线驱动(PCI、USB、AHCI、NVMe 等) |
| Universal/ | 通用驱动(Console、DiskIo、Fat、Partition 等) |
| Library/ | 通用库实例(如 DxeServicesLib、UefiBootServicesTableLib) |
| Include/ | 包内私有头文件及扩展协议定义 |
注意:MdeModulePkg 中的代码通常与具体硬件平台无关,但会假设存在标准的 UEFI 运行时环境。平台定制时,应优先考虑在此包中寻找可复用的驱动或库。
3.5 UefiCpuPkg:CPU 架构专属层
UefiCpuPkg 封装了与 CPU 架构紧密相关的功能,主要面向 x86/x64 平台。它依赖于 MdePkg 和 MdeModulePkg。
- CpuDxe:CPU 架构协议驱动,提供缓存控制、中断管理、MP 服务(多核启动)。
- SmmCpuFeaturesLib:SMM 模式下 CPU 特性抽象库。
- MpInitLib:多处理器初始化库,用于启动 Application Processor(AP)。
- RegisterCpuFeaturesLib:CPU 特性注册与管理库。
UefiCpuPkg 的代码通常需要根据具体的 CPU 型号(如 Intel 或 AMD)进行微调,但框架提供了清晰的库接口来隔离差异。
3.6 NetworkPkg:网络协议栈层
NetworkPkg 实现了完整的 UEFI 网络协议栈,支持 PXE 启动、HTTP Boot、iSCSI 等网络启动方式。它依赖于 MdePkg、MdeModulePkg 以及 UefiCpuPkg(用于 SMM 下的网络功能)。
3.7 包间依赖关系总结
下表总结了四个核心包之间的依赖关系及典型使用场景:
| 包名 | 依赖的包 | 典型模块示例 | 是否与硬件相关 |
|---|---|---|---|
| MdePkg | 无 | BaseLib, UefiLib |
否(纯定义) |
| MdeModulePkg | MdePkg | DxeCore, FatPei |
部分(总线驱动) |
| UefiCpuPkg | MdePkg, MdeModulePkg | CpuDxe, MpInitLib |
是(CPU 架构) |
| NetworkPkg | MdePkg, MdeModulePkg, UefiCpuPkg | TcpDxe, HttpBootDxe |
部分(网卡驱动) |
开发建议:在编写一个新的 UEFI 驱动时,优先从 MdePkg 中查找所需的数据类型和协议定义;如果涉及通用功能(如文件系统、控制台),则从 MdeModulePkg 中寻找现成的库或驱动;CPU 特定优化放在 UefiCpuPkg;网络功能则依赖 NetworkPkg。这种分层设计最大限度地提高了代码的可移植性和复用性。