2 # process FFS generation from INF statement
4 # Copyright (c) 2007 - 2011, 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.
23 from GenFdsGlobalVariable
import GenFdsGlobalVariable
29 import RuleComplexFile
30 from CommonDataClass
.FdfClass
import FfsInfStatementClassObject
31 from Common
.String
import *
32 from Common
.Misc
import PathClass
33 from Common
.Misc
import GuidStructureByteArrayToGuidString
34 from Common
import EdkLogger
35 from Common
.BuildToolError
import *
36 from GuidSection
import GuidSection
37 from FvImageSection
import FvImageSection
38 from Common
.Misc
import PeImageClass
39 from AutoGen
.GenDepex
import DependencyExpression
41 ## generate FFS from INF
44 class FfsInfStatement(FfsInfStatementClassObject
):
47 # @param self The object pointer
50 FfsInfStatementClassObject
.__init
__(self
)
51 self
.TargetOverrideList
= []
52 self
.ShadowFromInfFile
= None
53 self
.KeepRelocFromRule
= None
56 self
.PiSpecVersion
= '0x00000000'
58 self
.FinalTargetSuffixMap
= {}
59 self
.CurrentLineNum
= None
60 self
.CurrentLineContent
= None
62 self
.InfFileName
= None
64 ## GetFinalTargetSuffixMap() method
66 # Get final build target list
67 def GetFinalTargetSuffixMap(self
):
68 if not self
.InfModule
or not self
.CurrentArch
:
70 if not self
.FinalTargetSuffixMap
:
71 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
72 for File
in FinalBuildTargetList
:
73 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
75 # Check if current INF module has DEPEX
76 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= "USER_DEFINED" \
77 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
78 ModuleType
= self
.InfModule
.ModuleType
79 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
81 if ModuleType
!= DataType
.SUP_MODULE_USER_DEFINED
:
82 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
83 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
84 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
86 StrModule
= str(self
.InfModule
)
88 if StrModule
in PlatformDataBase
.Modules
:
89 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
90 for LibraryClass
in PlatformModule
.LibraryClasses
:
91 if LibraryClass
.startswith("NULL"):
92 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
94 DependencyList
= [self
.InfModule
]
97 while len(DependencyList
) > 0:
98 Module
= DependencyList
.pop(0)
101 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
103 DepexList
.append('AND')
104 DepexList
.append('(')
105 DepexList
.extend(Dep
)
106 if DepexList
[-1] == 'END': # no need of a END at this time
108 DepexList
.append(')')
109 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
111 for LibName
in Module
.LibraryClasses
:
112 if LibName
in LibraryInstance
:
114 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
115 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
117 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
119 LibraryPath
= Module
.LibraryClasses
[LibName
]
122 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
123 LibraryInstance
[LibName
] = LibraryModule
124 DependencyList
.append(LibraryModule
)
126 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
127 if len(Dpx
.PostfixNotation
) != 0:
128 # It means this module has DEPEX
129 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
130 return self
.FinalTargetSuffixMap
132 ## __InfParse() method
134 # Parse inf file to get module information
136 # @param self The object pointer
137 # @param Dict dictionary contains macro and value pair
139 def __InfParse__(self
, Dict
= {}):
141 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
143 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
144 if self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
145 self
.InfFileName
= self
.InfFileName
[1:]
147 if self
.InfFileName
.find('$') == -1:
148 InfPath
= NormPath(self
.InfFileName
)
149 if not os
.path
.exists(InfPath
):
150 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
151 if not os
.path
.exists(InfPath
):
152 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
154 self
.CurrentArch
= self
.GetCurrentArch()
156 # Get the InfClass object
159 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
160 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
162 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
164 if self
.CurrentArch
!= None:
166 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
168 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
170 self
.BaseName
= Inf
.BaseName
171 self
.ModuleGuid
= Inf
.Guid
172 self
.ModuleType
= Inf
.ModuleType
173 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
174 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
175 if Inf
.AutoGenVersion
< 0x00010005:
176 self
.ModuleType
= Inf
.ComponentType
177 self
.VersionString
= Inf
.Version
178 self
.BinFileList
= Inf
.Binaries
179 self
.SourceFileList
= Inf
.Sources
180 if self
.KeepReloc
== None and Inf
.Shadow
:
181 self
.ShadowFromInfFile
= Inf
.Shadow
184 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
185 self
.BaseName
= Inf
.BaseName
186 self
.ModuleGuid
= Inf
.Guid
187 self
.ModuleType
= Inf
.ModuleType
188 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
189 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
190 self
.VersionString
= Inf
.Version
191 self
.BinFileList
= Inf
.Binaries
192 self
.SourceFileList
= Inf
.Sources
193 if self
.BinFileList
== []:
194 EdkLogger
.error("GenFds", GENFDS_ERROR
,
195 "INF %s specified in FDF could not be found in build ARCH %s!" \
196 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
198 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
199 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
201 if self
.ModuleType
== 'SMM_CORE' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
202 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File
=self
.InfFileName
)
204 if Inf
._Defs
!= None and len(Inf
._Defs
) > 0:
205 self
.OptRomDefs
.update(Inf
._Defs
)
209 GenFdsGlobalVariable
.VerboseLogger( "BaseName : %s" %self
.BaseName
)
210 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" %self
.ModuleGuid
)
211 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" %self
.ModuleType
)
212 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" %self
.VersionString
)
213 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" %self
.InfFileName
)
216 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
219 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
220 self
.ModuleGuid
+ self
.BaseName
)
221 if not os
.path
.exists(self
.OutputPath
) :
222 os
.makedirs(self
.OutputPath
)
224 self
.EfiOutputPath
= self
.__GetEFIOutPutPath
__()
225 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
231 # @param self The object pointer
232 # @param Dict dictionary contains macro and value pair
233 # @param FvChildAddr Array of the inside FvImage base address
234 # @param FvParentAddr Parent Fv base address
235 # @retval string Generated FFS file name
237 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None):
239 # Parse Inf file get Module related information
242 self
.__InfParse
__(Dict
)
245 # Allow binary type module not specify override rule in FDF file.
247 if len(self
.BinFileList
) >0 and not self
.InDsc
:
248 if self
.Rule
== None or self
.Rule
== "":
252 # Get the rule of how to generate Ffs file
254 Rule
= self
.__GetRule
__()
255 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
257 # Convert Fv File Type for PI1.1 SMM driver.
259 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
260 if Rule
.FvFileType
== 'DRIVER':
261 Rule
.FvFileType
= 'SMM'
263 # Framework SMM Driver has no SMM FV file type
265 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
266 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== 'SMM_CORE':
267 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
269 # For the rule only has simpleFile
271 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
272 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
)
273 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
)
276 # For Rule has ComplexFile
278 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
279 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
)
280 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
)
284 ## __ExtendMacro__() method
286 # Replace macro with its value
288 # @param self The object pointer
289 # @param String The string to be replaced
290 # @retval string Macro replaced string
292 def __ExtendMacro__ (self
, String
):
294 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
295 '$(MODULE_NAME)' : self
.BaseName
,
296 '$(BUILD_NUMBER)': self
.BuildNum
,
297 '$(INF_VERSION)' : self
.VersionString
,
298 '$(NAMED_GUID)' : self
.ModuleGuid
300 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
303 ## __GetRule__() method
305 # Get correct rule for generating FFS for this INF
307 # @param self The object pointer
308 # @retval Rule Rule object
310 def __GetRule__ (self
) :
312 if self
.CurrentArch
== None:
313 CurrentArchList
= ['common']
315 CurrentArchList
.append(self
.CurrentArch
)
317 for CurrentArch
in CurrentArchList
:
318 RuleName
= 'RULE' + \
320 CurrentArch
.upper() + \
322 self
.ModuleType
.upper()
323 if self
.Rule
!= None:
324 RuleName
= RuleName
+ \
328 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
330 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
333 RuleName
= 'RULE' + \
337 self
.ModuleType
.upper()
339 if self
.Rule
!= None:
340 RuleName
= RuleName
+ \
344 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
346 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
348 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
352 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
353 % (RuleName
, self
.InfFileName
))
355 ## __GetPlatformArchList__() method
357 # Get Arch list this INF built under
359 # @param self The object pointer
360 # @retval list Arch list
362 def __GetPlatformArchList__(self
):
364 InfFileKey
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
366 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IA32', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
367 if PlatformDataBase
!= None:
368 if InfFileKey
in PlatformDataBase
.Modules
:
369 DscArchList
.append ('IA32')
371 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'X64', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
372 if PlatformDataBase
!= None:
373 if InfFileKey
in PlatformDataBase
.Modules
:
374 DscArchList
.append ('X64')
376 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IPF', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
377 if PlatformDataBase
!= None:
378 if InfFileKey
in (PlatformDataBase
.Modules
):
379 DscArchList
.append ('IPF')
381 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'ARM', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
382 if PlatformDataBase
!= None:
383 if InfFileKey
in (PlatformDataBase
.Modules
):
384 DscArchList
.append ('ARM')
386 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'EBC', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
387 if PlatformDataBase
!= None:
388 if InfFileKey
in (PlatformDataBase
.Modules
):
389 DscArchList
.append ('EBC')
393 ## GetCurrentArch() method
395 # Get Arch list of the module from this INF is to be placed into flash
397 # @param self The object pointer
398 # @retval list Arch list
400 def GetCurrentArch(self
) :
402 TargetArchList
= GenFdsGlobalVariable
.ArchList
404 PlatformArchList
= self
.__GetPlatformArchList
__()
406 CurArchList
= TargetArchList
407 if PlatformArchList
!= []:
408 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
409 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
412 if self
.KeyStringList
!= []:
413 for Key
in self
.KeyStringList
:
414 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
415 Target
, Tag
, Arch
= Key
.split('_')
416 if Arch
in CurArchList
:
417 ArchList
.append(Arch
)
418 if Target
not in self
.TargetOverrideList
:
419 self
.TargetOverrideList
.append(Target
)
421 ArchList
= CurArchList
423 UseArchList
= TargetArchList
424 if self
.UseArch
!= None:
426 UseArchList
.append(self
.UseArch
)
427 ArchList
= list(set (UseArchList
) & set (ArchList
))
429 self
.InfFileName
= NormPath(self
.InfFileName
)
430 if len(PlatformArchList
) == 0:
432 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
433 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
435 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
436 if len(ArchList
) == 1:
439 elif len(ArchList
) > 1:
440 if len(PlatformArchList
) == 0:
441 EdkLogger
.error("GenFds", GENFDS_ERROR
, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList
), self
.InfFileName
))
443 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList
), self
.InfFileName
))
445 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \
446 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
448 ## __GetEFIOutPutPath__() method
450 # Get the output path for generated files
452 # @param self The object pointer
453 # @retval string Path that output files from this INF go to
455 def __GetEFIOutPutPath__(self
):
458 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
459 Index
= FileName
.rfind('.')
460 FileName
= FileName
[0:Index
]
462 if self
.CurrentArch
!= None:
463 Arch
= self
.CurrentArch
465 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
471 OutputPath
= os
.path
.realpath(OutputPath
)
474 ## __GenSimpleFileSection__() method
476 # Generate section by specified file name or a list of files with file extension
478 # @param self The object pointer
479 # @param Rule The rule object used to generate section
480 # @retval string File name of the generated section file
482 def __GenSimpleFileSection__(self
, Rule
):
484 # Prepare the parameter of GenSection
488 GenSecInputFile
= None
489 if Rule
.FileName
!= None:
490 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
491 if os
.path
.isabs(GenSecInputFile
):
492 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
494 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
496 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
499 SectionType
= Rule
.SectionType
501 # Convert Fv Section Type for PI1.1 SMM driver.
503 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
504 if SectionType
== 'DXE_DEPEX':
505 SectionType
= 'SMM_DEPEX'
507 # Framework SMM Driver has no SMM_DEPEX section type
509 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
510 if SectionType
== 'SMM_DEPEX':
511 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
513 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
514 if self
.KeepReloc
!= None:
515 NoStrip
= self
.KeepReloc
516 elif Rule
.KeepReloc
!= None:
517 NoStrip
= Rule
.KeepReloc
518 elif self
.ShadowFromInfFile
!= None:
519 NoStrip
= self
.ShadowFromInfFile
522 for File
in FileList
:
525 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
526 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
528 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
529 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
531 #Get PE Section alignment when align is set to AUTO
532 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
533 ImageObj
= PeImageClass (File
)
534 if ImageObj
.SectionAlignment
< 0x400:
535 self
.Alignment
= str (ImageObj
.SectionAlignment
)
537 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
540 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
541 if not os
.path
.exists(FileBeforeStrip
) or \
542 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
543 shutil
.copyfile(File
, FileBeforeStrip
)
544 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
545 GenFdsGlobalVariable
.GenerateFirmwareImage(
552 if SectionType
== 'TE':
553 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
554 GenFdsGlobalVariable
.GenerateFirmwareImage(
561 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
])
562 OutputFileList
.append(OutputFile
)
565 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
566 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
567 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
568 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
570 #Get PE Section alignment when align is set to AUTO
571 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
572 ImageObj
= PeImageClass (GenSecInputFile
)
573 if ImageObj
.SectionAlignment
< 0x400:
574 self
.Alignment
= str (ImageObj
.SectionAlignment
)
576 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
579 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
580 if not os
.path
.exists(FileBeforeStrip
) or \
581 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
582 shutil
.copyfile(GenSecInputFile
, FileBeforeStrip
)
583 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
584 GenFdsGlobalVariable
.GenerateFirmwareImage(
589 GenSecInputFile
= StrippedFile
591 if SectionType
== 'TE':
592 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
593 GenFdsGlobalVariable
.GenerateFirmwareImage(
598 GenSecInputFile
= TeFile
600 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
])
601 OutputFileList
.append(OutputFile
)
603 return OutputFileList
605 ## __GenSimpleFileFfs__() method
609 # @param self The object pointer
610 # @param Rule The rule object used to generate section
611 # @param InputFileList The output file list from GenSection
612 # @retval string Generated FFS file name
614 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
):
615 FfsOutput
= self
.OutputPath
+ \
617 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
620 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
622 SectionAlignments
= []
623 for InputFile
in InputFileList
:
624 InputSection
.append(InputFile
)
625 SectionAlignments
.append(Rule
.SectAlignment
)
627 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
628 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
629 if len(PcdValue
) == 0:
630 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
632 if PcdValue
.startswith('{'):
633 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
634 RegistryGuidStr
= PcdValue
635 if len(RegistryGuidStr
) == 0:
636 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
638 self
.ModuleGuid
= RegistryGuidStr
640 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
641 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
642 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
643 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
644 SectionAlign
=SectionAlignments
648 ## __GenComplexFileSection__() method
650 # Generate section by sections in Rule
652 # @param self The object pointer
653 # @param Rule The rule object used to generate section
654 # @param FvChildAddr Array of the inside FvImage base address
655 # @param FvParentAddr Parent Fv base address
656 # @retval string File name of the generated section file
658 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
):
659 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
660 if Rule
.KeepReloc
!= None:
661 self
.KeepRelocFromRule
= Rule
.KeepReloc
665 HasGneratedFlag
= False
666 for Sect
in Rule
.SectionList
:
667 SecIndex
= '%d' %Index
670 # Convert Fv Section Type for PI1.1 SMM driver.
672 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
673 if Sect
.SectionType
== 'DXE_DEPEX':
674 Sect
.SectionType
= 'SMM_DEPEX'
676 # Framework SMM Driver has no SMM_DEPEX section type
678 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
679 if Sect
.SectionType
== 'SMM_DEPEX':
680 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
682 # process the inside FvImage from FvSection or GuidSection
684 if FvChildAddr
!= []:
685 if isinstance(Sect
, FvImageSection
):
686 Sect
.FvAddr
= FvChildAddr
.pop(0)
687 elif isinstance(Sect
, GuidSection
):
688 Sect
.FvAddr
= FvChildAddr
689 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
690 Sect
.FvParentAddr
= FvParentAddr
692 if Rule
.KeyStringList
!= []:
693 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
)
695 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
)
697 if not HasGneratedFlag
:
698 UniVfrOffsetFileSection
= ""
699 ModuleFileName
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
700 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
702 # Search the source list in InfData to find if there are .vfr file exist.
705 VfrUniOffsetList
= []
706 for SourceFile
in InfData
.Sources
:
707 if SourceFile
.Type
.upper() == ".VFR" :
709 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
711 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
712 if SourceFile
.Type
.upper() == ".UNI" :
714 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
716 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
719 if len(VfrUniBaseName
) > 0:
720 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
722 # Generate the Raw data of raw section
724 os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
725 UniVfrOffsetFileName
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
726 UniVfrOffsetFileSection
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
728 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
730 UniVfrOffsetFileNameList
= []
731 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
732 """Call GenSection"""
733 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
734 UniVfrOffsetFileNameList
,
737 os
.remove(UniVfrOffsetFileName
)
738 SectList
.append(UniVfrOffsetFileSection
)
739 HasGneratedFlag
= True
741 for SecName
in SectList
:
742 SectFiles
.append(SecName
)
743 SectAlignments
.append(Align
)
745 return SectFiles
, SectAlignments
747 ## __GenComplexFileFfs__() method
751 # @param self The object pointer
752 # @param Rule The rule object used to generate section
753 # @param InputFileList The output file list from GenSection
754 # @retval string Generated FFS file name
756 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
):
758 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
759 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
760 if len(PcdValue
) == 0:
761 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
763 if PcdValue
.startswith('{'):
764 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
765 RegistryGuidStr
= PcdValue
766 if len(RegistryGuidStr
) == 0:
767 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
769 self
.ModuleGuid
= RegistryGuidStr
771 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
772 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
773 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
774 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
775 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
776 SectionAlign
=Alignments
780 ## __GetGenFfsCmdParameter__() method
782 # Create parameter string for GenFfs
784 # @param self The object pointer
785 # @param Rule The rule object used to generate section
786 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
788 def __GetGenFfsCmdParameter__(self
, Rule
):
790 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
791 if Rule
.Fixed
!= False:
793 if Rule
.CheckSum
!= False:
796 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
797 result
+= ('-a', Rule
.Alignment
)
801 ## __GetBuildOutputMapFileVfrUniInfo() method
803 # Find the offset of UNI/INF object offset in the EFI image file.
805 # @param self The object pointer
806 # @param VfrUniBaseName A name list contain the UNI/INF object name.
807 # @retval RetValue A list contain offset of UNI/INF object.
809 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
813 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
815 fInputfile
= open(MapFileName
, "r", 0)
817 FileLinesList
= fInputfile
.readlines()
819 EdkLogger
.error("GenFds", FILE_READ_FAILURE
, "File read failed for %s" %MapFileName
,None)
823 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %MapFileName
,None)
826 for eachLine
in FileLinesList
:
827 for eachName
in VfrUniBaseName
.values():
828 if eachLine
.find(eachName
) != -1:
829 eachLine
= eachLine
.strip()
830 Element
= eachLine
.split()
832 # MSFT/ICC/EBC map file
834 if (len(Element
) == 4):
842 RetValue
.append((eachName
, Element
[2]))
847 elif (len(Element
) == 2) and Element
[0].startswith("0x"):
848 RetValue
.append((eachName
, Element
[0]))
852 ## __GenUniVfrOffsetFile() method
854 # Generate the offset file for the module which contain VFR or UNI file.
856 # @param self The object pointer
857 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
858 # @param UniVfrOffsetFileName The output offset file name.
860 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
863 fInputfile
= open(UniVfrOffsetFileName
, "wb+", 0)
865 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %UniVfrOffsetFileName
,None)
867 # Use a instance of StringIO to cache data
868 fStringIO
= StringIO
.StringIO('')
870 for Item
in VfrUniOffsetList
:
871 if (Item
[0].find("Strings") != -1):
873 # UNI offset in image.
875 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
877 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
878 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
879 fStringIO
.write(''.join(UniGuid
))
880 UniValue
= pack ('Q', int (Item
[1], 16))
881 fStringIO
.write (UniValue
)
884 # VFR binary offset in image.
886 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
888 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
889 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
890 fStringIO
.write(''.join(VfrGuid
))
892 VfrValue
= pack ('Q', int (Item
[1], 16))
893 fStringIO
.write (VfrValue
)
896 # write data into file.
899 fInputfile
.write (fStringIO
.getvalue())
901 EdkLogger
.error("GenFds", FILE_WRITE_FAILURE
, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName
,None)