]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsFileStatement.py
BaseTools: Enhance BaseTools supports FixedAtBuild usage in VFR file
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsFileStatement.py
1 ## @file
2 # process FFS generation from FILE statement
3 #
4 # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
5 #
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
10 #
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.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Ffs
19 import Rule
20 import Common.LongFilePathOs as os
21 import StringIO
22 import subprocess
23
24 from GenFdsGlobalVariable import GenFdsGlobalVariable
25 from CommonDataClass.FdfClass import FileStatementClassObject
26 from Common import EdkLogger
27 from Common.BuildToolError import *
28 from Common.Misc import GuidStructureByteArrayToGuidString
29 from GuidSection import GuidSection
30 from FvImageSection import FvImageSection
31 from Common.Misc import SaveFileOnChange
32 from struct import *
33
34 ## generate FFS from FILE
35 #
36 #
37 class FileStatement (FileStatementClassObject) :
38 ## The constructor
39 #
40 # @param self The object pointer
41 #
42 def __init__(self):
43 FileStatementClassObject.__init__(self)
44 self.CurrentLineNum = None
45 self.CurrentLineContent = None
46 self.FileName = None
47 self.InfFileName = None
48 self.SubAlignment = None
49
50 ## GenFfs() method
51 #
52 # Generate FFS
53 #
54 # @param self The object pointer
55 # @param Dict dictionary contains macro and value pair
56 # @param FvChildAddr Array of the inside FvImage base address
57 # @param FvParentAddr Parent Fv base address
58 # @retval string Generated FFS file name
59 #
60 def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None):
61
62 if self.NameGuid != None and self.NameGuid.startswith('PCD('):
63 PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
64 if len(PcdValue) == 0:
65 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
66 % (self.NameGuid))
67 if PcdValue.startswith('{'):
68 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
69 RegistryGuidStr = PcdValue
70 if len(RegistryGuidStr) == 0:
71 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
72 % (self.NameGuid))
73 self.NameGuid = RegistryGuidStr
74
75 OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid)
76 if not os.path.exists(OutputDir):
77 os.makedirs(OutputDir)
78
79 Dict.update(self.DefineVarDict)
80 SectionAlignments = None
81 if self.FvName != None :
82 Buffer = StringIO.StringIO('')
83 if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
84 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
85 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
86 FileName = Fv.AddToBuffer(Buffer)
87 SectionFiles = [FileName]
88
89 elif self.FdName != None:
90 if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
91 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
92 Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
93 FileName = Fd.GenFd()
94 SectionFiles = [FileName]
95
96 elif self.FileName != None:
97 if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW':
98 if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment):
99 FileContent = ''
100 MaxAlignIndex = 0
101 MaxAlignValue = 1
102 for Index, File in enumerate(self.FileName):
103 try:
104 f = open(File, 'rb')
105 except:
106 GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File))
107 Content = f.read()
108 f.close()
109 AlignValue = 1
110 if self.SubAlignment[Index] != None:
111 AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index])
112 if AlignValue > MaxAlignValue:
113 MaxAlignIndex = Index
114 MaxAlignValue = AlignValue
115 FileContent += Content
116 if len(FileContent) % AlignValue != 0:
117 Size = AlignValue - len(FileContent) % AlignValue
118 for i in range(0, Size):
119 FileContent += pack('B', 0xFF)
120
121 if FileContent:
122 OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw')
123 SaveFileOnChange(OutputRAWFile, FileContent, True)
124 self.FileName = OutputRAWFile
125 self.SubAlignment = self.SubAlignment[MaxAlignIndex]
126
127 if self.Alignment and self.SubAlignment:
128 if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment):
129 self.Alignment = self.SubAlignment
130 elif self.SubAlignment:
131 self.Alignment = self.SubAlignment
132
133 self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
134 #Replace $(SAPCE) with real space
135 self.FileName = self.FileName.replace('$(SPACE)', ' ')
136 SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
137
138 else:
139 SectionFiles = []
140 Index = 0
141 SectionAlignments = []
142 for section in self.SectionList :
143 Index = Index + 1
144 SecIndex = '%d' %Index
145 # process the inside FvImage from FvSection or GuidSection
146 if FvChildAddr != []:
147 if isinstance(section, FvImageSection):
148 section.FvAddr = FvChildAddr.pop(0)
149 elif isinstance(section, GuidSection):
150 section.FvAddr = FvChildAddr
151 if FvParentAddr != None and isinstance(section, GuidSection):
152 section.FvParentAddr = FvParentAddr
153
154 if self.KeepReloc == False:
155 section.KeepReloc = False
156 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
157 if sectList != []:
158 for sect in sectList:
159 SectionFiles.append(sect)
160 SectionAlignments.append(align)
161
162 #
163 # Prepare the parameter
164 #
165 FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
166 GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
167 Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType),
168 self.NameGuid,
169 Fixed=self.Fixed,
170 CheckSum=self.CheckSum,
171 Align=self.Alignment,
172 SectionAlign=SectionAlignments
173 )
174
175 return FfsFileOutput
176
177
178