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