2.5 Generic Build Process
All code starts out as either C sources and header files, assembly sources and header files, UCS-2 HII strings in Unicode files, Virtual Forms Representation files or binary data (native instructions, such as microcode) files. Per the UEFI and PI specifications, the C and Assembly files must be compiled and linked into PE32/PE32+ images.
While some code is designed to execute only from ROM, most UEFI/PI modules are written to be relocate-able. These are written and built different. For example, Execute In Place (XIP) module code is written and compiled to run from ROM, while the majority of the code is written and compiled to execute from memory, which requires that the code be relocate able.
Some modules may also permit dual mode, where it will execute from memory only if memory is available, otherwise it will execute from ROM. Additionally, modules may permit dual access, such as a driver that contains both PEI and DXE implementation code. Code is assembled or compiled, then linked into PE32/PE32+ images, the relocation section may or may not be stripped and an appropriate header will replace the PE32/PE32+ header. Additional processing may remove more non-essential information, generating a Terse (TE) image.
The binary executables are converted into EFI firmware file sections. Each module is converted into an EFI Section consisting of an Section header followed by the section data (driver binary).
The general section format for sections less than 16MB in size is shown in Figure 7. Figure 8 shows the section format for sections 16MB or larger in size using the extended length field.
Table 2 below lists the different architecturally defined section types, refer to the PI Specification, Volume 3 for additional details.
Multiple EFI Sections are combined into a Firmware file (FFS) which consists of zero or more EFI sections. Each FFS consists of a FFS header plus the data. Figure 9 show the basic FFS File layout and Figure 10 shows the FFS File layout for files of 16MB or larger.
Table 3 lists the different FV file types architecturally defined in the PI Specification describing the content (FFS) of the Firmware Volume Data.
One or more FFS files are combined into a Firmware Volume (FV). The format for an FV is a header followed by an optional extended header, followed by zero or more FFS files. Figure 11 illustrates the layout of the FV.
Multiple FV files, each of which is just a logical firmware device, can be combined into a single FD image.
Within the context of modules, error messages within the code are written in plain text (English - ASCII) while messages that are displayed as part of the menu system or are stored for display later, are written in Unicode (UCS2-LE encoded) format. The UEFI/PI specifications define the structure for Human Interface Infrastructure (HII) as well as Visual Forms Representation (VFR). Vital Product Data (VPD) areas are also supported. The VPD format is unique to a platform implementation, and not defined by any specification. The EDK II build system does provide tools to generate VPD binary data files and text based map files that show the layout of the VPD PCDs.
The Volume Top File (VTF) is a file that must be located such that the last byte of the file is also the last byte of the firmware volume. Regardless of the actual file type, a VTF file must have the file name GUID of
EFI_FFS_VOLUME_TOP_FILE_GUID. The file name is a GUID, and
EFI_FFS_VOLUME_TOP_FILE_GUIDis the C define that is used by code and the build system in place of the GUID value.
The build system must be aware of this GUID and insert a pad file if necessary to guarantee the VTF is located correctly at the top of the firmware volume. This is also required for update and write operations.
The Bootstrap file is firmware file that is aligned to the top of the 32-bit address space. It is responsible for encapsulating the reset vector for the Itanium processor family and IA-32 It also contains fixed information, such as the PEIM return link for IA-32 and the entry point to the PEI core. Also of interest, it contains the base of the boot FV to enable successive module discovery in PEI.
The security section is always executed from ROM. For size optimization, the relocation (
.reloc) section of security executables may be stripped.
Security drivers run directly from flash need to have the BaseAddress re-based to the location the driver occupies in ROM prior to putting the driver into a Firmware Volume (FV).
The last step of the security section was to hand-off execution to the PEI foundation, which is typically executed in three phases, pre-memory, during memory detection and after memory is available. For size optimization, it is recommended to have the prememory and memory detection PEI core modules ROM resident, to have the PE32+ image converted to a terse image, and to have the .reloc section stripped. After memory is present, it is recommended that the PEI Core modules be shadowed in memory to speed up execution. These modules can also contain signing, decryption and/or decompression routines to handle verification, uncompressing or decrypting algorithms for GUIDED encapsulation sections or for compressed PEIMs and any remaining FVs that contain the DXE Foundation and all drivers and applications that are used in the DXE phase or later. The decompression must always occur after memory is available.
The PEI Foundation modules that run directly from flash, need to have the BaseAddress re-based to the location it occupies in ROM, prior to putting the driver into an FV. By default, the EDK II build system will strip the .reloc section of all modules.
There are three types of PEIMs:
- XIP must execute from ROM,
- PEIMs that must be executed from memory and
- PEIMs that will execute in from memory if memory is available. If no memoryis available, then the PEIMs can execute from ROM.
For PEIMs executed only from ROM, it is recommended that the image be converted to a terse image, the
.relocsection stripped for size optimization and module cannot be compressed - the images must be re-based to the location in ROM.
PEIMs that execute from memory must never have the .reloc section stripped, but may be converted to terse images and may be compressed.
PEIMs that are coded to register for shadow, i.e., they may be run from memory if memory is present, must not have the
.relocsection stripped. The EDK II build system uses a keyword,
SHADOW, in the module's INF file to indicate this mode, setting
SHADOW = TRUE. By default, the EDK II build system will strip the
.relocsection of PEIMs; PEIMs must specify the
SHADOW = TRUEin the module's INF file to prevent this. Additional flags in the FDF file,
RELOCS_STRIPPED, are provided to over-ride stripping of the
Like the PEI Foundation, it is recommended that PEIMs that are able to run from memory, be shadowed in memory to speed up execution.
Once the PEI Foundation has been loaded, PEIMs are dispatched, and if a PEIM is dependent on the existence of another PEIM, an
EFI_SECTION_PEI_DEPEXsection is used to define the dependency relationship. The PEI Foundation will use this section (if present in an FFS) to ensure the required PEIMs are available prior to dispatch.
Dual function (PEI/DXE) drivers (PEIMs that are coded to register for shadow) must never have the
.relocsection stripped. Additionally, compression of these modules may decrease the overall size of the FD image in hardware. Using the terse image format for drivers of this type is not permitted by the PI specification. For this class of driver, one PEI and/or one DXE dependency section can be added to the FFS file containing the image.
.relocsection from these modules and any UEFI applications is not recommended, but is allowed in certain cases. Additionally, these images cannot be converted to the terse format - only elements of the PEI Foundation (PEI Core) and PEIMs can be converted to use the terse format headers. Compression of the images is permitted, however, as most compression algorithms work better over a larger data set, it is recommended that the images be combined into a Firmware Volume, and the entire FV can be compressed.
The modules (after the DXE Foundation has been given control) may have other dependent drivers. Similar to the
EFI_SECTION_PEI_DEPEXsection, a dependency
EFI_SECTION_DXE_DEPEXsection may be required. These files are used by the DXE foundation to ensure required drivers are available when needed.
Another feature of some of these modules, the BDS is particular, has to do with the Human Interface Infrastructure (HII). The HII uses internal forms representation (IFR) coded files.