? Figure 1. The Firmware Volume Format
In firmware development, binary file has its firmware layout following the Platform-Initialization Specification. Thus, operation on FV file / FFS file (Firmware File) is an efficient and convenient way for firmware function testing and developing. FMMT Python tool is used for firmware files operation.
The FMMT tool is capable of:
Parse a FD (Firmware Device) / FV (Firmware Volume) / FFS (Firmware Files)
Add a new FFS into a FV file (both included in a FD file or not)
Replace an FFS in a FV file with a new FFS file
Delete an FFS in a FV file (both included in a FD file or not)
Extract the FFS from a FV file (both included in a FD file or not)
Document |
---|
UEFI Platform Initialization (PI) Specification |
When independent use the FMMT Python Tool, the following files and settings are required:
GuidTool executable files used for Decompress/Compress Firmware data.
Environment variables path with GuidTool path setting.
When use the FMMT Python Tool with Build System:
If only use Edk2 based GuidTool, do not need other preparation.
If use other customized GuidTool, need prepare the config file with GuidTool info. The syntax for GuidTool definition shown as follow:
ToolsGuid ShortName Command
-- Example: 3d532050-5cda-4fd0-879e-0f7f630d5afb BROTLI BrotliCompress
-v < Inputfile > < Outputfile > -l < LogFileType > -c < ConfigFilePath >
-a < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < Outputfile >
-d < Inputfile > < TargetFvName/TargetFvGuid > < TargetFfsName > < Outputfile >
? -r < Inputfile > < TargetFvName/TargetFvGuid > < TargetFfsName > < NewFfsFile > < Outputfile >
-e < Inputfile > < TargetFvName/TargetFvGuid > < TargetFfsName > < Outputfile >
FMMT Python Tool uses the NodeTree saves whole Firmware layout. Each Node have its Data field, which saves the FirmwareClass(FD/FV/FFS/SECTION/BINARY) Data. All the parse/add/delete/replace/extract operations are based on the NodeTree (adjusting the layout and data).
A whole NodeTree saves all the Firmware info.
Parent & Child relationship figured out the Firmware layout.
Each Node have several fields. ?Data? field saves an FirmwareClass instance which contains all the data info of the info.
The NodeTree will be created with parse function. When parse a file, a Root Node will be initialized firstly. The Data split and Tree construction process is described with an FD file shown as ?Figure 2. The NodeTree format?:
A Root Node is initialized.
Use the ?FV Signature? as FV key to split Whole FD Data. ?FV0?, ?FV1?, ?FV2?? Node created.
After FV level Node created, use the ?Ffs Data Size? as FFS key to split each FV Data. ?Ffs0?...Node created.
After FFS level Node created, use the ?Section Data Size? as Section key to split each Ffs Data. ?Section0?...Node created.
If some of Section includes other Sections, continue use the ?Section Data Size? as Section key to split each Section Data.
After all Node created, the whole NodeTree saves all the info. (Can be used in other functions or print the whole firmware layout into log file)
? Figure 2. The NodeTree format
As 3.1.1, Each Node is created by data split and recognition. To extend the NodeTree usage, Factory pattern is used in Node created process.
Each Node have its Factory to create Product and use Product ParserData function to deal with the data.
There are two ways to set the GuidTool. One from Config file, another from environment variables.
Current GuidTool first check if has Config file.
If have, load the config GuidTool Information.
Else get from environment variables.
Config file should in same folder with FMMT.py or the path in environment variables.
Content should follow the format:
ToolsGuid ShortName Command
Guid | ShortName | Command |
---|---|---|
a31280ad-481e-41b6-95e8-127f4c984779 | TIANO | TianoCompress |
ee4e5898-3914-4259-9d6e-dc7bd79403cf | LZMA | LzmaCompress |
fc1bcdb0-7d31-49aa-936a-a4600d9dd083 | CRC32 | GenCrc32 |
d42ae6bd-1352-4bfb-909a-ca72a6eae889 | LZMAF86 | LzmaF86Compress |
3d532050-5cda-4fd0-879e-0f7f630d5afb | BROTLI | BrotliCompress |