1 /*++ 2 3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 GenFvImageExe.c 15 16 Abstract: 17 18 This contains all code necessary to build the GenFvImage.exe utility. 19 This utility relies heavily on the GenFvImage Lib. Definitions for both 20 can be found in the Tiano Firmware Volume Generation Utility 21 Specification, review draft. 22 23 --*/ 24 25 // 26 // File included in build 27 // 28 #include "GenFvImageExe.h" 29 #include "CommonLib.h" 30 #include "EfiUtilityMsgs.h" 31 32 VOID 33 PrintUtilityInfo ( 34 VOID 35 ) 36 /*++ 37 38 Routine Description: 39 40 Displays the standard utility information to SDTOUT 41 42 Arguments: 43 44 None 45 46 Returns: 47 48 None 49 50 --*/ 51 { 52 int Index; 53 const char *Str[] = { 54 UTILITY_NAME" "UTILITY_VERSION" - Intel Generate Firmware Volume Utility", 55 " Copyright (C), 2004 - 2009 Intel Corporation", 56 57 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) ) 58 " Built from "UTILITY_BUILD", project of "UTILITY_VENDOR, 59 #endif 60 NULL 61 }; 62 for (Index = 0; Str[Index] != NULL; Index++) { 63 fprintf (stdout, "%s\n", Str[Index]); 64 } 65 } 66 67 VOID 68 PrintUsage ( 69 VOID 70 ) 71 /*++ 72 73 Routine Description: 74 75 Displays the utility usage syntax to STDOUT 76 77 Arguments: 78 79 None 80 81 Returns: 82 83 None 84 85 --*/ 86 { 87 int Index; 88 const char *Str[] = { 89 "", 90 "Usage:", 91 " "UTILITY_NAME" [OPTION]", 92 "Options:", 93 " -I FvInfFileName The name of the image description file.", 94 NULL 95 }; 96 97 for (Index = 0; Str[Index] != NULL; Index++) { 98 fprintf (stdout, "%s\n", Str[Index]); 99 } 100 } 101 102 EFI_STATUS 103 main ( 104 IN INTN argc, 105 IN CHAR8 **argv 106 ) 107 /*++ 108 109 Routine Description: 110 111 This utility uses GenFvImage.Lib to build a firmware volume image. 112 113 Arguments: 114 115 FvInfFileName The name of an FV image description file. 116 117 Arguments come in pair in any order. 118 -I FvInfFileName 119 120 Returns: 121 122 EFI_SUCCESS No error conditions detected. 123 EFI_INVALID_PARAMETER One or more of the input parameters is invalid. 124 EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable. 125 Most commonly this will be memory allocation 126 or file creation. 127 EFI_LOAD_ERROR GenFvImage.lib could not be loaded. 128 EFI_ABORTED Error executing the GenFvImage lib. 129 130 --*/ 131 { 132 EFI_STATUS Status; 133 CHAR8 InfFileName[_MAX_PATH]; 134 CHAR8 *InfFileImage; 135 UINTN InfFileSize; 136 UINT8 *FvImage; 137 UINTN FvImageSize; 138 UINT8 Index; 139 CHAR8 FvFileNameBuffer[_MAX_PATH]; 140 CHAR8 *FvFileName; 141 FILE *FvFile; 142 FILE *SymFile; 143 CHAR8 SymFileNameBuffer[_MAX_PATH]; 144 CHAR8 *SymFileName; 145 UINT8 *SymImage; 146 UINTN SymImageSize; 147 CHAR8 *CurrentSymString; 148 149 FvFileName = FvFileNameBuffer; 150 SymFileName = SymFileNameBuffer; 151 152 SetUtilityName (UTILITY_NAME); 153 // 154 // Display utility information 155 // 156 PrintUtilityInfo (); 157 158 // 159 // Verify the correct number of arguments 160 // 161 if (argc != MAX_ARGS) { 162 Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); 163 PrintUsage (); 164 return GetUtilityStatus (); 165 } 166 // 167 // Initialize variables 168 // 169 strcpy (InfFileName, ""); 170 171 // 172 // Parse the command line arguments 173 // 174 for (Index = 1; Index < MAX_ARGS; Index += 2) { 175 // 176 // Make sure argument pair begin with - or / 177 // 178 if (argv[Index][0] != '-' && argv[Index][0] != '/') { 179 Error (NULL, 0, 0, argv[Index], "argument pair must begin with \"-\" or \"/\""); 180 PrintUsage (); 181 return GetUtilityStatus (); 182 } 183 // 184 // Make sure argument specifier is only one letter 185 // 186 if (argv[Index][2] != 0) { 187 Error (NULL, 0, 0, argv[Index], "unrecognized argument"); 188 PrintUsage (); 189 return GetUtilityStatus (); 190 } 191 // 192 // Determine argument to read 193 // 194 switch (argv[Index][1]) { 195 196 case 'I': 197 case 'i': 198 if (strlen (InfFileName) == 0) { 199 strcpy (InfFileName, argv[Index + 1]); 200 } else { 201 Error (NULL, 0, 0, argv[Index + 1], "FvInfFileName may only be specified once"); 202 PrintUsage (); 203 return GetUtilityStatus (); 204 } 205 break; 206 207 default: 208 Error (NULL, 0, 0, argv[Index], "unrecognized argument"); 209 PrintUsage (); 210 return GetUtilityStatus (); 211 break; 212 } 213 } 214 // 215 // Read the INF file image 216 // 217 Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize); 218 if (EFI_ERROR (Status)) { 219 return STATUS_ERROR; 220 } 221 // 222 // Call the GenFvImage lib 223 // 224 Status = GenerateFvImage ( 225 InfFileImage, 226 InfFileSize, 227 &FvImage, 228 &FvImageSize, 229 &FvFileName, 230 &SymImage, 231 &SymImageSize, 232 &SymFileName 233 ); 234 235 if (EFI_ERROR (Status)) { 236 switch (Status) { 237 238 case EFI_INVALID_PARAMETER: 239 Error (NULL, 0, 0, "invalid parameter passed to GenFvImage Lib", NULL); 240 return GetUtilityStatus (); 241 break; 242 243 case EFI_ABORTED: 244 Error (NULL, 0, 0, "error detected while creating the file image", NULL); 245 return GetUtilityStatus (); 246 break; 247 248 case EFI_OUT_OF_RESOURCES: 249 Error (NULL, 0, 0, "GenFvImage Lib could not allocate required resources", NULL); 250 return GetUtilityStatus (); 251 break; 252 253 case EFI_VOLUME_CORRUPTED: 254 Error (NULL, 0, 0, "no base address was specified, but the FV.INF included a PEI or BSF file", NULL); 255 return GetUtilityStatus (); 256 break; 257 258 case EFI_LOAD_ERROR: 259 Error (NULL, 0, 0, "could not load FV image generation library", NULL); 260 return GetUtilityStatus (); 261 break; 262 263 default: 264 Error (NULL, 0, 0, "GenFvImage Lib returned unknown status", "status returned = 0x%X", Status); 265 return GetUtilityStatus (); 266 break; 267 } 268 } 269 // 270 // Write file 271 // 272 FvFile = fopen (FvFileName, "wb"); 273 if (FvFile == NULL) { 274 Error (NULL, 0, 0, FvFileName, "could not open output file"); 275 free (FvImage); 276 free (SymImage); 277 return GetUtilityStatus (); 278 } 279 280 if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) { 281 Error (NULL, 0, 0, FvFileName, "failed to write to output file"); 282 free (FvImage); 283 free (SymImage); 284 fclose (FvFile); 285 return GetUtilityStatus (); 286 } 287 288 fclose (FvFile); 289 free (FvImage); 290 291 // 292 // Write symbol file 293 // 294 if (strcmp (SymFileName, "")) { 295 SymFile = fopen (SymFileName, "wt"); 296 if (SymFile == NULL) { 297 Error (NULL, 0, 0, SymFileName, "could not open output symbol file"); 298 free (SymImage); 299 return GetUtilityStatus (); 300 } 301 302 fprintf (SymFile, "TEXTSYM format | V1.0\n"); 303 304 CurrentSymString = SymImage; 305 while (((UINTN) CurrentSymString - (UINTN) SymImage) < SymImageSize) { 306 fprintf (SymFile, "%s", CurrentSymString); 307 CurrentSymString = (CHAR8 *) (((UINTN) CurrentSymString) + strlen (CurrentSymString) + 1); 308 } 309 310 fclose (SymFile); 311 } 312 313 free (SymImage); 314 315 return GetUtilityStatus (); 316 } 317