]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/GenFds/Capsule.py
BaseTools: Supported FMP capsule image.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / Capsule.py
... / ...
CommitLineData
1## @file\r
2# generate capsule\r
3#\r
4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials\r
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
18from GenFdsGlobalVariable import GenFdsGlobalVariable\r
19from CommonDataClass.FdfClass import CapsuleClassObject\r
20import Common.LongFilePathOs as os\r
21import subprocess\r
22import StringIO\r
23from Common.Misc import SaveFileOnChange\r
24from GenFds import GenFds\r
25from Common.Misc import PackRegistryFormatGuid\r
26import uuid\r
27from struct import pack\r
28\r
29\r
30T_CHAR_LF = '\n'\r
31\r
32## create inf file describes what goes into capsule and call GenFv to generate capsule\r
33#\r
34#\r
35class Capsule (CapsuleClassObject) :\r
36 ## The constructor\r
37 #\r
38 # @param self The object pointer\r
39 #\r
40 def __init__(self):\r
41 CapsuleClassObject.__init__(self)\r
42 # For GenFv\r
43 self.BlockSize = None\r
44 # For GenFv\r
45 self.BlockNum = None\r
46 self.CapsuleName = None\r
47\r
48 ## Generate FMP capsule\r
49 #\r
50 # @retval string Generated Capsule file path\r
51 #\r
52 def GenFmpCapsule(self):\r
53 #\r
54 # Generate capsule header\r
55 # typedef struct {\r
56 # EFI_GUID CapsuleGuid;\r
57 # UINT32 HeaderSize;\r
58 # UINT32 Flags;\r
59 # UINT32 CapsuleImageSize;\r
60 # } EFI_CAPSULE_HEADER;\r
61 #\r
62 Header = StringIO.StringIO()\r
63 #\r
64 # Use FMP capsule GUID: 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A\r
65 #\r
66 Header.write(PackRegistryFormatGuid('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A'))\r
67 HdrSize = 0\r
68 if 'CAPSULE_HEADER_SIZE' in self.TokensDict:\r
69 Header.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16)))\r
70 HdrSize = int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16)\r
71 else:\r
72 Header.write(pack('=I', 0x20))\r
73 HdrSize = 0x20\r
74 Flags = 0\r
75 if 'CAPSULE_FLAGS' in self.TokensDict:\r
76 for flag in self.TokensDict['CAPSULE_FLAGS'].split(','):\r
77 flag = flag.strip()\r
78 if flag == 'PopulateSystemTable':\r
79 Flags |= 0x00010000 | 0x00020000\r
80 elif flag == 'PersistAcrossReset':\r
81 Flags |= 0x00010000\r
82 elif flag == 'InitiateReset':\r
83 Flags |= 0x00040000\r
84 Header.write(pack('=I', Flags))\r
85 #\r
86 # typedef struct {\r
87 # UINT32 Version;\r
88 # UINT16 EmbeddedDriverCount;\r
89 # UINT16 PayloadItemCount;\r
90 # // UINT64 ItemOffsetList[];\r
91 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;\r
92 #\r
93 FwMgrHdr = StringIO.StringIO()\r
94 if 'CAPSULE_HEADER_INIT_VERSION' in self.TokensDict:\r
95 FwMgrHdr.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_INIT_VERSION'], 16)))\r
96 else:\r
97 FwMgrHdr.write(pack('=I', 0x00000001))\r
98 FwMgrHdr.write(pack('=HH', len(self.CapsuleDataList), len(self.FmpPayloadList)))\r
99 FwMgrHdrSize = 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList))\r
100\r
101 PreSize = FwMgrHdrSize\r
102 Content = StringIO.StringIO()\r
103 for driver in self.CapsuleDataList:\r
104 FileName = driver.GenCapsuleSubItem()\r
105 FwMgrHdr.write(pack('=Q', PreSize))\r
106 PreSize += os.path.getsize(FileName)\r
107 File = open(FileName, 'rb')\r
108 Content.write(File.read())\r
109 File.close()\r
110 for fmp in self.FmpPayloadList:\r
111 payload = fmp.GenCapsuleSubItem()\r
112 FwMgrHdr.write(pack('=Q', PreSize))\r
113 PreSize += len(payload)\r
114 Content.write(payload)\r
115 BodySize = len(FwMgrHdr.getvalue()) + len(Content.getvalue())\r
116 Header.write(pack('=I', HdrSize + BodySize))\r
117 #\r
118 # The real capsule header structure is 28 bytes\r
119 #\r
120 Header.write('\x00'*(HdrSize-28))\r
121 Header.write(FwMgrHdr.getvalue())\r
122 Header.write(Content.getvalue())\r
123 #\r
124 # Generate FMP capsule file\r
125 #\r
126 CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.Cap'\r
127 SaveFileOnChange(CapOutputFile, Header.getvalue(), True)\r
128 return CapOutputFile\r
129\r
130 ## Generate capsule\r
131 #\r
132 # @param self The object pointer\r
133 # @retval string Generated Capsule file path\r
134 #\r
135 def GenCapsule(self):\r
136 if self.UiCapsuleName.upper() + 'cap' in GenFds.ImageBinDict.keys():\r
137 return GenFds.ImageBinDict[self.UiCapsuleName.upper() + 'cap']\r
138\r
139 GenFdsGlobalVariable.InfLogger( "\nGenerate %s Capsule" %self.UiCapsuleName)\r
140 if ('CAPSULE_GUID' in self.TokensDict and \r
141 uuid.UUID(self.TokensDict['CAPSULE_GUID']) == uuid.UUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')):\r
142 return self.GenFmpCapsule()\r
143\r
144 CapInfFile = self.GenCapInf()\r
145 CapInfFile.writelines("[files]" + T_CHAR_LF)\r
146 CapFileList = []\r
147 for CapsuleDataObj in self.CapsuleDataList :\r
148 CapsuleDataObj.CapsuleName = self.CapsuleName\r
149 FileName = CapsuleDataObj.GenCapsuleSubItem()\r
150 CapsuleDataObj.CapsuleName = None\r
151 CapFileList.append(FileName)\r
152 CapInfFile.writelines("EFI_FILE_NAME = " + \\r
153 FileName + \\r
154 T_CHAR_LF)\r
155 SaveFileOnChange(self.CapInfFileName, CapInfFile.getvalue(), False)\r
156 CapInfFile.close()\r
157 #\r
158 # Call GenFv tool to generate capsule\r
159 #\r
160 CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName)\r
161 CapOutputFile = CapOutputFile + '.Cap'\r
162 GenFdsGlobalVariable.GenerateFirmwareVolume(\r
163 CapOutputFile,\r
164 [self.CapInfFileName],\r
165 Capsule=True,\r
166 FfsList=CapFileList\r
167 )\r
168\r
169 GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s Capsule Successfully" %self.UiCapsuleName)\r
170 GenFdsGlobalVariable.SharpCounter = 0\r
171 GenFds.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] = CapOutputFile\r
172 return CapOutputFile\r
173\r
174 ## Generate inf file for capsule\r
175 #\r
176 # @param self The object pointer\r
177 # @retval file inf file object\r
178 #\r
179 def GenCapInf(self):\r
180 self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir,\r
181 self.UiCapsuleName + "_Cap" + '.inf')\r
182 CapInfFile = StringIO.StringIO() #open (self.CapInfFileName , 'w+')\r
183\r
184 CapInfFile.writelines("[options]" + T_CHAR_LF)\r
185\r
186 for Item in self.TokensDict.keys():\r
187 CapInfFile.writelines("EFI_" + \\r
188 Item + \\r
189 ' = ' + \\r
190 self.TokensDict.get(Item) + \\r
191 T_CHAR_LF)\r
192\r
193 return CapInfFile\r