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).
2.5.1 EFI SECTION Files
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.
Figure 7 General EFI Section Format (< 16MB)
Figure 8 General EFI Section Format for Large Size Sections.
Table 2 below lists the different architecturally defined section types, refer to the PI Specification, Volume 3 for additional details.
Table 2 EFI Section Types
Name | Description |
---|---|
EFI_SECTION_COMPRESSION |
Encapsulation section where other sections are compressed |
EFI_SECTION_GUID_DEFINED |
Encapsulation section where other sections have a format defined by a GUID. |
EFI_SECTION_DISPOSABLE |
Encapsulation section used during the build process but not required for execution. |
EFI_SECTION_PE32 |
PE32+ Executable Image |
EFI_SECTION_PIC |
Position-Independent Code. |
EFI_SECTION_TE |
Terse Executable image. |
EFI_SECTION_DXE_DEPEX |
DXE Dependency Expression. |
EFI_SECTION_VERSION |
Version, Text and Numeric (UNICODE) |
EFI_SECTION_SMM_DEPEX |
Leaf section type for determining the dispatch order for an SMM driver. |
EFI_SECTION_USER_INTERFACE |
User-Friendly name of the driver (UNICODE) |
EFI_SECTION_COMPATIBILITY16 |
DOS-style 16-bit executable. |
EFI_SECTION_FIRMWARE_VOLUME_IMAGE |
PI Firmware Volume Image. |
EFI_SECTION_FREEFORM_SUBTYPE_GUID |
Raw data with GUID in header to define format. |
EFI_SECTION_RAW |
Raw data (for example, a logo). |
EFI_SECTION_PEI_DEPEX |
PEI Dependency Expression. |
2.5.2 Firmware Files
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.
Figure 9 Typical FFS File Layout (<16MB)
Figure 10 File Header 2 layout for files larger than 16Mb
Table 3 lists the different FV file types architecturally defined in the PI Specification describing the content (FFS) of the Firmware Volume Data.
Table 3 Defined FV File Types
Name | Description | Code |
---|---|---|
EFI_FV_FILETYPE_RAW |
Binary data. | 0x01 |
EFI_FV_FILETYPE_FREEFORM |
Sectioned Data. | 0x02 |
EFI_FV_FILETYPE_SECURITY_CORE |
Platform core code used during the SEC phase. | 0x03 |
EFI_FV_FILETYPE_PEI_CORE |
PEI Foundation code. | 0x04 |
EFI_FV_FILETYPE_DXE_CORE |
DXE Foundation code. | 0x05 |
EFI_FV_FILETYPE_PEIM |
PEI Module (PEIM) | 0x06 |
EFI_FV_FILETYPE_DRIVER |
DXE driver. | 0x07 |
EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER |
Combined PEIM/DXE driver | 0x08 |
EFI_FV_FILETYPE_APPLICATION |
Application | 0x09 |
EFI_FV_FILETYPE_SMM |
Contains a PE32+ image that will be loaded into SMRAM. | 0x0A |
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE |
An embedded Firmware Volume Image. | 0x0B |
EFI_FV_FILETYPE_COMBINED_SMM_DXE |
Contains PE32+ image that will be dispatched by the DXE Dispatcher and will also be loaded into SMRAM. | 0x0C |
EFI_FV_FILETYPE_SMM_CORE |
SMM Foundation | 0x0D |
EFI_FV_FILETYPE_OEM_* |
OEM File Types | 0xC0..0xDF |
EFI_FV_FILETYPE_DEBUG_* |
Debug/Test File Types | 0xE0..0xEF |
EFI_FV_FILETYPE_FFS_* |
Firmware File System Specific File Types | 0xF0..0xFF |
EFI_FV_FILETYPE_FFS_PAD |
Pad file for FFS. | 0xF0 |
2.5.3 Firmware Volumes
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.
Figure 11 General FV Layout
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.
2.5.4 Special Files - VTF & BSF
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_GUID
is 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.
2.5.5 EFI_FV_FILETYPE_SECURITY Notes
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).
2.5.6 EFI_FV_FILETYPE_PEI_CORE Notes
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.
2.5.7 EFI_FV_FILETYPE_PEIM Notes
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 memory is 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 .reloc
section 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 .reloc
section 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 .reloc
section of PEIMs; PEIMs must specify the SHADOW = TRUE
in
the module's INF file to prevent this. Additional flags in the FDF file,
RELOCS_RETAINED
and RELOCS_STRIPPED
, are provided to over-ride stripping of
the .reloc
section.
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_DEPEX
section
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.
2.5.8 EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER Notes
Dual function (PEI/DXE) drivers (PEIMs that are coded to register for shadow)
must never have the .reloc
section 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.
2.5.9 DXE, BDS, TLS and AL Notes
Stripping the .reloc
section 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_DEPEX
section, a dependency
EFI_SECTION_DXE_DEPEX
section 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.