]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools/FMMT: Add Shrink Fv function
authorChen, Christine <Yuwei.Chen@intel.com>
Fri, 16 Sep 2022 01:51:18 +0000 (09:51 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 19 Oct 2022 06:32:07 +0000 (06:32 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3938

This function is used to remove the useless FV free space.
Usage: FMMT -s Inputfile Outputfile

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>
BaseTools/Source/Python/FMMT/FMMT.py
BaseTools/Source/Python/FMMT/core/FMMTOperation.py
BaseTools/Source/Python/FMMT/core/FvHandler.py

index 3590f3340ec3addc132afb83823b6792747a1c25..bf580b3843a81b6e2427a54b4bb87164d312268b 100644 (file)
@@ -41,6 +41,8 @@ parser.add_argument("-c", "--ConfigFilePath", dest="ConfigFilePath", nargs='+',
                         FmmtConf file saves the target guidtool used in compress/uncompress process.\\r
                         If do not provide, FMMT tool will search the inputfile folder for FmmtConf.ini firstly, if not found,\\r
                         the FmmtConf.ini saved in FMMT tool's folder will be used as default.")\r
+parser.add_argument("-s", "--ShrinkFv", dest="ShrinkFv", nargs='+',\r
+                    help="Shrink the Fv file: '-s InputFvfile OutputFvfile")\r
 \r
 def print_banner():\r
     print("")\r
@@ -111,6 +113,9 @@ class FMMT():
         else:\r
             ReplaceFfs(inputfile, self.CheckFfsName(Ffs_name), newffsfile, outputfile)\r
 \r
+    def Shrink(self,inputfile: str, outputfile: str) -> None:\r
+        self.SetDestPath(inputfile)\r
+        ShrinkFv(inputfile, outputfile)\r
 \r
 def main():\r
     args=parser.parse_args()\r
@@ -142,6 +147,8 @@ def main():
                 fmmt.Replace(args.Replace[0],args.Replace[2],args.Replace[3],args.Replace[4],args.Replace[1])\r
             else:\r
                 fmmt.Replace(args.Replace[0],args.Replace[1],args.Replace[2],args.Replace[3])\r
+        elif args.ShrinkFv:\r
+            fmmt.Shrink(args.ShrinkFv[0], args.ShrinkFv[1])\r
         else:\r
             parser.print_help()\r
     except Exception as e:\r
index 4e58c91b5c4128320084a839e13857d7b3ee423e..a86f8dda9a1a99edc14981781413b55c009e1c1b 100644 (file)
@@ -204,3 +204,29 @@ def ExtractFfs(inputfile: str, Ffs_name: str, outputfile: str, Fv_name: str=None
             logger.debug('Extract ffs data is saved in {}.'.format(outputfile))\r
     else:\r
         logger.error('Target Ffs/Fv not found!!!')\r
+\r
+def ShrinkFv(inputfile: str, outputfile: str) -> None:\r
+    if not os.path.exists(inputfile):\r
+        logger.error("Invalid inputfile, can not open {}.".format(inputfile))\r
+        raise Exception("Process Failed: Invalid inputfile!")\r
+    # 1. Data Prepare\r
+    with open(inputfile, "rb") as f:\r
+        whole_data = f.read()\r
+    FmmtParser = FMMTParser(inputfile, ROOT_TREE)\r
+    # 2. DataTree Create\r
+    logger.debug('Parsing inputfile data......')\r
+    FmmtParser.ParserFromRoot(FmmtParser.WholeFvTree, whole_data)\r
+    logger.debug('Done!')\r
+    TargetFv = FmmtParser.WholeFvTree.Child[0]\r
+    if TargetFv:\r
+        FvMod = FvHandler(TargetFv)\r
+        Status = FvMod.ShrinkFv()\r
+    else:\r
+        logger.error('Target Fv not found!!!')\r
+    # 4. Data Encapsulation\r
+    if Status:\r
+        logger.debug('Start encapsulating data......')\r
+        FmmtParser.Encapsulation(FmmtParser.WholeFvTree, False)\r
+        with open(outputfile, "wb") as f:\r
+            f.write(FmmtParser.FinalData)\r
+        logger.debug('Encapsulated data is saved in {}.'.format(outputfile))\r
index e8b8480098785eec64c117a56ceebcb4014d1fe9..ff3d637623f843a7fc4bcf30fedd3ac1a81af4e0 100644 (file)
@@ -145,7 +145,7 @@ def ModifyFvSystemGuid(TargetFv) -> None:
             TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData\r
 \r
 class FvHandler:\r
-    def __init__(self, NewFfs, TargetFfs) -> None:\r
+    def __init__(self, NewFfs, TargetFfs=None) -> None:\r
         self.NewFfs = NewFfs\r
         self.TargetFfs = TargetFfs\r
         self.Status = False\r
@@ -638,3 +638,29 @@ class FvHandler:
         self.Status = True\r
         logger.debug('Done!')\r
         return self.Status\r
+\r
+    def ShrinkFv(self) -> bool:\r
+        TargetFv = self.NewFfs\r
+        TargetFv.Data.Data = b''\r
+        if not TargetFv.Data.Free_Space:\r
+            self.Status = True\r
+        else:\r
+            BlockSize = TargetFv.Data.Header.BlockMap[0].Length\r
+            New_Free_Space = TargetFv.Data.Free_Space%BlockSize\r
+            Removed_Space = TargetFv.Data.Free_Space - New_Free_Space\r
+            TargetFv.Child[-1].Data.Data = b'\xff' * New_Free_Space\r
+            TargetFv.Data.Size -= Removed_Space\r
+            TargetFv.Data.Header.Fvlength = TargetFv.Data.Size\r
+            ModifyFvSystemGuid(TargetFv)\r
+            for item in TargetFv.Child:\r
+                if item.type == FFS_FREE_SPACE:\r
+                    TargetFv.Data.Data += item.Data.Data + item.Data.PadData\r
+                else:\r
+                    TargetFv.Data.Data += struct2stream(item.Data.Header)+ item.Data.Data + item.Data.PadData\r
+            TargetFv.Data.ModFvExt()\r
+            TargetFv.Data.ModFvSize()\r
+            TargetFv.Data.ModExtHeaderData()\r
+            ModifyFvExtData(TargetFv)\r
+            TargetFv.Data.ModCheckSum()\r
+            self.Status = True\r
+        return self.Status\r