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