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 框架的基石。它们之间的依赖关系呈现为典型的“金字塔”结构。

EDK II 核心包依赖关系图 MdePkg 基础类型 / 协议 / PPI / GUID / 库类 MdeModulePkg DXE 基础架构 / 通用驱动 / 核心库实现 UefiCpuPkg CPU 驱动 / SMM / MP 服务 NetworkPkg TCP/IP / HTTP Boot / iSCSI 平台包(OvmfPkg / EmulatorPkg / 客户平台) 集成所有核心包,生成最终固件镜像 箭头方向表示“依赖”:下层包依赖上层包提供的接口与定义

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 下的网络功能)。

NetworkPkg 内部协议栈层次 UEFI 网络应用(HTTP Boot / iSCSI / PXE) TCP / UDP / IP4 / IP6 协议 ARP / DHCP / DNS / VLAN SNP(Simple Network Protocol) / UNDI

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。这种分层设计最大限度地提高了代码的可移植性和复用性。