10.3 Build Intermediate Images
10.3.1 Binary modules
Binary modules can be inserted into flash image in one of three ways. The first way is to use the FILE statement mentioned in Section 10.2.1. The second way uses an INF file listed in an FV section that describes binary files, like the one below:
[Defines]
INF_VERSION = 0x00010017
BASE_NAME = Logo
FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
MODULE_TYPE = USER_DEFINED
VERSION_STRING = 1.0
EFI_SPECIFICATION_VERSION = 0x00020000
[Binaries.common]
BIN|Logo.bmp|*
This INF file shows that binary file Logo.bmp
will be wrapped into the Logo
FFS file. This kind of INF file is specified using standard INF
statement in
an FV section of the FDF file.
The third method is to list a binary INF file containing the binary data in an FD section. If the binary specified in the INF file in this section is a BIN type (BIN|Filename.bin) the tools will not process the file and will be inserted at the offset specified for the region. This is equivalent of specifying a filename using the FILE statement, but with the binary file included from a binary module. If the file is another binary file type, such as an FSP binary containing PatchableInModule PCDs, the tools will be able to patch the binary file prior to adding it to the region.
10.3.2 Creating EFI Sections
Sections are produced by GenSec
tool using information in FDF file of what
type and content the section must contain. Section information in FDF file
belongs to two categories: either it is a leaf section, or it is an encapsulate
section. Encapsulation sections may contain one or more leaf sections or other
encapsulate section. The leaf section information appears in the FILE statement
in Section 10.2.1, the PE32 section type for the Fat.efi file. Normally this
information is enough for GenSec
tool, however, more information can be
specified by specifying a [Rule]
section in the FDF file. Rules in an FDF
file, look like:
[Rule.Common.SEC]
FILE SEC = $(NAMED_GUID) {
TE TE Align = 8 |.efi
RAW BIN Align = 16 |.com
}
The above rule stipulates that for file type SEC
(Security) in all build
architectures, the generated FFS must contain one TE section with 8-byte
alignment and one RAW
section with 16-byte alignment.
Different information can be specified for different section types:
[Rule.Common.PEIM]
FILE PEIM = $(NAMED_GUID) {
PEI_DEPEX PEI_DEPEX Optional |.depex
TE TE |.efi
UI STRING = "$(MODULE_NAME)" Optional
VERSION STRING = "$(INF_VERSION)" Optional BUILD_NUM = $(BUILD_NUMBER)
}
The above rule stipulates that for file type PEIM
in all build
architectures, the generated FFS may contain at most one optional PEI_DEPEX
section, must contain one TE section, and may contain at most one UI section
with the UI string set to the INF file's module name, and at most one VERSION
section.
10.3.3 Create an Apriori File
Some firmware volumes may require, an APRIORI
file to be created. An
APRIORI
file is a text file containing a GUID-named list of two or more
modules in the firmware volume. The modules will be invoked or dispatched in
the order they appear in the APRIORI
file. Only one of each PEI and DXE
Apriori file is permitted within a single Firmware Volume. Nested Firmware
Volumes are permitted, so Apriori
files are limited to specifying the files
(and not FVs) that are within the scope of the FV image in which it is located.
It is permissible for nested FV images to have one PEI and one DXE Apriori file
per FV. Scoping is accomplished using the curly "{}" braces.
The following example demonstrates an example of multiple APRIORI
files.
[Fv.Root]
DEFINE NT32 = $(WORKSPACE)/EdkNt32Pkg
DEFINE BuildDir = $(OUTPUT_DIRECTORY)/$(PLATFORM_NAME)/ $(TARGET)_$(TOOL_CHAIN_TAG)
APRIORI DXE {
FILE DXE_CORE = B5596C75-37A2-4b69-B40B-72ABD6DD8708 {
SECTION COMPRESS {
SECTION PE32 = $(BuildDir)/X/Y/Z/B5596C75-37A2-4b69-B40B-72ABD6DD8708-DxeCore.efi
SECTION VERSION "1.2.3"
}
}
INF VERSION = "1" ${NT32)/Dxe/WinNtThunk/Cpu/Cpu.inf
}
FILE FV_IMAGE = EF41A0E1-40B1-481f-958E-6FB4D9B12E76 {
SECTION GUIDED 3EA022A4-1439-4ff2-B4E4-A6F65A13A9AB {
SECTION FV_IMAGE = Dxe {
APRIORI DXE {
INF a/a/a.inf
INF a/c/c.inf
INF a/b/b.inf
}
INF a/d/d.inf
...
}
}
}
In the example above, there are three FFS files in the Fv.Root
and one
Encapsulated FV image. The build tools will create an APRIORI
file that will
dispatch the DXE_CORE
first, then the CPU module second. In the FV image,
named by the GUID EF41A0E
..., there will be at least five FFS files, the
APRIORI
file, named Dxe, listing the GUID names of modules a.inf
, c.inf
and b.inf
, which will be dispatched in this order. Once complete, the d.inf
module may be dispatched.
10.3.4 Create FFS Files from Leaf Sections
Section 9.2 shows the INF and FILE statements in an FDF to describe FFS files
that will be placed into FV. The FILE
statement is straight forward, letting
you know how an FFS file is organized, as it contains section information
within its scope. The INF
statement, on the other hand, will use a particular
RULE
that is determined by the module type in the INF and specified build
architecture.
The [Rule]
section of the FDF file is used to define custom rules. Custom
rules may also be applied to a given INF file listed in an [FV]
section. The
[Rule]
section is also used to define rules for module types that permit the
user to define the content of the FFS file - when an FFS type is not specified
by either PI or UEFI specifications.
The Rules can have multiple modifiers as shown below.
[Rule.$(ARCH).$(MODULE_TYPE).$(TEMPLATE_NAME)]
If no $(TEMPLATE_NAME)
is given then the match is based on $(ARCH)
and
$(MODULE_TYPE)
modifiers. BINARY is a reserved TEMPLATE_NAME as the default
rule name for binary modules. The $(TEMPLATE_NAME)
must be unique to the
$(ARCH)
and $(MODULE_TYPE)
. It is permissible to use the same
$(TEMPLATE_NAME)
for two or more [Rule]
sections only if the $(ARCH)
and
the $(MODULE_TYPE)
listed are different for each of the sections.
A [Rule]
section is terminated by another section header or the end of file.
The content of the [Rule]
section is based on the FILE
and section grammar
of the FV section. The difference is the FILE
referenced in the [RULE]
is a
MACRO
. The section grammar is extended to include an optional argument,
Optional
. The Optional
argument is used to say a section is optional, that
is to say if it does not exist it's O.K.
The generic form of the entries for leaf sections is:
<SectionType> <FileType> [Options] [{<Filename>} {<Extension>}]
When processing the FDF file, the rules apply in the following order:
- If
<SectionType>
not defined or not a legal name, then error - If
<FileType>
not defined or not a legal name, then error - If
[FilePath/FileName],
then:- Add one section to FFS with a section type of
<SectionType>
- Add one section to FFS with a section type of
Else:
Find all files defined by the INF file whose file type is
<FileType>
and add each one to the FFS with a section type of<SectionType>
Add files defined in
[Sources]
followed by files defined in[Binaries]
- If more than 1
UI
section in the final FFS file, then error - If more than 1
VER
section in the final FFS file, then error - If more than 1
DXE_DEPEX
section in final the FFS file, then error - If more than 1
PEI_DEPEX
section in the final FFS file, then error - If more than 1
SMM_DEPEX
section in the final FFS file, then error.
10.3.5 Create Encapsulation Sections
There are two types of encapsulation sections, a COMPRESSION
section and the
GUIDED section. A COMPRESSION
section uses standard UEFI
compression/decompression mechanisms. Other compression schemes must use the
GUIDED
form of encapsulation section.
The COMPRESS
encapsulation section uses the following format.
SECTION COMPRESS [type] {
SECTION EFI_SECTION_TYPE = FILENAME
SECTION EFI_SECTION_TYPE = "string"
}
The [type]
argument is optional, only EFI_STANDARD_COMPRESSION
is supported
by the PI specification. The current EDK enumerations for compression are a
violation of the PI specification, and SECTION GUIDED
must be used instead.
The EFI_SECTION_TYPE
and FILENAME
are required sub-elements within the
compression encapsulation section. for most sections, however both the VERSION
(EFI_SECTION_VERSION
) and UI (EFI_SECTION_USER_INTEFACE
) may specify a
string that will be used to create an EFI section.
The GUIDED
encapsulation section uses one of the following formats.
SECTION GUIDED $ (GUID_CNAME) [auth] {
SECTION EFI_SECTION_TYPE = FILENAME
SECTION EFI_SECTION_TYPE = "string"
}
SECTION GUIDED $ (GUID_CNAME) [auth] FILENAME
The required argument is the GUIDED
name followed by an optional auth
flag. If the argument auth
flag is specified, then the attribute
EFI_GUIDED_SECTION_AUTH_STATUS_VALID
must be set.
For statements that do not use a scoping notation, (the second SECTION
statement of the two listed above), if FILENAME
exists, the attribute
EFI_GUIDED_SECTION_PROCESSING_REQUIRED
must be set to TRUE
. The file
pointed to by FILENAME
is the data. If FILENAME
does not exist
EFI_GUIDED_SECTION_PROCESSING_REQUIRED
is cleared and normal leaf sections
must be used.
GenSec tool uses information from these encapsulated section definition as input parameters to generate the corresponding section format.