]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/GenFv/GenFv.c
There is a limitation on WINDOWS OS for the length of entire file path can’t be large...
[mirror_edk2.git] / BaseTools / Source / C / GenFv / GenFv.c
1 /** @file
2
3 Copyright (c) 2007 - 2014, 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 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
44 EFI_GUID mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;
45 EFI_GUID mEfiFirmwareFileSystem3Guid = EFI_FIRMWARE_FILE_SYSTEM3_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, __BUILD_VERSION);
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 - 2014, 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, " -F ForceRebase, --force-rebase ForceRebase\n\
129 If value is TRUE, will always take rebase action\n\
130 If value is FALSE, will always not take reabse action\n\
131 If not specified, will take rebase action if rebase address greater than zero, \n\
132 will not take rebase action if rebase address is zero.\n");
133 fprintf (stdout, " -a AddressFile, --addrfile AddressFile\n\
134 AddressFile is one file used to record the child\n\
135 FV base address when current FV base address is set.\n");
136 fprintf (stdout, " -m logfile, --map logfile\n\
137 Logfile is the output fv map file name. if it is not\n\
138 given, the FvName.map will be the default map file name\n");
139 fprintf (stdout, " -g Guid, --guid Guid\n\
140 GuidValue is one specific capsule guid value\n\
141 or fv file system guid value.\n\
142 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
143 fprintf (stdout, " --FvNameGuid Guid Guid is used to specify Fv Name.\n\
144 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
145 fprintf (stdout, " --capflag CapFlag Capsule Reset Flag can be PersistAcrossReset,\n\
146 or PopulateSystemTable or InitiateReset or not set\n");
147 fprintf (stdout, " --capoemflag CapOEMFlag\n\
148 Capsule OEM Flag is an integer between 0x0000 and 0xffff\n");
149 fprintf (stdout, " --capheadsize HeadSize\n\
150 HeadSize is one HEX or DEC format value\n\
151 HeadSize is required by Capsule Image.\n");
152 fprintf (stdout, " -c, --capsule Create Capsule Image.\n");
153 fprintf (stdout, " -p, --dump Dump Capsule Image header.\n");
154 fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
155 fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
156 fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
157 fprintf (stdout, " --version Show program's version number and exit.\n");
158 fprintf (stdout, " -h, --help Show this help message and exit.\n");
159 }
160
161 UINT32 mFvTotalSize;
162 UINT32 mFvTakenSize;
163
164 int
165 main (
166 IN int argc,
167 IN char **argv
168 )
169 /*++
170
171 Routine Description:
172
173 This utility uses GenFvImage.Lib to build a firmware volume image.
174
175 Arguments:
176
177 FvInfFileName The name of an FV image description file or Capsule Image.
178
179 Arguments come in pair in any order.
180 -I FvInfFileName
181
182 Returns:
183
184 EFI_SUCCESS No error conditions detected.
185 EFI_INVALID_PARAMETER One or more of the input parameters is invalid.
186 EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable.
187 Most commonly this will be memory allocation
188 or file creation.
189 EFI_LOAD_ERROR GenFvImage.lib could not be loaded.
190 EFI_ABORTED Error executing the GenFvImage lib.
191
192 --*/
193 {
194 EFI_STATUS Status;
195 CHAR8 *InfFileName;
196 CHAR8 *AddrFileName;
197 CHAR8 *MapFileName;
198 CHAR8 *InfFileImage;
199 UINT32 InfFileSize;
200 CHAR8 *OutFileName;
201 BOOLEAN CapsuleFlag;
202 BOOLEAN DumpCapsule;
203 FILE *FpFile;
204 EFI_CAPSULE_HEADER *CapsuleHeader;
205 UINT64 LogLevel, TempNumber;
206 UINT32 Index;
207
208 InfFileName = NULL;
209 AddrFileName = NULL;
210 InfFileImage = NULL;
211 OutFileName = NULL;
212 MapFileName = NULL;
213 InfFileSize = 0;
214 CapsuleFlag = FALSE;
215 DumpCapsule = FALSE;
216 FpFile = NULL;
217 CapsuleHeader = NULL;
218 LogLevel = 0;
219 TempNumber = 0;
220 Index = 0;
221 mFvTotalSize = 0;
222 mFvTakenSize = 0;
223 Status = EFI_SUCCESS;
224
225 SetUtilityName (UTILITY_NAME);
226
227 if (argc == 1) {
228 Error (NULL, 0, 1001, "Missing options", "No input options specified.");
229 Usage ();
230 return STATUS_ERROR;
231 }
232
233 //
234 // Init global data to Zero
235 //
236 memset (&mFvDataInfo, 0, sizeof (FV_INFO));
237 memset (&mCapDataInfo, 0, sizeof (CAP_INFO));
238 //
239 // Set the default FvGuid
240 //
241 memcpy (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid, sizeof (EFI_GUID));
242 mFvDataInfo.ForceRebase = -1;
243
244 //
245 // Parse command line
246 //
247 argc --;
248 argv ++;
249
250 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
251 Version ();
252 Usage ();
253 return STATUS_SUCCESS;
254 }
255
256 if (stricmp (argv[0], "--version") == 0) {
257 Version ();
258 return STATUS_SUCCESS;
259 }
260
261 while (argc > 0) {
262 if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {
263 InfFileName = argv[1];
264 if (InfFileName == NULL) {
265 Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");
266 return STATUS_ERROR;
267 }
268 argc -= 2;
269 argv += 2;
270 continue;
271 }
272
273 if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {
274 AddrFileName = argv[1];
275 if (AddrFileName == NULL) {
276 Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");
277 return STATUS_ERROR;
278 }
279 argc -= 2;
280 argv += 2;
281 continue;
282 }
283
284 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
285 OutFileName = argv[1];
286 if (OutFileName == NULL) {
287 Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
288 return STATUS_ERROR;
289 }
290 argc -= 2;
291 argv += 2;
292 continue;
293 }
294
295 if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 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 mFvDataInfo.BaseAddress = TempNumber;
302 mFvDataInfo.BaseAddressSet = TRUE;
303 argc -= 2;
304 argv += 2;
305 continue;
306 }
307
308 if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {
309 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
310 if (EFI_ERROR (Status)) {
311 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
312 return STATUS_ERROR;
313 }
314 if (TempNumber == 0) {
315 Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");
316 return STATUS_ERROR;
317 }
318 mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;
319 DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%llx", EFI_BLOCK_SIZE_STRING, (unsigned long long) TempNumber);
320 argc -= 2;
321 argv += 2;
322 continue;
323 }
324
325 if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {
326 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
327 if (EFI_ERROR (Status)) {
328 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
329 return STATUS_ERROR;
330 }
331 if (TempNumber == 0) {
332 Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");
333 return STATUS_ERROR;
334 }
335 mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;
336 DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%llx", EFI_NUM_BLOCKS_STRING, (unsigned long long) TempNumber);
337 argc -= 2;
338 argv += 2;
339 continue;
340 }
341
342 if ((strcmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {
343 if (argv[1] == NULL) {
344 Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");
345 return STATUS_ERROR;
346 }
347 strcpy (mFvDataInfo.FvFiles[Index], argv[1]);
348 DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index + 1, argv[1]);
349 argc -= 2;
350 argv += 2;
351
352 if (argc > 0) {
353 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
354 if (argv[1] == NULL) {
355 Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");
356 return STATUS_ERROR;
357 }
358 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
359 if (EFI_ERROR (Status)) {
360 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
361 return STATUS_ERROR;
362 }
363 mFvDataInfo.SizeofFvFiles[Index] = (UINT32) TempNumber;
364 DebugMsg (NULL, 0, 9, "FV component file size", "the %uth size is %s", (unsigned) Index + 1, argv[1]);
365 argc -= 2;
366 argv += 2;
367 }
368 }
369 Index ++;
370 continue;
371 }
372
373 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
374 Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");
375 return STATUS_ERROR;
376 }
377
378 if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {
379 CapsuleFlag = TRUE;
380 argc --;
381 argv ++;
382 continue;
383 }
384
385 if ((strcmp (argv[0], "-F") == 0) || (stricmp (argv[0], "--force-rebase") == 0)) {
386 if (argv[1] == NULL) {
387 Error (NULL, 0, 1003, "Invalid option value", "Froce rebase flag can't be null");
388 return STATUS_ERROR;
389 }
390
391 if (stricmp (argv[1], "TRUE") == 0) {
392 mFvDataInfo.ForceRebase = 1;
393 } else if (stricmp (argv[1], "FALSE") == 0) {
394 mFvDataInfo.ForceRebase = 0;
395 } else {
396 Error (NULL, 0, 1003, "Invalid option value", "froce rebase flag value must be \"TRUE\" or \"FALSE\"");
397 return STATUS_ERROR;
398 }
399
400 argc -= 2;
401 argv += 2;
402 continue;
403 }
404
405 if (stricmp (argv[0], "--capheadsize") == 0) {
406 //
407 // Get Capsule Image Header Size
408 //
409 Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
410 if (EFI_ERROR (Status)) {
411 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
412 return STATUS_ERROR;
413 }
414 mCapDataInfo.HeaderSize = (UINT32) TempNumber;
415 DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%llx", EFI_CAPSULE_HEADER_SIZE_STRING, (unsigned long long) TempNumber);
416 argc -= 2;
417 argv += 2;
418 continue;
419 }
420
421 if (stricmp (argv[0], "--capflag") == 0) {
422 //
423 // Get Capsule Header
424 //
425 if (argv[1] == NULL) {
426 Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);
427 return STATUS_ERROR;
428 }
429 if (strcmp (argv[1], "PopulateSystemTable") == 0) {
430 mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
431 } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {
432 mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
433 } else if (strcmp (argv[1], "InitiateReset") == 0) {
434 mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET;
435 } else {
436 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
437 return STATUS_ERROR;
438 }
439 DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);
440 argc -= 2;
441 argv += 2;
442 continue;
443 }
444
445 if (stricmp (argv[0], "--capoemflag") == 0) {
446 if (argv[1] == NULL) {
447 Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag can't be null");
448 }
449 Status = AsciiStringToUint64(argv[1], FALSE, &TempNumber);
450 if (EFI_ERROR (Status) || TempNumber > 0xffff) {
451 Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag value must be integer value between 0x0000 and 0xffff");
452 return STATUS_ERROR;
453 }
454 mCapDataInfo.Flags |= TempNumber;
455 DebugMsg( NULL, 0, 9, "Capsule OEM Flags", argv[1]);
456 argc -= 2;
457 argv += 2;
458 continue;
459 }
460
461 if (stricmp (argv[0], "--capguid") == 0) {
462 //
463 // Get the Capsule Guid
464 //
465 Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
466 if (EFI_ERROR (Status)) {
467 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
468 return STATUS_ERROR;
469 }
470 DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
471 argc -= 2;
472 argv += 2;
473 continue;
474 }
475
476 if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {
477 //
478 // Get the Capsule or Fv Guid
479 //
480 Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
481 if (EFI_ERROR (Status)) {
482 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
483 return STATUS_ERROR;
484 }
485 memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));
486 mFvDataInfo.FvFileSystemGuidSet = TRUE;
487 DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
488 DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);
489 argc -= 2;
490 argv += 2;
491 continue;
492 }
493
494 if (stricmp (argv[0], "--FvNameGuid") == 0) {
495 //
496 // Get Fv Name Guid
497 //
498 Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);
499 if (EFI_ERROR (Status)) {
500 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
501 return STATUS_ERROR;
502 }
503 mFvDataInfo.FvNameGuidSet = TRUE;
504 DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);
505 argc -= 2;
506 argv += 2;
507 continue;
508 }
509
510 if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {
511 DumpCapsule = TRUE;
512 argc --;
513 argv ++;
514 continue;
515 }
516
517 if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {
518 MapFileName = argv[1];
519 if (MapFileName == NULL) {
520 Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");
521 return STATUS_ERROR;
522 }
523 argc -= 2;
524 argv += 2;
525 continue;
526 }
527
528 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
529 SetPrintLevel (VERBOSE_LOG_LEVEL);
530 VerboseMsg ("Verbose output Mode Set!");
531 argc --;
532 argv ++;
533 continue;
534 }
535
536 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
537 SetPrintLevel (KEY_LOG_LEVEL);
538 KeyMsg ("Quiet output Mode Set!");
539 argc --;
540 argv ++;
541 continue;
542 }
543
544 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
545 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
546 if (EFI_ERROR (Status)) {
547 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
548 return STATUS_ERROR;
549 }
550 if (LogLevel > 9) {
551 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
552 return STATUS_ERROR;
553 }
554 SetPrintLevel (LogLevel);
555 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
556 argc -= 2;
557 argv += 2;
558 continue;
559 }
560
561 //
562 // Don't recognize the parameter.
563 //
564 Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);
565 return STATUS_ERROR;
566 }
567
568 VerboseMsg ("%s tool start.", UTILITY_NAME);
569
570 //
571 // check input parameter, InfFileName can be NULL
572 //
573 if (InfFileName == NULL && DumpCapsule) {
574 Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");
575 return STATUS_ERROR;
576 }
577 VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);
578
579 if (!DumpCapsule && OutFileName == NULL) {
580 Error (NULL, 0, 1001, "Missing option", "Output File");
581 return STATUS_ERROR;
582 }
583 if (OutFileName != NULL) {
584 VerboseMsg ("the output file name is %s", OutFileName);
585 }
586
587 //
588 // Read the INF file image
589 //
590 if (InfFileName != NULL) {
591 Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);
592 if (EFI_ERROR (Status)) {
593 return STATUS_ERROR;
594 }
595 }
596
597 if (DumpCapsule) {
598 VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);
599 //
600 // Dump Capsule Image Header Information
601 //
602 CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;
603 if (OutFileName == NULL) {
604 FpFile = stdout;
605 } else {
606 FpFile = fopen (LongFilePath (OutFileName), "w");
607 if (FpFile == NULL) {
608 Error (NULL, 0, 0001, "Error opening file", OutFileName);
609 return STATUS_ERROR;
610 }
611 }
612 fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);
613 fprintf (FpFile, " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
614 (unsigned) CapsuleHeader->CapsuleGuid.Data1,
615 (unsigned) CapsuleHeader->CapsuleGuid.Data2,
616 (unsigned) CapsuleHeader->CapsuleGuid.Data3,
617 (unsigned) CapsuleHeader->CapsuleGuid.Data4[0],
618 (unsigned) CapsuleHeader->CapsuleGuid.Data4[1],
619 (unsigned) CapsuleHeader->CapsuleGuid.Data4[2],
620 (unsigned) CapsuleHeader->CapsuleGuid.Data4[3],
621 (unsigned) CapsuleHeader->CapsuleGuid.Data4[4],
622 (unsigned) CapsuleHeader->CapsuleGuid.Data4[5],
623 (unsigned) CapsuleHeader->CapsuleGuid.Data4[6],
624 (unsigned) CapsuleHeader->CapsuleGuid.Data4[7]);
625 fprintf (FpFile, " Header size 0x%08X\n", (unsigned) CapsuleHeader->HeaderSize);
626 fprintf (FpFile, " Flags 0x%08X\n", (unsigned) CapsuleHeader->Flags);
627 fprintf (FpFile, " Capsule image size 0x%08X\n", (unsigned) CapsuleHeader->CapsuleImageSize);
628 fclose (FpFile);
629 } else if (CapsuleFlag) {
630 VerboseMsg ("Create capsule image");
631 //
632 // Call the GenerateCapImage to generate Capsule Image
633 //
634 for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {
635 strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);
636 }
637
638 Status = GenerateCapImage (
639 InfFileImage,
640 InfFileSize,
641 OutFileName
642 );
643 } else {
644 VerboseMsg ("Create Fv image and its map file");
645 //
646 // Will take rebase action at below situation:
647 // 1. ForceRebase Flag specified to TRUE;
648 // 2. ForceRebase Flag not specified, BaseAddress greater than zero.
649 //
650 if (((mFvDataInfo.BaseAddress > 0) && (mFvDataInfo.ForceRebase == -1)) || (mFvDataInfo.ForceRebase == 1)) {
651 VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);
652 }
653 //
654 // Call the GenerateFvImage to generate Fv Image
655 //
656 Status = GenerateFvImage (
657 InfFileImage,
658 InfFileSize,
659 OutFileName,
660 MapFileName
661 );
662 }
663
664 //
665 // free InfFileImage memory
666 //
667 if (InfFileImage != NULL) {
668 free (InfFileImage);
669 }
670
671 //
672 // update boot driver address and runtime driver address in address file
673 //
674 if (Status == EFI_SUCCESS && AddrFileName != NULL && mFvBaseAddressNumber > 0) {
675 FpFile = fopen (LongFilePath (AddrFileName), "w");
676 if (FpFile == NULL) {
677 Error (NULL, 0, 0001, "Error opening file", AddrFileName);
678 return STATUS_ERROR;
679 }
680 fprintf (FpFile, FV_BASE_ADDRESS_STRING);
681 fprintf (FpFile, "\n");
682 for (Index = 0; Index < mFvBaseAddressNumber; Index ++) {
683 fprintf (
684 FpFile,
685 "0x%llx\n",
686 (unsigned long long)mFvBaseAddress[Index]
687 );
688 }
689 fflush (FpFile);
690 fclose (FpFile);
691 }
692
693 if (Status == EFI_SUCCESS) {
694 DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
695 DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);
696 DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));
697 }
698
699 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
700
701 return GetUtilityStatus ();
702 }