]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Fv.py
2 # process FV generation
4 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 from GenFdsGlobalVariable
import GenFdsGlobalVariable
27 from GenFds
import GenFds
28 from CommonDataClass
.FdfClass
import FvClassObject
29 from Common
.Misc
import SaveFileOnChange
36 class FV (FvClassObject
):
39 # @param self The object pointer
42 FvClassObject
.__init
__(self
)
44 self
.FvAddressFile
= None
45 self
.BaseAddress
= None
46 self
.InfFileName
= None
47 self
.FvAddressFileName
= None
48 self
.CapsuleName
= None
49 self
.FvBaseAddress
= None
50 self
.FvForceRebase
= None
54 # Generate Fv and add it to the Buffer
56 # @param self The object pointer
57 # @param Buffer The buffer generated FV data will be put
58 # @param BaseAddress base address of FV
59 # @param BlockSize block size of FV
60 # @param BlockNum How many blocks in FV
61 # @param ErasePolarity Flash erase polarity
62 # @param VtfDict VTF objects
63 # @param MacroDict macro value pair
64 # @retval string Generated FV file path
66 def AddToBuffer (self
, Buffer
, BaseAddress
=None, BlockSize
= None, BlockNum
=None, ErasePloarity
='1', VtfDict
=None, MacroDict
= {}) :
68 if BaseAddress
== None and self
.UiFvName
.upper() + 'fv' in GenFds
.ImageBinDict
.keys():
69 return GenFds
.ImageBinDict
[self
.UiFvName
.upper() + 'fv']
72 # Check whether FV in Capsule is in FD flash region.
73 # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.
75 if self
.CapsuleName
!= None:
76 for FdName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
77 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[FdName
]
78 for RegionObj
in FdObj
.RegionList
:
79 if RegionObj
.RegionType
== 'FV':
80 for RegionData
in RegionObj
.RegionDataList
:
81 if RegionData
.endswith(".fv"):
83 elif RegionData
.upper() + 'fv' in GenFds
.ImageBinDict
.keys():
85 elif self
.UiFvName
.upper() == RegionData
.upper():
86 GenFdsGlobalVariable
.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self
.CapsuleName
, self
.UiFvName
.upper()))
88 GenFdsGlobalVariable
.InfLogger( "\nGenerating %s FV" %self
.UiFvName
)
90 if self
.FvBaseAddress
!= None:
91 BaseAddress
= self
.FvBaseAddress
93 self
.__InitializeInf
__(BaseAddress
, BlockSize
, BlockNum
, ErasePloarity
, VtfDict
)
95 # First Process the Apriori section
97 MacroDict
.update(self
.DefineVarDict
)
99 GenFdsGlobalVariable
.VerboseLogger('First generate Apriori file !')
101 for AprSection
in self
.AprioriSectionList
:
102 FileName
= AprSection
.GenFfs (self
.UiFvName
, MacroDict
)
103 FfsFileList
.append(FileName
)
104 # Add Apriori file name to Inf file
105 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
109 # Process Modules in FfsList
110 for FfsFile
in self
.FfsList
:
111 FileName
= FfsFile
.GenFfs(MacroDict
, FvParentAddr
=BaseAddress
)
112 FfsFileList
.append(FileName
)
113 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
117 SaveFileOnChange(self
.InfFileName
, self
.FvInfFile
.getvalue(), False)
118 self
.FvInfFile
.close()
122 FvOutputFile
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, self
.UiFvName
)
123 FvOutputFile
= FvOutputFile
+ '.Fv'
124 # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
125 if self
.CreateFileName
!= None:
126 FvOutputFile
= self
.CreateFileName
128 FvInfoFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.UiFvName
+ '.inf')
129 shutil
.copy(GenFdsGlobalVariable
.FvAddressFileName
, FvInfoFileName
)
131 if os
.path
.exists (FvInfoFileName
):
132 OrigFvInfo
= open(FvInfoFileName
, 'r').read()
133 GenFdsGlobalVariable
.GenerateFirmwareVolume(
136 AddressFile
=FvInfoFileName
,
138 ForceRebase
=self
.FvForceRebase
142 if os
.path
.exists (FvInfoFileName
):
143 NewFvInfo
= open(FvInfoFileName
, 'r').read()
144 if NewFvInfo
!= None and NewFvInfo
!= OrigFvInfo
:
146 AddFileObj
= open(FvInfoFileName
, 'r')
147 AddrStrings
= AddFileObj
.readlines()
149 for AddrString
in AddrStrings
:
151 #get base address for the inside FvImage
152 FvChildAddr
.append (AddrString
)
153 elif AddrString
.find ("[FV_BASE_ADDRESS]") != -1:
157 if FvChildAddr
!= []:
159 for FfsFile
in self
.FfsList
:
160 FileName
= FfsFile
.GenFfs(MacroDict
, FvChildAddr
, BaseAddress
)
163 GenFdsGlobalVariable
.GenerateFirmwareVolume(
166 AddressFile
=FvInfoFileName
,
168 ForceRebase
=self
.FvForceRebase
172 # Write the Fv contents to Buffer
174 FvFileObj
= open ( FvOutputFile
,'r+b')
176 GenFdsGlobalVariable
.VerboseLogger( "\nGenerate %s FV Successfully" %self
.UiFvName
)
177 GenFdsGlobalVariable
.SharpCounter
= 0
179 Buffer
.write(FvFileObj
.read())
181 # PI FvHeader is 0x48 byte
182 FvHeaderBuffer
= FvFileObj
.read(0x48)
183 # FV alignment position.
184 FvAlignmentValue
= 1 << (ord (FvHeaderBuffer
[0x2E]) & 0x1F)
185 # FvAlignmentValue is larger than or equal to 1K
186 if FvAlignmentValue
>= 0x400:
187 if FvAlignmentValue
>= 0x10000:
188 #The max alignment supported by FFS is 64K.
189 self
.FvAlignment
= "64K"
191 self
.FvAlignment
= str (FvAlignmentValue
/ 0x400) + "K"
193 # FvAlignmentValue is less than 1K
194 self
.FvAlignment
= str (FvAlignmentValue
)
196 GenFds
.ImageBinDict
[self
.UiFvName
.upper() + 'fv'] = FvOutputFile
199 ## __InitializeInf__()
201 # Initilize the inf file to create FV
203 # @param self The object pointer
204 # @param BaseAddress base address of FV
205 # @param BlockSize block size of FV
206 # @param BlockNum How many blocks in FV
207 # @param ErasePolarity Flash erase polarity
208 # @param VtfDict VTF objects
210 def __InitializeInf__ (self
, BaseAddress
= None, BlockSize
= None, BlockNum
= None, ErasePloarity
='1', VtfDict
=None) :
214 self
.InfFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
,
215 self
.UiFvName
+ '.inf')
216 self
.FvInfFile
= StringIO
.StringIO()
221 self
.FvInfFile
.writelines("[options]" + T_CHAR_LF
)
222 if BaseAddress
!= None :
223 self
.FvInfFile
.writelines("EFI_BASE_ADDRESS = " + \
227 if BlockSize
!= None:
228 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = " + \
229 '0x%X' %BlockSize
+ \
232 self
.FvInfFile
.writelines("EFI_NUM_BLOCKS = " + \
233 ' 0x%X' %BlockNum
+ \
236 if self
.BlockSizeList
== []:
237 #set default block size is 1
238 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = 0x1" + T_CHAR_LF
)
240 for BlockSize
in self
.BlockSizeList
:
241 if BlockSize
[0] != None:
242 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = " + \
243 '0x%X' %BlockSize
[0] + \
246 if BlockSize
[1] != None:
247 self
.FvInfFile
.writelines("EFI_NUM_BLOCKS = " + \
248 ' 0x%X' %BlockSize
[1] + \
251 if self
.BsBaseAddress
!= None:
252 self
.FvInfFile
.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \
253 '0x%X' %self
.BsBaseAddress
)
254 if self
.RtBaseAddress
!= None:
255 self
.FvInfFile
.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \
256 '0x%X' %self
.RtBaseAddress
)
260 self
.FvInfFile
.writelines("[attributes]" + T_CHAR_LF
)
262 self
.FvInfFile
.writelines("EFI_ERASE_POLARITY = " + \
263 ' %s' %ErasePloarity
+ \
265 if not (self
.FvAttributeDict
== None):
266 for FvAttribute
in self
.FvAttributeDict
.keys() :
267 self
.FvInfFile
.writelines("EFI_" + \
270 self
.FvAttributeDict
[FvAttribute
] + \
272 if self
.FvAlignment
!= None:
273 self
.FvInfFile
.writelines("EFI_FVB2_ALIGNMENT_" + \
274 self
.FvAlignment
.strip() + \
279 # Generate FV extension header file
281 if self
.FvNameGuid
== None or self
.FvNameGuid
== '':
282 if len(self
.FvExtEntryType
) > 0:
283 GenFdsGlobalVariable
.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self
.UiFvName
))
285 if self
.FvNameGuid
<> None and self
.FvNameGuid
<> '':
288 for Index
in range (0, len(self
.FvExtEntryType
)):
289 if self
.FvExtEntryType
[Index
] == 'FILE':
290 # check if the path is absolute or relative
291 if os
.path
.isabs(self
.FvExtEntryData
[Index
]):
292 FileFullPath
= os
.path
.normpath(self
.FvExtEntryData
[Index
])
294 FileFullPath
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.FvExtEntryData
[Index
]))
295 # check if the file path exists or not
296 if not os
.path
.isfile(FileFullPath
):
297 GenFdsGlobalVariable
.ErrorLogger("Error opening FV Extension Header Entry file %s." % (self
.FvExtEntryData
[Index
]))
298 FvExtFile
= open (FileFullPath
,'rb')
300 Size
= FvExtFile
.tell()
302 GenFdsGlobalVariable
.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self
.FvExtEntryData
[Index
]))
303 TotalSize
+= (Size
+ 4)
305 Buffer
+= pack('HH', (Size
+ 4), int(self
.FvExtEntryTypeValue
[Index
], 16))
306 Buffer
+= FvExtFile
.read()
308 if self
.FvExtEntryType
[Index
] == 'DATA':
309 ByteList
= self
.FvExtEntryData
[Index
].split(',')
310 Size
= len (ByteList
)
312 GenFdsGlobalVariable
.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self
.FvExtEntryData
[Index
]))
313 TotalSize
+= (Size
+ 4)
314 Buffer
+= pack('HH', (Size
+ 4), int(self
.FvExtEntryTypeValue
[Index
], 16))
315 for Index1
in range (0, Size
):
316 Buffer
+= pack('B', int(ByteList
[Index1
], 16))
318 Guid
= self
.FvNameGuid
.split('-')
319 Buffer
= pack('LHHBBBBBBBBL',
323 int(Guid
[3][-4:-2], 16),
324 int(Guid
[3][-2:], 16),
325 int(Guid
[4][-12:-10], 16),
326 int(Guid
[4][-10:-8], 16),
327 int(Guid
[4][-8:-6], 16),
328 int(Guid
[4][-6:-4], 16),
329 int(Guid
[4][-4:-2], 16),
330 int(Guid
[4][-2:], 16),
335 # Generate FV extension header file if the total size is not zero
338 FvExtHeaderFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, self
.UiFvName
+ '.ext')
339 FvExtHeaderFile
= StringIO
.StringIO()
340 FvExtHeaderFile
.write(Buffer
)
341 Changed
= SaveFileOnChange(FvExtHeaderFileName
, FvExtHeaderFile
.getvalue(), True)
342 FvExtHeaderFile
.close()
344 if os
.path
.exists (self
.InfFileName
):
345 os
.remove (self
.InfFileName
)
346 self
.FvInfFile
.writelines("EFI_FV_EXT_HEADER_FILE_NAME = " + \
347 FvExtHeaderFileName
+ \
354 self
.FvInfFile
.writelines("[files]" + T_CHAR_LF
)
355 if VtfDict
!= None and self
.UiFvName
in VtfDict
.keys():
356 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
357 VtfDict
.get(self
.UiFvName
) + \