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 179