## @file # Generate capsules for Vlv2TbltDevicePkg # openssl must be install and in path # # Copyright (c) 2019, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # ''' GenCapsuleAll ''' import os import sys import argparse import subprocess import glob import shutil import struct import datetime # # Globals for help information # __prog__ = 'GenCapsuleAll' __copyright__ = 'Copyright (c) 2019, Intel Corporation. All rights reserved.' __description__ = 'Generate Vlv2Tbl2DevicePkg capsules.\n' # # Globals # gWorkspace = '' gBaseToolsPath = '' gArgs = None def LogAlways(Message): sys.stdout.write (__prog__ + ': ' + Message + '\n') sys.stdout.flush() def Log(Message): global gArgs if not gArgs.Verbose: return sys.stdout.write (__prog__ + ': ' + Message + '\n') sys.stdout.flush() def Error(Message, ExitValue=1): sys.stderr.write (__prog__ + ': ERROR: ' + Message + '\n') sys.exit (ExitValue) def RelativePath(target): global gWorkspace Log('RelativePath' + target) return os.path.relpath (target, gWorkspace) def NormalizePath(target): if isinstance(target, tuple): return os.path.normpath (os.path.join (*target)) else: return os.path.normpath (target) def RemoveFile(target): target = NormalizePath(target) if not target or target == os.pathsep: Error ('RemoveFile() invalid target') if os.path.exists(target): os.remove (target) Log ('remove %s' % (RelativePath (target))) def RemoveDirectory(target): target = NormalizePath(target) if not target or target == os.pathsep: Error ('RemoveDirectory() invalid target') if os.path.exists(target): Log ('rmdir %s' % (RelativePath (target))) shutil.rmtree(target) def CreateDirectory(target): target = NormalizePath(target) if not os.path.exists(target): Log ('mkdir %s' % (RelativePath (target))) os.makedirs (target) def Copy(src, dst): src = NormalizePath(src) dst = NormalizePath(dst) for File in glob.glob(src): Log ('copy %s -> %s' % (RelativePath (File), RelativePath (dst))) shutil.copy (File, dst) GenerateCapsuleCommand = ''' GenerateCapsule --encode --guid {FMP_CAPSULE_GUID} --fw-version {FMP_CAPSULE_VERSION} --lsv {FMP_CAPSULE_LSV} --capflag PersistAcrossReset --capflag InitiateReset --signer-private-cert={BASE_TOOLS_PATH}/Source/Python/Pkcs7Sign/TestCert.pem --other-public-cert={BASE_TOOLS_PATH}/Source/Python/Pkcs7Sign/TestSub.pub.pem --trusted-public-cert={BASE_TOOLS_PATH}/Source/Python/Pkcs7Sign/TestRoot.pub.pem -o {FMP_CAPSULE_FILE} {FMP_CAPSULE_PAYLOAD} ''' MetaInfoXmlTemplate = ''' com.intel.FMP_CAPSULE_BASE_NAME.firmware FMP_CAPSULE_BASE_NAME System firmware for the FMP_CAPSULE_BASE_NAME Description of System firmware for the FMP_CAPSULE_BASE_NAME FMP_CAPSULE_GUID http://www.tianocore.org CC0-1.0 BSD Tianocore Build FMP_CAPSULE_STRING ''' LvfsDdfTemplate = ''' .OPTION EXPLICIT ; Generate errors on variable typos .Set CabinetNameTemplate=firmware.cab ; The name of the file .set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory .Set Cabinet=on ; .Set Compress=on ; .Set DiskDirectory1=. .Set MaxDiskSize=99999744 ; multiple of 512 ;*** Files to zip ; ; firmware.bin firmware.metainfo.xml ;*** ''' def GenCapsuleDevice (BaseName, PayloadFileName, Guid, Version, Lsv, CapsulesPath, CapsulesSubDir): global gBaseToolsPath LogAlways ('Generate Capsule: {0} {1:08x} {2:08x} {3}'.format (Guid, Version, Lsv, PayloadFileName)) VersionString = '.'.join([str(ord(x)) for x in struct.pack('>I', Version).decode()]) FmpCapsuleFile = NormalizePath ((CapsulesPath, CapsulesSubDir, BaseName + '.' + VersionString + '.cap')) Command = GenerateCapsuleCommand.format ( FMP_CAPSULE_GUID = Guid, FMP_CAPSULE_VERSION = Version, FMP_CAPSULE_LSV = Lsv, BASE_TOOLS_PATH = gBaseToolsPath, FMP_CAPSULE_FILE = FmpCapsuleFile, FMP_CAPSULE_PAYLOAD = PayloadFileName ) Command = ' '.join(Command.splitlines()).strip() if gArgs.Verbose: Command = Command + ' -v' Log (Command) Process = subprocess.Popen(Command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) ProcessOutput = Process.communicate() if Process.returncode == 0: Log (ProcessOutput[0].decode()) else: LogAlways (Command) LogAlways (ProcessOutput[0].decode()) Error ('GenerateCapsule returned an error') Copy (PayloadFileName, (CapsulesPath, 'firmware.bin')) MetaInfoXml = MetaInfoXmlTemplate MetaInfoXml = MetaInfoXml.replace ('FMP_CAPSULE_GUID', Guid) MetaInfoXml = MetaInfoXml.replace ('FMP_CAPSULE_BASE_NAME', BaseName) MetaInfoXml = MetaInfoXml.replace ('FMP_CAPSULE_VERSION_DECIMAL', str(Version)) MetaInfoXml = MetaInfoXml.replace ('FMP_CAPSULE_STRING', VersionString) MetaInfoXml = MetaInfoXml.replace ('FMP_CAPSULE_DATE', str(datetime.date.today())) f = open (NormalizePath ((CapsulesPath, 'firmware.metainfo.xml')), 'w') f.write(MetaInfoXml) f.close() f = open (NormalizePath ((CapsulesPath, 'Lvfs.ddf')), 'w') f.write(LvfsDdfTemplate) f.close() if sys.platform == "win32": Command = 'makecab /f ' + NormalizePath ((CapsulesPath, 'Lvfs.ddf')) else: Command = 'gcab --create firmware.cab firmware.bin firmware.metainfo.xml' Log (Command) Process = subprocess.Popen(Command, cwd=CapsulesPath, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) ProcessOutput = Process.communicate() if Process.returncode == 0: Log (ProcessOutput[0].decode()) else: LogAlways (Command) LogAlways (ProcessOutput[0].decode()) Error ('GenerateCapsule returned an error') FmpCabinetFile = NormalizePath ((CapsulesPath, CapsulesSubDir, BaseName + '.' + VersionString + '.cab')) Copy ((CapsulesPath, 'firmware.cab'), FmpCabinetFile) RemoveFile ((CapsulesPath, 'firmware.cab')) RemoveFile ((CapsulesPath, 'setup.inf')) RemoveFile ((CapsulesPath, 'setup.rpt')) RemoveFile ((CapsulesPath, 'Lvfs.ddf')) RemoveFile ((CapsulesPath, 'firmware.metainfo.xml')) RemoveFile ((CapsulesPath, 'firmware.bin')) def GenCapsuleSampleDevice (SampleDeviceName, Guid, Version, Lsv, CapsulesPath, CapsulesSubDir): BinaryPayload = SampleDeviceName.encode() + bytearray(0x18 - len (SampleDeviceName.encode())) BinaryPayload = BinaryPayload + struct.pack(' 1: if ['X64'] in gArgs.Arch: UefiArch = 'X64' CapsulesPath = NormalizePath((EdkiiBuildDir, 'Capsules')) CapsulesSubDir = 'TestCert' + '_' + UefiArch + '_' + gArgs.BuildTarget + '_' + gArgs.ToolChain # # Create output directories # try: CreateDirectory ((CapsulesPath)) except: pass try: CreateDirectory ((CapsulesPath, CapsulesSubDir)) except: pass # # Copy CapsuleApp # Copy ((EdkiiBuildOutput, UefiArch, 'CapsuleApp.efi'), (CapsulesPath, CapsulesSubDir)) # # Generate capsules for the Red Sample Device # GenCapsuleSampleDevice('Red','72e2945a-00da-448e-9aa7-075ad840f9d4',0x00000010,0x00000000, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Red','72e2945a-00da-448e-9aa7-075ad840f9d4',0x00000011,0x00000000, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Red','72e2945a-00da-448e-9aa7-075ad840f9d4',0x00000012,0x00000000, CapsulesPath, CapsulesSubDir) # # Generate capsules for the Green Sample Device # GenCapsuleSampleDevice('Green','79179bfd-704d-4c90-9e02-0ab8d968c18a',0x00000020,0x00000020, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Green','79179bfd-704d-4c90-9e02-0ab8d968c18a',0x00000021,0x00000020, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Green','79179bfd-704d-4c90-9e02-0ab8d968c18a',0x00000022,0x00000020, CapsulesPath, CapsulesSubDir) # # Generate capsules for the Blue Sample Device # GenCapsuleSampleDevice('Blue','149da854-7d19-4faa-a91e-862ea1324be6',0x00000010,0x00000000, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Blue','149da854-7d19-4faa-a91e-862ea1324be6',0x00000011,0x00000000, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Blue','149da854-7d19-4faa-a91e-862ea1324be6',0x00000012,0x00000012, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Blue','149da854-7d19-4faa-a91e-862ea1324be6',0x00000013,0x00000012, CapsulesPath, CapsulesSubDir) GenCapsuleSampleDevice('Blue','149da854-7d19-4faa-a91e-862ea1324be6',0x00000014,0x00000012, CapsulesPath, CapsulesSubDir) # # Generate capsules for Minnow Max Firmware Updates # RomFileName = os.path.join (EdkiiBuildOutput, 'FV', 'VLV.fd') GenCapsuleDevice('MinnowMax', RomFileName,'4096267b-da0a-42eb-b5eb-fef31d207cb4',0x0000000C,0x00000000, CapsulesPath, CapsulesSubDir)