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