]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenFv/GenFv.c
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / C / GenFv / GenFv.c
CommitLineData
30fdf114
LG
1/** @file\r
2\r
3Copyright (c) 2007 - 2008, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 GenFv.c\r
15\r
16Abstract:\r
17\r
18 This contains all code necessary to build the GenFvImage.exe utility. \r
19 This utility relies heavily on the GenFvImage Lib. Definitions for both\r
20 can be found in the Tiano Firmware Volume Generation Utility \r
21 Specification, review draft.\r
22\r
23**/\r
24\r
25//\r
26// File included in build\r
27//\r
28#include <stdio.h>\r
29#include <string.h>\r
30#include <stdlib.h>\r
31#include "GenFvInternalLib.h"\r
32\r
33//\r
34// Utility Name\r
35//\r
36#define UTILITY_NAME "GenFv"\r
37\r
38//\r
39// Utility version information\r
40//\r
41#define UTILITY_MAJOR_VERSION 0\r
42#define UTILITY_MINOR_VERSION 1\r
43#define GENFV_UPDATE_TIME " updated on 2008/11/21"\r
44\r
45EFI_GUID mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;\r
46\r
47STATIC\r
48VOID \r
49Version (\r
50 VOID\r
51)\r
52/*++\r
53\r
54Routine Description:\r
55\r
56 Displays the standard utility information to SDTOUT\r
57\r
58Arguments:\r
59\r
60 None\r
61\r
62Returns:\r
63\r
64 None\r
65\r
66--*/\r
67{\r
68 fprintf (stdout, "%s Version %d.%d %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, GENFV_UPDATE_TIME);\r
69}\r
70\r
71STATIC\r
72VOID \r
73Usage (\r
74 VOID\r
75 )\r
76/*++\r
77\r
78Routine Description:\r
79\r
80 Displays the utility usage syntax to STDOUT\r
81\r
82Arguments:\r
83\r
84 None\r
85\r
86Returns:\r
87\r
88 None\r
89\r
90--*/\r
91{\r
92 //\r
93 // Summary usage\r
94 //\r
95 fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);\r
96 \r
97 //\r
98 // Copyright declaration\r
99 // \r
100 fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
101\r
102 //\r
103 // Details Option\r
104 //\r
105 fprintf (stdout, "Options:\n");\r
106 fprintf (stdout, " -o FileName, --outputfile FileName\n\\r
107 File is the FvImage or CapImage to be created.\n");\r
108 fprintf (stdout, " -i FileName, --inputfile FileName\n\\r
109 File is the input FV.inf or Cap.inf to specify\n\\r
110 how to construct FvImage or CapImage.\n");\r
111 fprintf (stdout, " -b BlockSize, --blocksize BlockSize\n\\r
112 BlockSize is one HEX or DEC format value\n\\r
113 BlockSize is required by Fv Image.\n");\r
114 fprintf (stdout, " -n NumberBlock, --numberblock NumberBlock\n\\r
115 NumberBlock is one HEX or DEC format value\n\\r
116 NumberBlock is one optional parameter.\n");\r
117 fprintf (stdout, " -f FfsFile, --ffsfile FfsFile\n\\r
118 FfsFile is placed into Fv Image\n\\r
119 multi files can input one by one\n");\r
120 fprintf (stdout, " -s FileTakenSize, --filetakensize FileTakenSize\n\\r
121 FileTakenSize specifies the size of the required\n\\r
122 space that the input file is placed in Fvimage.\n\\r
123 It is specified together with the input file.\n");\r
124 fprintf (stdout, " -r Address, --baseaddr Address\n\\r
125 Address is the rebase start address for drivers that\n\\r
126 run in Flash. It supports DEC or HEX digital format.\n\\r
127 If it is set to zero, no rebase action will be taken\n");\r
128 fprintf (stdout, " -a AddressFile, --addrfile AddressFile\n\\r
129 AddressFile is one file used to record boot driver base\n\\r
130 address and runtime driver base address. And this tool\n\\r
131 will update these two addresses after it relocates all\n\\r
132 boot drivers and runtime drivers in this fv iamge to\n\\r
133 the preferred loaded memory address.\n");\r
134 fprintf (stdout, " -m logfile, --map logfile\n\\r
135 Logfile is the output fv map file name. if it is not\n\\r
136 given, the FvName.map will be the default map file name\n"); \r
137 fprintf (stdout, " -g Guid, --guid GuidValue\n\\r
138 GuidValue is one specific capsule guid value\n\\r
139 or fv file system guid value.\n\\r
140 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
141 fprintf (stdout, " --FvNameGuid GuidValue is the Fv Name Guid value.\n\\r
142 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
143 fprintf (stdout, " --capflag CapFlag Capsule Reset Flag can be PersistAcrossReset,\n\\r
144 or PopulateSystemTable or not set.\n");\r
145 fprintf (stdout, " --capheadsize HeadSize\n\\r
146 HeadSize is one HEX or DEC format value\n\\r
147 HeadSize is required by Capsule Image.\n"); \r
148 fprintf (stdout, " -c, --capsule Create Capsule Image.\n");\r
149 fprintf (stdout, " -p, --dump Dump Capsule Image header.\n");\r
150 fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
151 fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
152 fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
153 fprintf (stdout, " --version Show program's version number and exit.\n");\r
154 fprintf (stdout, " -h, --help Show this help message and exit.\n");\r
155}\r
156\r
157UINT32 mFvTotalSize;\r
158UINT32 mFvTakenSize;\r
159\r
160int\r
161main (\r
162 IN int argc,\r
163 IN char **argv\r
164 )\r
165/*++\r
166\r
167Routine Description:\r
168\r
169 This utility uses GenFvImage.Lib to build a firmware volume image.\r
170\r
171Arguments:\r
172\r
173 FvInfFileName The name of an FV image description file or Capsule Image.\r
174\r
175 Arguments come in pair in any order.\r
176 -I FvInfFileName \r
177\r
178Returns:\r
179\r
180 EFI_SUCCESS No error conditions detected.\r
181 EFI_INVALID_PARAMETER One or more of the input parameters is invalid.\r
182 EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable. \r
183 Most commonly this will be memory allocation \r
184 or file creation.\r
185 EFI_LOAD_ERROR GenFvImage.lib could not be loaded.\r
186 EFI_ABORTED Error executing the GenFvImage lib.\r
187\r
188--*/\r
189{\r
190 EFI_STATUS Status;\r
191 CHAR8 *InfFileName;\r
192 CHAR8 *AddrFileName;\r
193 CHAR8 *MapFileName;\r
194 CHAR8 *InfFileImage;\r
195 UINT32 InfFileSize;\r
196 CHAR8 *OutFileName;\r
197 CHAR8 ValueString[_MAX_PATH];\r
198 BOOLEAN CapsuleFlag;\r
199 BOOLEAN DumpCapsule;\r
200 MEMORY_FILE AddrMemoryFile;\r
201 FILE *FpFile;\r
202 EFI_CAPSULE_HEADER *CapsuleHeader;\r
203 UINT64 LogLevel, TempNumber;\r
204 UINT32 Index;\r
205\r
206 InfFileName = NULL;\r
207 AddrFileName = NULL;\r
208 InfFileImage = NULL;\r
209 OutFileName = NULL;\r
210 MapFileName = NULL;\r
211 InfFileSize = 0;\r
212 CapsuleFlag = FALSE;\r
213 DumpCapsule = FALSE;\r
214 FpFile = NULL;\r
215 CapsuleHeader = NULL;\r
216 LogLevel = 0;\r
217 TempNumber = 0;\r
218 Index = 0;\r
219 mFvTotalSize = 0;\r
220 mFvTakenSize = 0;\r
221\r
222 SetUtilityName (UTILITY_NAME);\r
223 \r
224 if (argc == 1) {\r
225 Error (NULL, 0, 1001, "Missing options", "No input options specified.");\r
226 Usage ();\r
227 return STATUS_ERROR;\r
228 }\r
229\r
230 //\r
231 // Init global data to Zero\r
232 //\r
233 memset (&mFvDataInfo, 0, sizeof (FV_INFO));\r
234 memset (&mCapDataInfo, 0, sizeof (CAP_INFO)); \r
235 //\r
236 // Set the default FvGuid\r
237 //\r
238 memcpy (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid, sizeof (EFI_GUID));\r
239 \r
240 //\r
241 // Parse command line\r
242 //\r
243 argc --;\r
244 argv ++;\r
245\r
246 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
247 Version ();\r
248 Usage ();\r
249 return STATUS_SUCCESS; \r
250 }\r
251\r
252 if (stricmp (argv[0], "--version") == 0) {\r
253 Version ();\r
254 return STATUS_SUCCESS; \r
255 }\r
256\r
257 while (argc > 0) {\r
258 if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {\r
259 InfFileName = argv[1];\r
260 if (InfFileName == NULL) {\r
261 Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");\r
262 return STATUS_ERROR;\r
263 }\r
264 argc -= 2;\r
265 argv += 2;\r
266 continue; \r
267 }\r
268\r
269 if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {\r
270 AddrFileName = argv[1];\r
271 if (AddrFileName == NULL) {\r
272 Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");\r
273 return STATUS_ERROR;\r
274 }\r
275 argc -= 2;\r
276 argv += 2;\r
277 continue; \r
278 }\r
279\r
280 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
281 OutFileName = argv[1];\r
282 if (OutFileName == NULL) {\r
283 Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");\r
284 return STATUS_ERROR;\r
285 }\r
286 argc -= 2;\r
287 argv += 2;\r
288 continue; \r
289 }\r
290\r
291 if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {\r
292 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
293 if (EFI_ERROR (Status)) {\r
294 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
295 return STATUS_ERROR; \r
296 }\r
297 mFvDataInfo.BaseAddress = TempNumber;\r
298 mFvDataInfo.BaseAddressSet = TRUE;\r
299 argc -= 2;\r
300 argv += 2;\r
301 continue; \r
302 }\r
303\r
304 if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {\r
305 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
306 if (EFI_ERROR (Status)) {\r
307 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
308 return STATUS_ERROR; \r
309 }\r
310 if (TempNumber == 0) {\r
311 Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");\r
312 return STATUS_ERROR; \r
313 }\r
314 mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;\r
315 DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%x", EFI_BLOCK_SIZE_STRING, TempNumber);\r
316 argc -= 2;\r
317 argv += 2;\r
318 continue; \r
319 }\r
320\r
321 if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {\r
322 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
323 if (EFI_ERROR (Status)) {\r
324 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
325 return STATUS_ERROR; \r
326 }\r
327 if (TempNumber == 0) {\r
328 Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");\r
329 return STATUS_ERROR; \r
330 }\r
331 mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;\r
332 DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%x", EFI_NUM_BLOCKS_STRING, TempNumber);\r
333 argc -= 2;\r
334 argv += 2;\r
335 continue; \r
336 }\r
337\r
338 if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {\r
339 if (argv[1] == NULL) {\r
340 Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");\r
341 return STATUS_ERROR;\r
342 }\r
343 strcpy (mFvDataInfo.FvFiles[Index], argv[1]);\r
344 DebugMsg (NULL, 0, 9, "FV component file", "the %dth name is %s", Index + 1, argv[1]);\r
345 argc -= 2;\r
346 argv += 2;\r
347\r
348 if (argc > 0) {\r
349 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {\r
350 if (argv[1] == NULL) {\r
351 Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");\r
352 return STATUS_ERROR;\r
353 }\r
354 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
355 if (EFI_ERROR (Status)) {\r
356 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
357 return STATUS_ERROR; \r
358 }\r
359 mFvDataInfo.SizeofFvFiles[Index] = TempNumber;\r
360 DebugMsg (NULL, 0, 9, "FV component file size", "the %dth size is %s", Index + 1, argv[1]);\r
361 argc -= 2;\r
362 argv += 2;\r
363 }\r
364 }\r
365 Index ++;\r
366 continue; \r
367 }\r
368\r
369 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {\r
370 Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");\r
371 return STATUS_ERROR; \r
372 }\r
373\r
374 if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {\r
375 CapsuleFlag = TRUE;\r
376 argc --;\r
377 argv ++;\r
378 continue; \r
379 }\r
380\r
381 if (stricmp (argv[0], "--capheadsize") == 0) {\r
382 //\r
383 // Get Capsule Image Header Size\r
384 //\r
385 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
386 if (EFI_ERROR (Status)) {\r
387 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
388 return STATUS_ERROR; \r
389 }\r
390 mCapDataInfo.HeaderSize = (UINT32) TempNumber;\r
391 DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%x", EFI_CAPSULE_HEADER_SIZE_STRING, TempNumber);\r
392 argc -= 2;\r
393 argv += 2;\r
394 continue; \r
395 }\r
396\r
397 if (stricmp (argv[0], "--capflag") == 0) {\r
398 //\r
399 // Get Capsule Header\r
400 //\r
401 if (argv[1] == NULL) {\r
402 Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);\r
403 return STATUS_ERROR;\r
404 }\r
405 if (strcmp (argv[1], "PopulateSystemTable") == 0) {\r
406 mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;\r
407 } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {\r
408 mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;\r
409 } else {\r
410 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
411 return STATUS_ERROR;\r
412 }\r
413 DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);\r
414 argc -= 2;\r
415 argv += 2;\r
416 continue; \r
417 }\r
418\r
419 if (stricmp (argv[0], "--capguid") == 0) {\r
420 //\r
421 // Get the Capsule Guid\r
422 //\r
423 Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
424 if (EFI_ERROR (Status)) {\r
425 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
426 return STATUS_ERROR;\r
427 }\r
428 DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
429 argc -= 2;\r
430 argv += 2;\r
431 continue; \r
432 }\r
433\r
434 if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {\r
435 //\r
436 // Get the Capsule or Fv Guid\r
437 //\r
438 Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
439 if (EFI_ERROR (Status)) {\r
440 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
441 return STATUS_ERROR;\r
442 }\r
443 memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));\r
444 mFvDataInfo.FvFileSystemGuidSet = TRUE;\r
445 DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
446 DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);\r
447 argc -= 2;\r
448 argv += 2;\r
449 continue; \r
450 }\r
451\r
452 if (stricmp (argv[0], "--FvNameGuid") == 0) {\r
453 //\r
454 // Get Fv Name Guid\r
455 //\r
456 Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);\r
457 if (EFI_ERROR (Status)) {\r
458 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
459 return STATUS_ERROR;\r
460 }\r
461 mFvDataInfo.FvNameGuidSet = TRUE;\r
462 DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);\r
463 argc -= 2;\r
464 argv += 2;\r
465 continue; \r
466 }\r
467\r
468 if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
469 DumpCapsule = TRUE;\r
470 argc --;\r
471 argv ++;\r
472 continue; \r
473 }\r
474\r
475 if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {\r
476 MapFileName = argv[1];\r
477 if (MapFileName == NULL) {\r
478 Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");\r
479 return STATUS_ERROR;\r
480 }\r
481 argc -= 2;\r
482 argv += 2;\r
483 continue; \r
484 }\r
485\r
486 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
487 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
488 VerboseMsg ("Verbose output Mode Set!");\r
489 argc --;\r
490 argv ++;\r
491 continue;\r
492 }\r
493\r
494 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
495 SetPrintLevel (KEY_LOG_LEVEL);\r
496 KeyMsg ("Quiet output Mode Set!");\r
497 argc --;\r
498 argv ++;\r
499 continue;\r
500 }\r
501\r
502 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
503 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
504 if (EFI_ERROR (Status)) {\r
505 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
506 return STATUS_ERROR;\r
507 }\r
508 if (LogLevel > 9) {\r
509 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", LogLevel);\r
510 return STATUS_ERROR;\r
511 }\r
512 SetPrintLevel (LogLevel);\r
513 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
514 argc -= 2;\r
515 argv += 2;\r
516 continue;\r
517 }\r
518\r
519 //\r
520 // Don't recognize the parameter.\r
521 //\r
522 Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);\r
523 return STATUS_ERROR;\r
524 }\r
525\r
526 VerboseMsg ("%s tool start.", UTILITY_NAME);\r
527 \r
528 //\r
529 // check input parameter, InfFileName can be NULL\r
530 //\r
531 if (InfFileName == NULL && DumpCapsule) {\r
532 Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");\r
533 return STATUS_ERROR;\r
534 }\r
535 VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);\r
536\r
537 if (!DumpCapsule && OutFileName == NULL) {\r
538 Error (NULL, 0, 1001, "Missing option", "Output File");\r
539 return STATUS_ERROR;\r
540 }\r
541 if (OutFileName != NULL) {\r
542 VerboseMsg ("the output file name is %s", OutFileName);\r
543 }\r
544 \r
545 //\r
546 // Read boot and runtime address from address file\r
547 //\r
548 if (AddrFileName != NULL) {\r
549 VerboseMsg ("the input address file name is %s", AddrFileName);\r
550 Status = GetFileImage (AddrFileName, &InfFileImage, &InfFileSize);\r
551 if (EFI_ERROR (Status)) {\r
552 return STATUS_ERROR;\r
553 }\r
554\r
555 AddrMemoryFile.FileImage = InfFileImage;\r
556 AddrMemoryFile.CurrentFilePointer = InfFileImage;\r
557 AddrMemoryFile.Eof = InfFileImage + InfFileSize;\r
558\r
559 //\r
560 // Read the boot driver base address for this FV image\r
561 //\r
562 Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
563 if (Status == EFI_SUCCESS) {\r
564 //\r
565 // Get the base address\r
566 //\r
567 Status = AsciiStringToUint64 (ValueString, FALSE, &TempNumber);\r
568 if (EFI_ERROR (Status)) {\r
569 Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
570 return STATUS_ERROR;\r
571 }\r
572 mFvDataInfo.BootBaseAddress = TempNumber;\r
573 DebugMsg (NULL, 0, 9, "Boot driver base address", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
574 }\r
575 \r
576 //\r
577 // Read the FV runtime driver base address\r
578 //\r
579 Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
580 if (Status == EFI_SUCCESS) {\r
581 //\r
582 // Get the base address\r
583 //\r
584 Status = AsciiStringToUint64 (ValueString, FALSE, &TempNumber);\r
585 if (EFI_ERROR (Status)) {\r
586 Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
587 return STATUS_ERROR;\r
588 }\r
589 mFvDataInfo.RuntimeBaseAddress = TempNumber;\r
590 DebugMsg (NULL, 0, 9, "Runtime driver base address", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
591 }\r
592 \r
593 //\r
594 // free the allocated memory space for addr file.\r
595 //\r
596 free (InfFileImage);\r
597 InfFileImage = NULL;\r
598 InfFileSize = 0;\r
599 }\r
600\r
601 //\r
602 // Read the INF file image\r
603 //\r
604 if (InfFileName != NULL) {\r
605 Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
606 if (EFI_ERROR (Status)) {\r
607 return STATUS_ERROR;\r
608 }\r
609 }\r
610 \r
611 if (DumpCapsule) {\r
612 VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);\r
613 //\r
614 // Dump Capsule Image Header Information\r
615 //\r
616 CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;\r
617 if (OutFileName == NULL) {\r
618 FpFile = stdout;\r
619 } else {\r
620 FpFile = fopen (OutFileName, "w");\r
621 if (FpFile == NULL) {\r
622 Error (NULL, 0, 0001, "Error opening file", OutFileName);\r
623 return STATUS_ERROR;\r
624 }\r
625 }\r
626 fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);\r
627 fprintf (FpFile, " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", \r
628 CapsuleHeader->CapsuleGuid.Data1,\r
629 (UINT32) CapsuleHeader->CapsuleGuid.Data2,\r
630 (UINT32) CapsuleHeader->CapsuleGuid.Data3,\r
631 (UINT32) CapsuleHeader->CapsuleGuid.Data4[0],\r
632 (UINT32) CapsuleHeader->CapsuleGuid.Data4[1],\r
633 (UINT32) CapsuleHeader->CapsuleGuid.Data4[2],\r
634 (UINT32) CapsuleHeader->CapsuleGuid.Data4[3],\r
635 (UINT32) CapsuleHeader->CapsuleGuid.Data4[4],\r
636 (UINT32) CapsuleHeader->CapsuleGuid.Data4[5],\r
637 (UINT32) CapsuleHeader->CapsuleGuid.Data4[6],\r
638 (UINT32) CapsuleHeader->CapsuleGuid.Data4[7]);\r
639 fprintf (FpFile, " Header size 0x%08X\n", CapsuleHeader->HeaderSize);\r
640 fprintf (FpFile, " Flags 0x%08X\n", CapsuleHeader->Flags);\r
641 fprintf (FpFile, " Capsule image size 0x%08X\n", CapsuleHeader->CapsuleImageSize);\r
642 fclose (FpFile);\r
643 } else if (CapsuleFlag) {\r
644 VerboseMsg ("Create capsule image");\r
645 //\r
646 // Call the GenerateCapImage to generate Capsule Image\r
647 //\r
648 for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {\r
649 strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);\r
650 }\r
651\r
652 Status = GenerateCapImage (\r
653 InfFileImage, \r
654 InfFileSize,\r
655 OutFileName\r
656 );\r
657 } else {\r
658 VerboseMsg ("Create Fv image and its map file");\r
659 if (mFvDataInfo.BaseAddress != 0) {\r
660 VerboseMsg ("FvImage Rebase Address is 0x%X", mFvDataInfo.BaseAddress);\r
661 }\r
662 //\r
663 // Call the GenerateFvImage to generate Fv Image\r
664 //\r
665 Status = GenerateFvImage (\r
666 InfFileImage,\r
667 InfFileSize,\r
668 OutFileName,\r
669 MapFileName\r
670 );\r
671 }\r
672\r
673 //\r
674 // free InfFileImage memory\r
675 //\r
676 if (InfFileImage != NULL) {\r
677 free (InfFileImage);\r
678 }\r
679 \r
680 //\r
681 // update boot driver address and runtime driver address in address file\r
682 //\r
683 if (Status == EFI_SUCCESS && AddrFileName != NULL) {\r
684 FpFile = fopen (AddrFileName, "w");\r
685 if (FpFile == NULL) {\r
686 Error (NULL, 0, 0001, "Error opening file", AddrFileName);\r
687 return STATUS_ERROR;\r
688 }\r
689 fprintf (FpFile, OPTIONS_SECTION_STRING);\r
690 fprintf (FpFile, "\n");\r
691 if (mFvDataInfo.BootBaseAddress != 0) {\r
692 fprintf (FpFile, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING);\r
693 fprintf (FpFile, " = 0x%lx\n", mFvDataInfo.BootBaseAddress);\r
694 DebugMsg (NULL, 0, 9, "Updated boot driver base address", "%s = 0x%x", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, mFvDataInfo.BootBaseAddress);\r
695 }\r
696 if (mFvDataInfo.RuntimeBaseAddress != 0) {\r
697 fprintf (FpFile, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING);\r
698 fprintf (FpFile, " = 0x%lx\n", mFvDataInfo.RuntimeBaseAddress);\r
699 DebugMsg (NULL, 0, 9, "Updated runtime driver base address", "%s = 0x%x", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, mFvDataInfo.RuntimeBaseAddress);\r
700 }\r
701 fclose (FpFile);\r
702 }\r
703 \r
704 if (Status == EFI_SUCCESS) {\r
705 DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, mFvTotalSize);\r
706 DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, mFvTakenSize);\r
707 DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, mFvTotalSize - mFvTakenSize);\r
708 }\r
709\r
710 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
711\r
712 return GetUtilityStatus ();\r
713}\r