]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Fv.py
773b0efbe81f073a5c687b334db207dec705f4fd
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
53 # Generate Fv and add it to the Buffer
55 # @param self The object pointer
56 # @param Buffer The buffer generated FV data will be put
57 # @param BaseAddress base address of FV
58 # @param BlockSize block size of FV
59 # @param BlockNum How many blocks in FV
60 # @param ErasePolarity Flash erase polarity
61 # @param VtfDict VTF objects
62 # @param MacroDict macro value pair
63 # @retval string Generated FV file path
65 def AddToBuffer (self
, Buffer
, BaseAddress
=None, BlockSize
= None, BlockNum
=None, ErasePloarity
='1', VtfDict
=None, MacroDict
= {}) :
67 if BaseAddress
== None and self
.UiFvName
.upper() + 'fv' in GenFds
.ImageBinDict
.keys():
68 return GenFds
.ImageBinDict
[self
.UiFvName
.upper() + 'fv']
71 # Check whether FV in Capsule is in FD flash region.
72 # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.
74 if self
.CapsuleName
!= None:
75 for FdName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
76 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[FdName
]
77 for RegionObj
in FdObj
.RegionList
:
78 if RegionObj
.RegionType
== 'FV':
79 for RegionData
in RegionObj
.RegionDataList
:
80 if RegionData
.endswith(".fv"):
82 elif RegionData
.upper() + 'fv' in GenFds
.ImageBinDict
.keys():
84 elif self
.UiFvName
.upper() == RegionData
.upper():
85 GenFdsGlobalVariable
.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self
.CapsuleName
, self
.UiFvName
.upper()))
87 GenFdsGlobalVariable
.InfLogger( "\nGenerating %s FV" %self
.UiFvName
)
89 if self
.FvBaseAddress
!= None:
90 BaseAddress
= self
.FvBaseAddress
92 self
.__InitializeInf
__(BaseAddress
, BlockSize
, BlockNum
, ErasePloarity
, VtfDict
)
94 # First Process the Apriori section
96 MacroDict
.update(self
.DefineVarDict
)
98 GenFdsGlobalVariable
.VerboseLogger('First generate Apriori file !')
100 for AprSection
in self
.AprioriSectionList
:
101 FileName
= AprSection
.GenFfs (self
.UiFvName
, MacroDict
)
102 FfsFileList
.append(FileName
)
103 # Add Apriori file name to Inf file
104 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
108 # Process Modules in FfsList
109 for FfsFile
in self
.FfsList
:
110 FileName
= FfsFile
.GenFfs(MacroDict
, FvParentAddr
=BaseAddress
)
111 FfsFileList
.append(FileName
)
112 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
116 SaveFileOnChange(self
.InfFileName
, self
.FvInfFile
.getvalue(), False)
117 self
.FvInfFile
.close()
121 FvOutputFile
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, self
.UiFvName
)
122 FvOutputFile
= FvOutputFile
+ '.Fv'
123 # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
124 if self
.CreateFileName
!= None:
125 FvOutputFile
= self
.CreateFileName
127 FvInfoFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.UiFvName
+ '.inf')
128 shutil
.copy(GenFdsGlobalVariable
.FvAddressFileName
, FvInfoFileName
)
130 if os
.path
.exists (FvInfoFileName
):
131 OrigFvInfo
= open(FvInfoFileName
, 'r').read()
132 GenFdsGlobalVariable
.GenerateFirmwareVolume(
135 AddressFile
=FvInfoFileName
,
140 if os
.path
.exists (FvInfoFileName
):
141 NewFvInfo
= open(FvInfoFileName
, 'r').read()
142 if NewFvInfo
!= None and NewFvInfo
!= OrigFvInfo
:
144 AddFileObj
= open(FvInfoFileName
, 'r')
145 AddrStrings
= AddFileObj
.readlines()
147 for AddrString
in AddrStrings
:
149 #get base address for the inside FvImage
150 FvChildAddr
.append (AddrString
)
151 elif AddrString
.find ("[FV_BASE_ADDRESS]") != -1:
155 if FvChildAddr
!= []:
157 for FfsFile
in self
.FfsList
:
158 FileName
= FfsFile
.GenFfs(MacroDict
, FvChildAddr
, BaseAddress
)
161 GenFdsGlobalVariable
.GenerateFirmwareVolume(
164 AddressFile
=FvInfoFileName
,
169 # Write the Fv contents to Buffer
171 FvFileObj
= open ( FvOutputFile
,'r+b')
173 GenFdsGlobalVariable
.VerboseLogger( "\nGenerate %s FV Successfully" %self
.UiFvName
)
174 GenFdsGlobalVariable
.SharpCounter
= 0
176 Buffer
.write(FvFileObj
.read())
178 # PI FvHeader is 0x48 byte
179 FvHeaderBuffer
= FvFileObj
.read(0x48)
180 # FV alignment position.
181 FvAlignmentValue
= 1 << (ord (FvHeaderBuffer
[0x2E]) & 0x1F)
182 # FvAlignmentValue is larger than or equal to 1K
183 if FvAlignmentValue
>= 0x400:
184 if FvAlignmentValue
>= 0x10000:
185 #The max alignment supported by FFS is 64K.
186 self
.FvAlignment
= "64K"
188 self
.FvAlignment
= str (FvAlignmentValue
/ 0x400) + "K"
190 # FvAlignmentValue is less than 1K
191 self
.FvAlignment
= str (FvAlignmentValue
)
193 GenFds
.ImageBinDict
[self
.UiFvName
.upper() + 'fv'] = FvOutputFile
196 ## __InitializeInf__()
198 # Initilize the inf file to create FV
200 # @param self The object pointer
201 # @param BaseAddress base address of FV
202 # @param BlockSize block size of FV
203 # @param BlockNum How many blocks in FV
204 # @param ErasePolarity Flash erase polarity
205 # @param VtfDict VTF objects
207 def __InitializeInf__ (self
, BaseAddress
= None, BlockSize
= None, BlockNum
= None, ErasePloarity
='1', VtfDict
=None) :
211 self
.InfFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
,
212 self
.UiFvName
+ '.inf')
213 self
.FvInfFile
= StringIO
.StringIO()
218 self
.FvInfFile
.writelines("[options]" + T_CHAR_LF
)
219 if BaseAddress
!= None :
220 self
.FvInfFile
.writelines("EFI_BASE_ADDRESS = " + \
224 if BlockSize
!= None:
225 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = " + \
226 '0x%X' %BlockSize
+ \
229 self
.FvInfFile
.writelines("EFI_NUM_BLOCKS = " + \
230 ' 0x%X' %BlockNum
+ \
233 if self
.BlockSizeList
== []:
234 #set default block size is 1
235 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = 0x1" + T_CHAR_LF
)
237 for BlockSize
in self
.BlockSizeList
:
238 if BlockSize
[0] != None:
239 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = " + \
240 '0x%X' %BlockSize
[0] + \
243 if BlockSize
[1] != None:
244 self
.FvInfFile
.writelines("EFI_NUM_BLOCKS = " + \
245 ' 0x%X' %BlockSize
[1] + \
248 if self
.BsBaseAddress
!= None:
249 self
.FvInfFile
.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \
250 '0x%X' %self
.BsBaseAddress
)
251 if self
.RtBaseAddress
!= None:
252 self
.FvInfFile
.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \
253 '0x%X' %self
.RtBaseAddress
)
257 self
.FvInfFile
.writelines("[attributes]" + T_CHAR_LF
)
259 self
.FvInfFile
.writelines("EFI_ERASE_POLARITY = " + \
260 ' %s' %ErasePloarity
+ \
262 if not (self
.FvAttributeDict
== None):
263 for FvAttribute
in self
.FvAttributeDict
.keys() :
264 self
.FvInfFile
.writelines("EFI_" + \
267 self
.FvAttributeDict
[FvAttribute
] + \
269 if self
.FvAlignment
!= None:
270 self
.FvInfFile
.writelines("EFI_FVB2_ALIGNMENT_" + \
271 self
.FvAlignment
.strip() + \
276 # Generate FV extension header file
278 if self
.FvNameGuid
== None or self
.FvNameGuid
== '':
279 if len(self
.FvExtEntryType
) > 0:
280 GenFdsGlobalVariable
.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self
.UiFvName
))
282 if self
.FvNameGuid
<> None and self
.FvNameGuid
<> '':
285 for Index
in range (0, len(self
.FvExtEntryType
)):
286 if self
.FvExtEntryType
[Index
] == 'FILE':
287 # check if the path is absolute or relative
288 if os
.path
.isabs(self
.FvExtEntryData
[Index
]):
289 FileFullPath
= os
.path
.normpath(self
.FvExtEntryData
[Index
])
291 FileFullPath
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.FvExtEntryData
[Index
]))
292 # check if the file path exists or not
293 if not os
.path
.isfile(FileFullPath
):
294 GenFdsGlobalVariable
.ErrorLogger("Error opening FV Extension Header Entry file %s." % (self
.FvExtEntryData
[Index
]))
295 FvExtFile
= open (FileFullPath
,'rb')
297 Size
= FvExtFile
.tell()
299 GenFdsGlobalVariable
.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self
.FvExtEntryData
[Index
]))
300 TotalSize
+= (Size
+ 4)
302 Buffer
+= pack('HH', (Size
+ 4), int(self
.FvExtEntryTypeValue
[Index
], 16))
303 Buffer
+= FvExtFile
.read()
305 if self
.FvExtEntryType
[Index
] == 'DATA':
306 ByteList
= self
.FvExtEntryData
[Index
].split(',')
307 Size
= len (ByteList
)
309 GenFdsGlobalVariable
.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self
.FvExtEntryData
[Index
]))
310 TotalSize
+= (Size
+ 4)
311 Buffer
+= pack('HH', (Size
+ 4), int(self
.FvExtEntryTypeValue
[Index
], 16))
312 for Index1
in range (0, Size
):
313 Buffer
+= pack('B', int(ByteList
[Index1
], 16))
315 Guid
= self
.FvNameGuid
.split('-')
316 Buffer
= pack('LHHBBBBBBBBL',
320 int(Guid
[3][-4:-2], 16),
321 int(Guid
[3][-2:], 16),
322 int(Guid
[4][-12:-10], 16),
323 int(Guid
[4][-10:-8], 16),
324 int(Guid
[4][-8:-6], 16),
325 int(Guid
[4][-6:-4], 16),
326 int(Guid
[4][-4:-2], 16),
327 int(Guid
[4][-2:], 16),
332 # Generate FV extension header file if the total size is not zero
335 FvExtHeaderFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, self
.UiFvName
+ '.ext')
336 FvExtHeaderFile
= StringIO
.StringIO()
337 FvExtHeaderFile
.write(Buffer
)
338 Changed
= SaveFileOnChange(FvExtHeaderFileName
, FvExtHeaderFile
.getvalue(), True)
339 FvExtHeaderFile
.close()
341 if os
.path
.exists (self
.InfFileName
):
342 os
.remove (self
.InfFileName
)
343 self
.FvInfFile
.writelines("EFI_FV_EXT_HEADER_FILE_NAME = " + \
344 FvExtHeaderFileName
+ \
351 self
.FvInfFile
.writelines("[files]" + T_CHAR_LF
)
352 if VtfDict
!= None and self
.UiFvName
in VtfDict
.keys():
353 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
354 VtfDict
.get(self
.UiFvName
) + \