目录
前言
EDK II 架构
配置文件
结语
前言
基本输入输出系统 (Basic Input Output System, BIOS) 最早由 IBM(International Business Machines Corporation) 公司于1981年提出并开发,后来成为个人计算机(PC)的标准固件接口。但受限于传统BIOS (Legacy BIOS) 的诸多缺点,如支持的硬盘容量不超过2T,安全性和灵活性也不够,Intel 在2005年提出了新一代固件接口标准——统一可扩展固件接口(Unified Extensible Firmware Interface, UEFI),一言不合,便革了Legacy BIOS的老命。
UEFI并非凭空出现,而是在Legacy BIOS的基础上发展而来,提供了更多的功能和灵活性。所以,即使在UEFI中,也有CSM Mode (Compatibel Support Mode),以实现对Legacy BIOS的支持,让某些老机器能通过UEFI来引导。
目前,UEFI 已经逐渐取代了 Legacy BIOS。许多新的计算机和主板上都采用了UEFI作为固件接口。UEFI相对于BIOS具有更强大的功能和更好的兼容性,支持更大的硬盘容量、启动速度更快、图形界面更友好等优点。 UEFI最新的Spec已经更新到了2.10。但UEFI Spec只是对UEFI进行了规范定义,并未给出具体实现,代码实现这部分工作则是由 TianoCore 社区来实现,其源代码维护在 GitHub 网站。
UEFI 最早的实现是EDK I (EFI Development Kit I),现在已经进化到 EDK II。EDK II 是一个UEFI/PI Spec的一个固件开发环境,具有丰富的 features,和跨平台等特点。
作为一个BIOS工程师,要想深入理解UEFI的设计原理和细节,还是得结合UEFI/PI Spec和EDK II 源码进行学习。
本文主要对 EDK II 的架构做一个简单、粗浅的介绍,算是Kick off,后面再慢慢深入了解,学习EDK II 的某个具体 Package。
EDK II 架构
为了更好地实现UEFI的可扩展性(Extendibility),EDK II 引入了 包(Package)、模块(Module) 的概念。整个EDK II 由许多 Packages 和配置文件组成,也即: EDK II = Packages + Configuration Files.
笔者Download 的EDK II 包含以下 Packages:
通常,EDK II 的 Package 具有以下特点:
- 最小的发布单元(distribution)
- 包含零个或多个模块(modules)
- 包含一个包声明文件(.dec),以及可能包含一个平台描述文件(.dsc)
- 一个包里面的模块可能依赖于其它包
下表对其中一些 Packages 的功能做了简单介绍。
ArmPkg | 针对Arm架构的固件开发工具包,提供相关的Protocols。 |
ArmPlatformPkg | 提供了一组适用于Arm架构平台的特定固件和驱动程序。 |
ArmVirtPkg | 用于在Arm架构的虚拟化环境中构建和运行UEFI固件。 |
BaseTools | 提供了一系列用于开发、构建和调试UEFI固件的命令行工具集合,包括编译器、链接器、工具链和脚本等。由于BaseTools是基于Python编写的,所以这些工具与平台无关,可以在不同的操作系统上运行,并且支持多种编译器和构建配置。 |
CryptoPkg | 为UEFI固件提供安全的加密和密码学功能,以支持安全启动,固件验证,密钥管理和数据保护等应用场景。它包含了一些常见的密码学算法和协议的实现,如AES,RSA,SHA和TLS等。 |
DynamicTablesPkg | 提供了一种在UEFI固件中动态生成ACPI表格的机制。 |
EmbeddedPkg | 提供了用于嵌入式系统的UEFI固件的开源平台,它包括了一些常用的嵌入式功能和驱动程序的实现,如GPIO,SPI,I2C,USB和网络等。 |
EmulatorPkg | UEFI固件模拟器,可用于非硬件环境中运行UEFI固件。EmulatorPkg 提供了一个基于 QEMU 的 UEFI 固件模拟器,可用于在 PC 上模拟 UEFI 固件的运行环境。它包括了一个模拟的 BIOS 和 UEFI 固件环境,支持 UEFI 规范和 ACPI 规范,并提供了常用的 UEFI Shell 和 Shell 库命令等。开发人员可以在 PC 上运行 UEFI 固件,进行Protocol调用、设备初始化和驱动程序调试等操作。 |
FatPkg | FatPkg 提供了一些库和驱动程序,用于在 UEFI 固件中对 FAT 文件系统进行操作。它包括了一些常用的文件系统操作,如文件读写、目录遍历、簇分配和空间管理等。此外,FatPkg 还提供了支持 FAT12、FAT16 和 FAT32 文件系统的驱动程序和工具,以方便使用和调试。 |
FmpDevicePkg | Firmware Management Protocol,FmpDevicePkg 提供了用于开发和支持 FMP 设备的库和驱动程序。它包括了 FMP 协议的实现和相关的功能接口,以及用于固件更新管理的驱动程序和工具。开发人员可以使用 FmpDevicePkg 来构建支持 FMP 协议的设备或固件功能,并实现固件更新和管理的功能。 |
IntelFsp2Pkg | Firmware Support Package 2(FSP 2),通过使用 IntelFsp2Pkg,开发人员能够快速搭建基于 Intel 平台的 UEFI 固件,并根据硬件特性和要求进行定制和配置。IntelFsp2Pkg 还提供了一些工具和示例代码,用于帮助开发人员进行 FSP 2 的集成和调试。 |
MdeModulePkg | MdeModulePkg 中包含了若干模块,如文件系统、网络、媒体、安全等,以及 UEFI 标准规范定义的模块,如 UEFI Boot 和 UEFI Runtime Services。这些模块提供了 UEFI 固件开发中常用的功能和服务,如文件读写、网络传输、音视频播放、加密解密等。 |
MdePkg | MdePkg 包含了 UEFI 规范定义的各种模块,如 UEFI Core、UEFI Boot、UEFI Runtime Services 等。这些模块实现了 UEFI 规范中定义的接口和功能,包括启动引导、运行时服务、协议和驱动程序框架等。MdePkg 是 EDK II 的核心部分,其他的 Pkg(Package)也可以依赖和扩展 MdePkg 中的模块和功能。 |
NetworkPkg | NetworkPkg 中包含了若干模块,如 TCP/IP 协议栈、DHCP 客户端、SNMP 代理、网卡驱动程序等,以及与网络相关的应用程序和工具,如 TFTP 客户端和服务器、FTP 客户端、HTTP 客户端和服务器等。 |
OvmfPkg | OVMF(Open Virtual Machine Firmware)是一个开源项目,旨在为虚拟机提供符合 UEFI 规范的 BIOS 替代方案。OVMFPkg 中的代码可以用于构建支持 UEFI 的虚拟机环境,以便在虚拟机中运行基于 UEFI 的操作系统(如 Windows、Linux 等) |
PcAtChipsetPkg | PcAtChipsetPkg 中包含了各种针对传统 PC 架构芯片组的 UEFI 驱动程序,如 Intel H55、P55 和 Z68 芯片组、AMD 970 和 990FX 芯片组等。这些驱动程序实现了 UEFI 规范定义的接口和功能,以支持 UEFI 引导启动、硬件访问和系统配置等操作。 |
PrmPkg | PrmPkg(Platform ROM Manifest Package)为 UEFI 固件中的平台固化设置(Platform ROM Manifest)提供了支持。平台固化设置是一组包含在 UEFI 固件中的配置数据,用于指定特定平台的默认配置和行为。 |
RedfishPkg | RedfishPkg 中的驱动程序和应用程序实现了 UEFI 固件中与 Redfish 标准兼容的功能和接口。它们可以将服务器硬件资源的信息发布为 Redfish API,让管理者可以通过使用标准的 HTTP 请求和响应来访问和控制服务器。 |
SecurityPkg | SecurityPkg 中包含了一系列用于增强 UEFI 固件安全性的组件,包括 Secure Boot 驱动程序、认证和授权模块、数字签名工具、加密算法库等。 |
ShellPkg | ShellPkg 中的驱动程序和应用程序可以在 UEFI 固件中或操作系统环境中实现 Shell 环境及其相关命令和脚本的功能。它们可以加载、执行和管理 Shell 命令和脚本,并提供标准 I/O 控制和文件系统访问等功能。 |
SignedCapsulePkg | SignedCapsulePkg 添加了一个包含数字签名的验证步骤,以增强 Capsule 包的安全性。它使用数字证书来验证 Capsule 包的完整性和适用性,并防止未经授权的 Capsule 包加载和运行。 |
SourceLevelDebugPkg | SourceLevelDebugPkg 中包含了一些调试驱动程序和工具,用于与调试器交互并实现源代码级别的调试功能。这些驱动程序和工具可以与支持源代码级别调试的调试器一起使用,例如 EDK II Debug Agent 或其他兼容的调试器。 |
StandaloneMmPkg | StandaloneMmPkg 旨在为开发人员提供一种在 UEFI 固件中实现内存管理的解决方案。它提供了一个独立的内存管理器模块(Standalone Memory Manager,SMM),该模块可以在 UEFI 固件的 SMM 环境中运行。 |
UefiCpuPkg | UefiCpuPkg 提供了一些 CPU 相关的驱动程序和库,用于控制和管理 CPU 行为,如电源管理、多核处理、浮点运算、高级定时器等。它也提供了一些基本的 CPU 功能接口和协议,如 EFI CPU 协议、EFI MP 服务等。 |
UefiPayloadPkg | UefiPayloadPkg 的目标是将 UEFI (统一的可扩展固件接口)引入嵌入式系统中,以提供更多的功能和灵活性。它提供了一个 UEFI 负载模块,可以与主引导加载程序(如 Coreboot 或 U-Boot)一起使用,从而构建出支持 UEFI 标准的完整系统。 |
UnitTestFrameworkPkg | UnitTestFrameworkPkg 旨在帮助开发人员编写和运行单元测试,以验证 UEFI 驱动程序、应用程序或其他模块的正确性和稳定性。它提供了一套功能丰富的工具和库,可用于构建测试用例、执行测试、收集和分析测试结果。 |
配置文件
配置好 EDK II 的环境后,执行Build指令,会在EDK II 目录下生成一个Build文件夹,该文件夹里保存了Build生成后的Image和其它文件。
关于 EDK II 的硬件平台配置,则是通过 Conf 文件夹下面的相关文件来实现,主要有配置三个文件:
- build_rule.txt: 编译规则配置,保持默认就好,基本无需改动。
- tools_def.txt : 定义了一些编译相关的工具。
- target.txt : 目标硬件平台配置。
ACTIVE_PLATFORM = EmulatorPkg/EmulatorPkg.dsc ## 配置当前编译的有效平台,通过指定*.dsc文件实现(.dsc描述了具体某个平台的内容)
TARGET = DEBUG ## 模式,DEBUG/RELEASE
TARGET_ARCH = X64 ## 目标平台的架构,比如IA32,X64
TOOL_CHAIN_CONF = Conf/tools_def.txt ## 指的编译时的工具配置文件
TOOL_CHAIN_TAG = VS2019 ## 指定编译用到的编译器,比如VS2019
MAX_CONCURRENT_THREAD_NUMBER = 15 ## 设置编译时最大的并行线程数量
BUILD_RULE_CONF = Conf/build_rule.txt ## 指定编译规则文件
结语
好,本文的内容就到这里,后面将会针对EDK II 的 Package、Module进行详细介绍。最后,欢迎关注笔者的知乎账号(@月初),第一时间获取最新,最全的文章内容。