| ## @file | |
| # generate capsule | |
| # | |
| # Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR> | |
| # | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| # | |
| ## | |
| # Import Modules | |
| # | |
| from __future__ import absolute_import | |
| from .GenFdsGlobalVariable import GenFdsGlobalVariable | |
| from io import BytesIO | |
| from struct import pack | |
| import os | |
| from Common.Misc import SaveFileOnChange | |
| import uuid | |
| ## base class for capsule data | |
| # | |
| # | |
| class CapsuleData: | |
| ## The constructor | |
| # | |
| # @param self The object pointer | |
| def __init__(self): | |
| pass | |
| ## generate capsule data | |
| # | |
| # @param self The object pointer | |
| def GenCapsuleSubItem(self): | |
| pass | |
| ## FFS class for capsule data | |
| # | |
| # | |
| class CapsuleFfs (CapsuleData): | |
| ## The constructor | |
| # | |
| # @param self The object pointer | |
| # | |
| def __init__(self) : | |
| self.Ffs = None | |
| self.FvName = None | |
| ## generate FFS capsule data | |
| # | |
| # @param self The object pointer | |
| # @retval string Generated file name | |
| # | |
| def GenCapsuleSubItem(self): | |
| FfsFile = self.Ffs.GenFfs() | |
| return FfsFile | |
| ## FV class for capsule data | |
| # | |
| # | |
| class CapsuleFv (CapsuleData): | |
| ## The constructor | |
| # | |
| # @param self The object pointer | |
| # | |
| def __init__(self) : | |
| self.Ffs = None | |
| self.FvName = None | |
| self.CapsuleName = None | |
| ## generate FV capsule data | |
| # | |
| # @param self The object pointer | |
| # @retval string Generated file name | |
| # | |
| def GenCapsuleSubItem(self): | |
| if self.FvName.find('.fv') == -1: | |
| if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict: | |
| FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[self.FvName.upper()] | |
| FdBuffer = BytesIO() | |
| FvObj.CapsuleName = self.CapsuleName | |
| FvFile = FvObj.AddToBuffer(FdBuffer) | |
| FvObj.CapsuleName = None | |
| FdBuffer.close() | |
| return FvFile | |
| else: | |
| FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName) | |
| return FvFile | |
| ## FD class for capsule data | |
| # | |
| # | |
| class CapsuleFd (CapsuleData): | |
| ## The constructor | |
| # | |
| # @param self The object pointer | |
| # | |
| def __init__(self) : | |
| self.Ffs = None | |
| self.FdName = None | |
| self.CapsuleName = None | |
| ## generate FD capsule data | |
| # | |
| # @param self The object pointer | |
| # @retval string Generated file name | |
| # | |
| def GenCapsuleSubItem(self): | |
| if self.FdName.find('.fd') == -1: | |
| if self.FdName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict: | |
| FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[self.FdName.upper()] | |
| FdFile = FdObj.GenFd() | |
| return FdFile | |
| else: | |
| FdFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FdName) | |
| return FdFile | |
| ## AnyFile class for capsule data | |
| # | |
| # | |
| class CapsuleAnyFile (CapsuleData): | |
| ## The constructor | |
| # | |
| # @param self The object pointer | |
| # | |
| def __init__(self) : | |
| self.Ffs = None | |
| self.FileName = None | |
| ## generate AnyFile capsule data | |
| # | |
| # @param self The object pointer | |
| # @retval string Generated file name | |
| # | |
| def GenCapsuleSubItem(self): | |
| return self.FileName | |
| ## Afile class for capsule data | |
| # | |
| # | |
| class CapsuleAfile (CapsuleData): | |
| ## The constructor | |
| # | |
| # @param self The object pointer | |
| # | |
| def __init__(self) : | |
| self.Ffs = None | |
| self.FileName = None | |
| ## generate Afile capsule data | |
| # | |
| # @param self The object pointer | |
| # @retval string Generated file name | |
| # | |
| def GenCapsuleSubItem(self): | |
| return self.FileName | |
| class CapsulePayload(CapsuleData): | |
| '''Generate payload file, the header is defined below: | |
| #pragma pack(1) | |
| typedef struct { | |
| UINT32 Version; | |
| EFI_GUID UpdateImageTypeId; | |
| UINT8 UpdateImageIndex; | |
| UINT8 reserved_bytes[3]; | |
| UINT32 UpdateImageSize; | |
| UINT32 UpdateVendorCodeSize; | |
| UINT64 UpdateHardwareInstance; //Introduced in v2 | |
| } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER; | |
| ''' | |
| def __init__(self): | |
| self.UiName = None | |
| self.Version = None | |
| self.ImageTypeId = None | |
| self.ImageIndex = None | |
| self.HardwareInstance = None | |
| self.ImageFile = [] | |
| self.VendorCodeFile = [] | |
| self.Certificate_Guid = None | |
| self.MonotonicCount = None | |
| self.Existed = False | |
| self.Buffer = None | |
| def GenCapsuleSubItem(self, AuthData=[]): | |
| if not self.Version: | |
| self.Version = '0x00000002' | |
| if not self.ImageIndex: | |
| self.ImageIndex = '0x1' | |
| if not self.HardwareInstance: | |
| self.HardwareInstance = '0x0' | |
| ImageFileSize = os.path.getsize(self.ImageFile) | |
| if AuthData: | |
| # the ImageFileSize need include the full authenticated info size. From first bytes of MonotonicCount to last bytes of certificate. | |
| # the 32 bit is the MonotonicCount, dwLength, wRevision, wCertificateType and CertType | |
| ImageFileSize += 32 | |
| VendorFileSize = 0 | |
| if self.VendorCodeFile: | |
| VendorFileSize = os.path.getsize(self.VendorCodeFile) | |
| # | |
| # Fill structure | |
| # | |
| Guid = self.ImageTypeId.split('-') | |
| Buffer = pack('=ILHHBBBBBBBBBBBBIIQ', | |
| int(self.Version, 16), | |
| int(Guid[0], 16), | |
| int(Guid[1], 16), | |
| int(Guid[2], 16), | |
| int(Guid[3][-4:-2], 16), | |
| int(Guid[3][-2:], 16), | |
| int(Guid[4][-12:-10], 16), | |
| int(Guid[4][-10:-8], 16), | |
| int(Guid[4][-8:-6], 16), | |
| int(Guid[4][-6:-4], 16), | |
| int(Guid[4][-4:-2], 16), | |
| int(Guid[4][-2:], 16), | |
| int(self.ImageIndex, 16), | |
| 0, | |
| 0, | |
| 0, | |
| ImageFileSize, | |
| VendorFileSize, | |
| int(self.HardwareInstance, 16) | |
| ) | |
| if AuthData: | |
| Buffer += pack('QIHH', AuthData[0], AuthData[1], AuthData[2], AuthData[3]) | |
| Buffer += uuid.UUID(AuthData[4]).bytes_le | |
| # | |
| # Append file content to the structure | |
| # | |
| ImageFile = open(self.ImageFile, 'rb') | |
| Buffer += ImageFile.read() | |
| ImageFile.close() | |
| if self.VendorCodeFile: | |
| VendorFile = open(self.VendorCodeFile, 'rb') | |
| Buffer += VendorFile.read() | |
| VendorFile.close() | |
| self.Existed = True | |
| return Buffer |