What Is EDK II and How to Build UEFI Firmware
This article provides an overview of EFI Development Kit II (EDK II), the industry-standard open-source implementation of the Unified Extensible Firmware Interface (UEFI). It explores the architecture of EDK II, breaks down its core components, and walks through the step-by-step process of using the kit to build bootable UEFI firmware images for virtualized environments and physical hardware platforms.
What Is EDK II?
EDK II (EFI Development Kit II) is an open-source, modern implementation of the UEFI and Platform Initialization (PI) specifications. Maintained under the TianoCore project, EDK II serves as the foundation for the firmware found in most modern PCs, servers, and embedded systems, effectively replacing legacy BIOS.
Written primarily in C, EDK II provides the low-level code required to initialize hardware components (such as the CPU, memory, and PCIe devices), enforce secure boot policies, and hand control of the system over to the operating system bootloader.
Core Components and File Structure
EDK II uses a modular, package-based architecture to organize source code and platform definitions. The primary configuration files include:
- INF Files (
.inf): Module Information files. These define individual modules (drivers, libraries, or applications), specifying source files, library dependencies, and target architectures. - DEC Files (
.dec): Package Declaration files. These define public interfaces, structures, and globally unique identifiers (GUIDs) that can be shared across packages. - DSC Files (
.dsc): Platform Description files. These orchestrate the build process by specifying which libraries, components, and drivers to compile for a specific platform. - FDF Files (
.fdf): Flash Description files. These define the layout and binary structure of the final firmware image, detailing how compiled modules are placed into firmware volumes (FV) and the final firmware device (.fd) file.
Common standard packages in the repository include
MdePkg (core definitions), MdeModulePkg
(standard drivers and services), and OvmfPkg (Open Virtual
Machine Firmware for QEMU/KVM).
How to Build UEFI Firmware with EDK II
Building firmware with EDK II involves preparing a toolchain, compiling EDK II's internal build tools, configuring the platform parameters, and running the build script to generate a firmware image.
1. Set Up the Build Environment
EDK II requires specific build tools and compilers. On Linux, this
typically includes gcc, g++,
make, python3, nasm,
uuid-dev, and git. On Windows, the process
requires Visual Studio, Python, and NASM.
Once the system prerequisites are installed, clone the EDK II repository along with its submodules:
git clone --recursive https://github.com/tianocore/edk2.git
cd edk22. Compile BaseTools
EDK II includes a set of custom tools called BaseTools,
written in C and Python, that parse configuration files
(.dsc, .fdf, .inf) and generate
code. To build them:
make -C BaseTools3. Configure the Environment
Source the environment setup script to initialize variables like
WORKSPACE, EDK_TOOLS_PATH, and default
paths:
source edksetup.shThis command automatically generates default configuration templates
inside the Conf/ directory, including
target.txt and tools_def.txt.
4. Define the Build Target
You can configure the target platform by editing
Conf/target.txt or by passing command-line arguments to the
build tool. The key parameters are:
- ACTIVE_PLATFORM: The
.dscfile of the platform you are compiling (e.g.,OvmfPkg/OvmfPkgX64.dsc). - TARGET: The build type, typically
DEBUGorRELEASE. - TARGET_ARCH: The processor architecture, such as
X64,IA32, orAARCH64. - TOOL_CHAIN_TAG: The compiler tag matching your
installed toolchain (e.g.,
GCC5orVS2019).
5. Execute the Build
Run the build command with the appropriate flags. For
example, to build an x86_64 OVMF image using GCC:
build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -b RELEASEDuring this step, the build system:
- Validates dependencies via
.dscand.decfiles. - Compiles individual modules specified by
.inffiles into.efibinaries. - Packages the
.efibinaries into firmware volumes based on the.fdffile. - Produces the final binary flash file (
.fd).
6. Locate and Test the Firmware
The generated binary is placed in the Build/ directory
(e.g., Build/OvmfX64/RELEASE_GCC5/FV/OVMF.fd).
You can test this virtual UEFI firmware using an emulator like QEMU:
qemu-system-x86_64 -bios Build/OvmfX64/RELEASE_GCC5/FV/OVMF.fd -net noneFor physical hardware, platform-specific packages (often supplied by
board vendors or silicon manufacturers) replace OvmfPkg,
and the resulting .fd image is flashed directly to the
target system's SPI flash memory.