]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsFileStatement.py
BaseTools: Extend the RAW format to support multiple binary files
[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
49 ## GenFfs() method
50 #
51 # Generate FFS
52 #
53 # @param self The object pointer
54 # @param Dict dictionary contains macro and value pair
55 # @param FvChildAddr Array of the inside FvImage base address
56 # @param FvParentAddr Parent Fv base address
57 # @retval string Generated FFS file name
58 #
59 def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None):
60
61 if self.NameGuid != None and self.NameGuid.startswith('PCD('):
62 PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
63 if len(PcdValue) == 0:
64 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
65 % (self.NameGuid))
66 if PcdValue.startswith('{'):
67 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
68 RegistryGuidStr = PcdValue
69 if len(RegistryGuidStr) == 0:
70 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
71 % (self.NameGuid))
72 self.NameGuid = RegistryGuidStr
73
74 OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid)
75 if not os.path.exists(OutputDir):
76 os.makedirs(OutputDir)
77
78 Dict.update(self.DefineVarDict)
79 SectionAlignments = None
80 if self.FvName != None :
81 Buffer = StringIO.StringIO('')
82 if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
83 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
84 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
85 FileName = Fv.AddToBuffer(Buffer)
86 SectionFiles = [FileName]
87
88 elif self.FdName != None:
89 if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
90 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
91 Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
92 FileName = Fd.GenFd()
93 SectionFiles = [FileName]
94
95 elif self.FileName != None:
96 if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW':
97 if isinstance(self.FileName, list) and isinstance(self.Alignment, list) and len(self.FileName) == len(self.Alignment):
98 FileContent = ''
99 for Index, File in enumerate(self.FileName):
100 try:
101 f = open(File, 'r+b')
102 except:
103 GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File))
104 Content = f.read()
105 f.close()
106 AlignValue = self.Alignment[Index]
107 if AlignValue == None:
108 AlignValue = 1
109 FileContent += Content
110 if len(FileContent) % AlignValue != 0:
111 Size = AlignValue - len(FileContent) % AlignValue
112 for i in range(0, Size):
113 FileContent += pack('B', 0xFF)
114
115 if FileContent:
116 OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw')
117 SaveFileOnChange(OutputRAWFile, FileContent, True)
118 self.FileName = OutputRAWFile
119 if max(self.Alignment):
120 self.Alignment = str(max(self.Alignment))
121 else:
122 self.Alignment = None
123 self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
124 #Replace $(SAPCE) with real space
125 self.FileName = self.FileName.replace('$(SPACE)', ' ')
126 SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
127
128 else:
129 SectionFiles = []
130 Index = 0
131 SectionAlignments = []
132 for section in self.SectionList :
133 Index = Index + 1
134 SecIndex = '%d' %Index
135 # process the inside FvImage from FvSection or GuidSection
136 if FvChildAddr != []:
137 if isinstance(section, FvImageSection):
138 section.FvAddr = FvChildAddr.pop(0)
139 elif isinstance(section, GuidSection):
140 section.FvAddr = FvChildAddr
141 if FvParentAddr != None and isinstance(section, GuidSection):
142 section.FvParentAddr = FvParentAddr
143
144 if self.KeepReloc == False:
145 section.KeepReloc = False
146 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
147 if sectList != []:
148 for sect in sectList:
149 SectionFiles.append(sect)
150 SectionAlignments.append(align)
151
152 #
153 # Prepare the parameter
154 #
155 FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
156 GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
157 Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType),
158 self.NameGuid,
159 Fixed=self.Fixed,
160 CheckSum=self.CheckSum,
161 Align=self.Alignment,
162 SectionAlign=SectionAlignments
163 )
164
165 return FfsFileOutput
166
167
168