]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/Capsule.py
BaseTools: Move ImageBinDict to GenFdsGlobalVariable.py
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / Capsule.py
CommitLineData
30fdf114
LG
1## @file\r
2# generate capsule\r
3#\r
9eb87141 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
30fdf114 5#\r
40d841f6 6# This program and the accompanying materials\r
30fdf114
LG
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
bfa65b61
GL
18from __future__ import absolute_import\r
19from .GenFdsGlobalVariable import GenFdsGlobalVariable\r
89a69d4b 20from .GenFdsGlobalVariable import FindExtendTool\r
30fdf114 21from CommonDataClass.FdfClass import CapsuleClassObject\r
1be2ed90 22import Common.LongFilePathOs as os\r
30fdf114 23import subprocess\r
86379ac4 24from io import BytesIO\r
30fdf114 25from Common.Misc import SaveFileOnChange\r
a3251d84
YL
26from Common.Misc import PackRegistryFormatGuid\r
27import uuid\r
28from struct import pack\r
91ae2988
YZ
29from Common import EdkLogger\r
30from Common.BuildToolError import *\r
30fdf114
LG
31\r
32\r
33T_CHAR_LF = '\n'\r
91ae2988
YZ
34WIN_CERT_REVISION = 0x0200\r
35WIN_CERT_TYPE_EFI_GUID = 0x0EF1\r
36EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID('{4aafd29d-68df-49ee-8aa9-347d375665a7}')\r
37EFI_CERT_TYPE_RSA2048_SHA256_GUID = uuid.UUID('{a7717414-c616-4977-9420-844712a735bf}')\r
30fdf114
LG
38\r
39## create inf file describes what goes into capsule and call GenFv to generate capsule\r
40#\r
41#\r
42class Capsule (CapsuleClassObject) :\r
43 ## The constructor\r
44 #\r
45 # @param self The object pointer\r
46 #\r
47 def __init__(self):\r
48 CapsuleClassObject.__init__(self)\r
49 # For GenFv\r
50 self.BlockSize = None\r
51 # For GenFv\r
52 self.BlockNum = None\r
fd171542 53 self.CapsuleName = None\r
30fdf114 54\r
a3251d84
YL
55 ## Generate FMP capsule\r
56 #\r
57 # @retval string Generated Capsule file path\r
58 #\r
59 def GenFmpCapsule(self):\r
60 #\r
61 # Generate capsule header\r
62 # typedef struct {\r
63 # EFI_GUID CapsuleGuid;\r
64 # UINT32 HeaderSize;\r
65 # UINT32 Flags;\r
66 # UINT32 CapsuleImageSize;\r
67 # } EFI_CAPSULE_HEADER;\r
68 #\r
86379ac4 69 Header = BytesIO()\r
a3251d84
YL
70 #\r
71 # Use FMP capsule GUID: 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A\r
72 #\r
73 Header.write(PackRegistryFormatGuid('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A'))\r
74 HdrSize = 0\r
75 if 'CAPSULE_HEADER_SIZE' in self.TokensDict:\r
76 Header.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16)))\r
77 HdrSize = int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16)\r
78 else:\r
79 Header.write(pack('=I', 0x20))\r
80 HdrSize = 0x20\r
81 Flags = 0\r
82 if 'CAPSULE_FLAGS' in self.TokensDict:\r
83 for flag in self.TokensDict['CAPSULE_FLAGS'].split(','):\r
84 flag = flag.strip()\r
85 if flag == 'PopulateSystemTable':\r
86 Flags |= 0x00010000 | 0x00020000\r
87 elif flag == 'PersistAcrossReset':\r
88 Flags |= 0x00010000\r
89 elif flag == 'InitiateReset':\r
90 Flags |= 0x00040000\r
91 Header.write(pack('=I', Flags))\r
92 #\r
93 # typedef struct {\r
94 # UINT32 Version;\r
95 # UINT16 EmbeddedDriverCount;\r
96 # UINT16 PayloadItemCount;\r
97 # // UINT64 ItemOffsetList[];\r
98 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;\r
99 #\r
86379ac4 100 FwMgrHdr = BytesIO()\r
a3251d84
YL
101 if 'CAPSULE_HEADER_INIT_VERSION' in self.TokensDict:\r
102 FwMgrHdr.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_INIT_VERSION'], 16)))\r
103 else:\r
104 FwMgrHdr.write(pack('=I', 0x00000001))\r
105 FwMgrHdr.write(pack('=HH', len(self.CapsuleDataList), len(self.FmpPayloadList)))\r
106 FwMgrHdrSize = 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList))\r
107\r
91ae2988
YZ
108 #\r
109 # typedef struct _WIN_CERTIFICATE {\r
110 # UINT32 dwLength;\r
111 # UINT16 wRevision;\r
112 # UINT16 wCertificateType;\r
113 # //UINT8 bCertificate[ANYSIZE_ARRAY];\r
114 # } WIN_CERTIFICATE;\r
115 #\r
116 # typedef struct _WIN_CERTIFICATE_UEFI_GUID {\r
117 # WIN_CERTIFICATE Hdr;\r
118 # EFI_GUID CertType;\r
119 # //UINT8 CertData[ANYSIZE_ARRAY];\r
120 # } WIN_CERTIFICATE_UEFI_GUID;\r
121 #\r
122 # typedef struct {\r
123 # UINT64 MonotonicCount;\r
124 # WIN_CERTIFICATE_UEFI_GUID AuthInfo;\r
125 # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;\r
126 #\r
127 # typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {\r
128 # EFI_GUID HashType;\r
129 # UINT8 PublicKey[256];\r
130 # UINT8 Signature[256];\r
131 # } EFI_CERT_BLOCK_RSA_2048_SHA256;\r
132 #\r
133\r
a3251d84 134 PreSize = FwMgrHdrSize\r
86379ac4 135 Content = BytesIO()\r
a3251d84
YL
136 for driver in self.CapsuleDataList:\r
137 FileName = driver.GenCapsuleSubItem()\r
138 FwMgrHdr.write(pack('=Q', PreSize))\r
139 PreSize += os.path.getsize(FileName)\r
140 File = open(FileName, 'rb')\r
141 Content.write(File.read())\r
142 File.close()\r
143 for fmp in self.FmpPayloadList:\r
d4c558e8
YZ
144 if fmp.Existed:\r
145 FwMgrHdr.write(pack('=Q', PreSize))\r
146 PreSize += len(fmp.Buffer)\r
147 Content.write(fmp.Buffer)\r
148 continue\r
19e3aa7a
YZ
149 if fmp.ImageFile:\r
150 for Obj in fmp.ImageFile:\r
151 fmp.ImageFile = Obj.GenCapsuleSubItem()\r
152 if fmp.VendorCodeFile:\r
153 for Obj in fmp.VendorCodeFile:\r
154 fmp.VendorCodeFile = Obj.GenCapsuleSubItem()\r
91ae2988
YZ
155 if fmp.Certificate_Guid:\r
156 ExternalTool, ExternalOption = FindExtendTool([], GenFdsGlobalVariable.ArchList, fmp.Certificate_Guid)\r
157 CmdOption = ''\r
158 CapInputFile = fmp.ImageFile\r
159 if not os.path.isabs(fmp.ImageFile):\r
160 CapInputFile = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, fmp.ImageFile)\r
161 CapOutputTmp = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.tmp'\r
4231a819 162 if ExternalTool is None:\r
91ae2988
YZ
163 EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % fmp.Certificate_Guid)\r
164 else:\r
165 CmdOption += ExternalTool\r
166 if ExternalOption:\r
167 CmdOption = CmdOption + ' ' + ExternalOption\r
168 CmdOption += ' -e ' + ' --monotonic-count ' + str(fmp.MonotonicCount) + ' -o ' + CapOutputTmp + ' ' + CapInputFile\r
169 CmdList = CmdOption.split()\r
170 GenFdsGlobalVariable.CallExternalTool(CmdList, "Failed to generate FMP auth capsule")\r
171 if uuid.UUID(fmp.Certificate_Guid) == EFI_CERT_TYPE_PKCS7_GUID:\r
172 dwLength = 4 + 2 + 2 + 16 + os.path.getsize(CapOutputTmp) - os.path.getsize(CapInputFile)\r
173 else:\r
174 dwLength = 4 + 2 + 2 + 16 + 16 + 256 + 256\r
5f53a7aa
YZ
175 fmp.ImageFile = CapOutputTmp\r
176 AuthData = [fmp.MonotonicCount, dwLength, WIN_CERT_REVISION, WIN_CERT_TYPE_EFI_GUID, fmp.Certificate_Guid]\r
d4c558e8 177 fmp.Buffer = fmp.GenCapsuleSubItem(AuthData)\r
91ae2988 178 else:\r
d4c558e8 179 fmp.Buffer = fmp.GenCapsuleSubItem()\r
5f53a7aa 180 FwMgrHdr.write(pack('=Q', PreSize))\r
d4c558e8
YZ
181 PreSize += len(fmp.Buffer)\r
182 Content.write(fmp.Buffer)\r
a3251d84
YL
183 BodySize = len(FwMgrHdr.getvalue()) + len(Content.getvalue())\r
184 Header.write(pack('=I', HdrSize + BodySize))\r
185 #\r
186 # The real capsule header structure is 28 bytes\r
187 #\r
188 Header.write('\x00'*(HdrSize-28))\r
189 Header.write(FwMgrHdr.getvalue())\r
190 Header.write(Content.getvalue())\r
191 #\r
192 # Generate FMP capsule file\r
193 #\r
194 CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.Cap'\r
195 SaveFileOnChange(CapOutputFile, Header.getvalue(), True)\r
196 return CapOutputFile\r
197\r
30fdf114
LG
198 ## Generate capsule\r
199 #\r
200 # @param self The object pointer\r
fd171542 201 # @retval string Generated Capsule file path\r
30fdf114
LG
202 #\r
203 def GenCapsule(self):\r
7de00838
GL
204 if self.UiCapsuleName.upper() + 'cap' in GenFdsGlobalVariable.ImageBinDict:\r
205 return GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap']\r
fd171542 206\r
207 GenFdsGlobalVariable.InfLogger( "\nGenerate %s Capsule" %self.UiCapsuleName)\r
f7496d71 208 if ('CAPSULE_GUID' in self.TokensDict and\r
a3251d84
YL
209 uuid.UUID(self.TokensDict['CAPSULE_GUID']) == uuid.UUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')):\r
210 return self.GenFmpCapsule()\r
211\r
30fdf114
LG
212 CapInfFile = self.GenCapInf()\r
213 CapInfFile.writelines("[files]" + T_CHAR_LF)\r
fd171542 214 CapFileList = []\r
30fdf114 215 for CapsuleDataObj in self.CapsuleDataList :\r
fd171542 216 CapsuleDataObj.CapsuleName = self.CapsuleName\r
30fdf114 217 FileName = CapsuleDataObj.GenCapsuleSubItem()\r
fd171542 218 CapsuleDataObj.CapsuleName = None\r
219 CapFileList.append(FileName)\r
30fdf114
LG
220 CapInfFile.writelines("EFI_FILE_NAME = " + \\r
221 FileName + \\r
222 T_CHAR_LF)\r
223 SaveFileOnChange(self.CapInfFileName, CapInfFile.getvalue(), False)\r
224 CapInfFile.close()\r
225 #\r
226 # Call GenFv tool to generate capsule\r
227 #\r
228 CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName)\r
229 CapOutputFile = CapOutputFile + '.Cap'\r
230 GenFdsGlobalVariable.GenerateFirmwareVolume(\r
231 CapOutputFile,\r
232 [self.CapInfFileName],\r
fd171542 233 Capsule=True,\r
234 FfsList=CapFileList\r
30fdf114 235 )\r
fd171542 236\r
237 GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s Capsule Successfully" %self.UiCapsuleName)\r
30fdf114 238 GenFdsGlobalVariable.SharpCounter = 0\r
7de00838 239 GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] = CapOutputFile\r
fd171542 240 return CapOutputFile\r
30fdf114
LG
241\r
242 ## Generate inf file for capsule\r
243 #\r
244 # @param self The object pointer\r
245 # @retval file inf file object\r
246 #\r
247 def GenCapInf(self):\r
248 self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir,\r
249 self.UiCapsuleName + "_Cap" + '.inf')\r
86379ac4 250 CapInfFile = BytesIO() #open (self.CapInfFileName , 'w+')\r
30fdf114
LG
251\r
252 CapInfFile.writelines("[options]" + T_CHAR_LF)\r
253\r
9eb87141 254 for Item in self.TokensDict:\r
30fdf114
LG
255 CapInfFile.writelines("EFI_" + \\r
256 Item + \\r
257 ' = ' + \\r
9eb87141 258 self.TokensDict[Item] + \\r
30fdf114
LG
259 T_CHAR_LF)\r
260\r
261 return CapInfFile\r