The FMMT python tool is used for firmware files operation, which has the Fv/FFs-based 'View'&'Add'&'Delete'&'Replace' operation function: 1.Parse a FD(Firmware Device) / FV(Firmware Volume) / FFS(Firmware Files) 2.Add a new FFS into a FV file (both included in a FD file or not) 3.Replace an FFS in a FV file with a new FFS file 4.Delete an FFS in a FV file (both included in a FD file or not) 5.Extract the FFS from a FV file (both included in a FD file or not) This version of FMMT Python tool does not support PEIM rebase feature, this feature will be added in future update. Currently the FMMT C tool is saved in edk2-staging repo, but its quality and coding style can't meet the Edk2 quality, which is hard to maintain (Hard/Duplicate Code; Regression bugs; Restrict usage). The new Python version keeps same functions with origin C version. It has higher quality and better coding style, and it is much easier to extend new functions and to maintain. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1847 RFC Link: https://edk2.groups.io/g/devel/message/82877 Staging Link: https://github.com/tianocore/edk2-staging/tree/PyFMMT Cc: Bob Feng <bob.c.feng@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> Reviewed-by: Bob Feng <bob.c.feng@intel.com> Acked-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			184 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # FMMT
 | |
| ## Overview
 | |
| This FMMT tool is the python implementation of the edk2 FMMT tool which locates at https://github.com/tianocore/edk2-staging/tree/FceFmmt.
 | |
| This implementation has the same usage as the edk2 FMMT, but it's more readable and relaiable.
 | |
| 
 | |
| # FMMT User Guide
 | |
| 
 | |
| #### Last updated April 28, 2022
 | |
| 
 | |
| Important Changes and Updates:
 | |
| 
 | |
| - Oct 13, 2021 Initial Draft of FMMT Python Tool
 | |
| - Apr 28, 2022 Optimize functions & Command line
 | |
| 
 | |
| #### Note:
 | |
| 
 | |
| - FMMT Python Tool keeps same function with origin FMMT C Tool. It is much easier to maintain and extend other functions.
 | |
| 
 | |
| #### Known issue:
 | |
| 
 | |
| - Currently, FMMT Python tool does not support PEIM rebase feature, this feature will be added in future update.
 | |
| 
 | |
| # 1. Introduction
 | |
| 
 | |
| ## 1.1  Overview
 | |
| 
 | |
| The Firmware Device is a persistent physical repository that contains firmware code and/or data. The firmware code and/or data stored in Firmware Volumes. Detail layout of Firmware Volumes is described in ?Figure 1. The Firmware Volume Format?.
 | |
| 
 | |
| 
 | |
| 
 | |
| ?                                                   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.
 | |
| 
 | |
| ## 1.2  Tool Capabilities
 | |
| 
 | |
| 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)
 | |
| 
 | |
| ## 1.3  References
 | |
| 
 | |
| | Document                                         |
 | |
| | ------------------------------------------------ |
 | |
| | UEFI Platform Initialization (PI)  Specification |
 | |
| 
 | |
| # 2. FMMT Python Tool Usage
 | |
| 
 | |
| ## 2.1  Required Files
 | |
| 
 | |
| ### 2.1.1  Independent use
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ### 2.1.2  Use with Build System
 | |
| 
 | |
| 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***
 | |
| 
 | |
| ## 2.2  Syntax
 | |
| 
 | |
| ### 2.2.1  Syntax for Parse file
 | |
| 
 | |
|   ***-v < Inputfile > < Outputfile > -l < LogFileType > -c < ConfigFilePath >***
 | |
| 
 | |
| - Parse *Inputfile*, show its firmware layout with log file. *Outputfile* is optional, if inputs, the *Inputfile* will be encapsulated into *Outputfile* following the parsed firmware layout. *"-l LogFileType"* is optional, it decides the format of log file which saves Binary layout. Currently supports: json, txt. More formats will be added in the future. *"-c ConfigFilePath "* is optional, target FmmtConf.ini file can be selected with this parameter. If not provided, default FmmtConf.ini file will be used.
 | |
| - Ex: py -3 FMMT.py -v test.fd
 | |
| 
 | |
| ### 2.2.2  Syntax for Add a new FFS
 | |
| 
 | |
|   ***-a  < Inputfile > < TargetFvName/TargetFvGuid > < NewFfsFile > < Outputfile >***
 | |
| 
 | |
| - Add the *NewFfsFile* into *Inputfile*. *TargetFvName/TargetFvGuid* (Name or Guid) is the TargetFv which *NewFfsFile* will be added into.
 | |
| - Ex: py -3 FMMT.py -a Ovmf.fd 6938079b-b503-4e3d-9d24-b28337a25806 NewAdd.ffs output.fd
 | |
| 
 | |
| ### 2.2.3  Syntax for Delete an FFS
 | |
| 
 | |
|   ***-d  < Inputfile > < TargetFvName/TargetFvGuid > < TargetFfsName > < Outputfile >***
 | |
| 
 | |
| - Delete the Ffs from *Inputfile*. TargetFfsName (Guid) is the TargetFfs which will be deleted. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
 | |
| - Ex: py -3 FMMT.py -d Ovmf.fd 6938079b-b503-4e3d-9d24-b28337a25806 S3Resume2Pei output.fd
 | |
| 
 | |
| ### 2.2.4  Syntax for Replace an FFS
 | |
| 
 | |
| ?  ***-r  < Inputfile > < TargetFvName/TargetFvGuid > < TargetFfsName > < NewFfsFile > < Outputfile >***
 | |
| 
 | |
| - Replace the Ffs with the NewFfsFile. TargetFfsName (Guid) is the TargetFfs which will be replaced. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
 | |
| - Ex: py -3 FMMT.py -r Ovmf.fd 6938079b-b503-4e3d-9d24-b28337a25806 S3Resume2Pei NewS3Resume2Pei.ffs output.fd
 | |
| 
 | |
| ### 2.2.5  Syntax for Extract an FFS
 | |
| 
 | |
|   ***-e  < Inputfile > < TargetFvName/TargetFvGuid > < TargetFfsName > < Outputfile >***
 | |
| 
 | |
| - Extract the Ffs from the Inputfile. TargetFfsName (Guid) is the TargetFfs which will be extracted. *TargetFvName/TargetFvGuid* is optional, which is the parent of TargetFfs*.*
 | |
| - Ex: py -3 FMMT.py -e Ovmf.fd 6938079b-b503-4e3d-9d24-b28337a25806 S3Resume2Pei output.fd
 | |
| 
 | |
| # 3. FMMT Python Tool Design
 | |
| 
 | |
| 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).
 | |
| 
 | |
| ## 3.1  NodeTree
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ### 3.1.1  NodeTree Format
 | |
| 
 | |
| 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
 | |
| 
 | |
| ### 3.1.2  Node Factory and Product
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ## 3.2  GuidTool
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ### 3.2.1  Get from Config file
 | |
| 
 | |
| - Config file should in same folder with FMMT.py or the path in environment variables.
 | |
| 
 | |
| - Content should follow the format:
 | |
| 
 | |
|   ***ToolsGuid ShortName Command***
 | |
| 
 | |
| ### 3.2.2  Get from Environment Variables
 | |
| 
 | |
| - The GuidTool Command used must be set in environment variables.
 | |
| 
 | |
| ### 3.2.3  Edk2 Based GuidTool
 | |
| 
 | |
| | ***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***  |
 |