3 Copyright (c) 2007 - 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
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.
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.
26 // File included in build
31 #include "GenFvInternalLib.h"
36 #define UTILITY_NAME "GenFv"
39 // Utility version information
41 #define UTILITY_MAJOR_VERSION 0
42 #define UTILITY_MINOR_VERSION 1
43 #define GENFV_UPDATE_TIME " updated on 2010/2/1"
45 EFI_GUID mEfiFirmwareFileSystem2Guid
= EFI_FIRMWARE_FILE_SYSTEM2_GUID
;
56 Displays the standard utility information to SDTOUT
68 fprintf (stdout
, "%s Version %d.%d %s\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, GENFV_UPDATE_TIME
);
80 Displays the utility usage syntax to STDOUT
95 fprintf (stdout
, "\nUsage: %s [options]\n\n", UTILITY_NAME
);
98 // Copyright declaration
100 fprintf (stdout
, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
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");
166 This utility uses GenFvImage.Lib to build a firmware volume image.
170 FvInfFileName The name of an FV image description file or Capsule Image.
172 Arguments come in pair in any order.
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
182 EFI_LOAD_ERROR GenFvImage.lib could not be loaded.
183 EFI_ABORTED Error executing the GenFvImage lib.
197 EFI_CAPSULE_HEADER
*CapsuleHeader
;
198 UINT64 LogLevel
, TempNumber
;
210 CapsuleHeader
= NULL
;
216 Status
= EFI_SUCCESS
;
218 SetUtilityName (UTILITY_NAME
);
221 Error (NULL
, 0, 1001, "Missing options", "No input options specified.");
227 // Init global data to Zero
229 memset (&mFvDataInfo
, 0, sizeof (FV_INFO
));
230 memset (&mCapDataInfo
, 0, sizeof (CAP_INFO
));
232 // Set the default FvGuid
234 memcpy (&mFvDataInfo
.FvFileSystemGuid
, &mEfiFirmwareFileSystem2Guid
, sizeof (EFI_GUID
));
237 // Parse command line
242 if ((stricmp (argv
[0], "-h") == 0) || (stricmp (argv
[0], "--help") == 0)) {
245 return STATUS_SUCCESS
;
248 if (stricmp (argv
[0], "--version") == 0) {
250 return STATUS_SUCCESS
;
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");
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");
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");
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]);
293 mFvDataInfo
.BaseAddress
= TempNumber
;
294 mFvDataInfo
.BaseAddressSet
= TRUE
;
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]);
306 if (TempNumber
== 0) {
307 Error (NULL
, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");
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
);
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]);
323 if (TempNumber
== 0) {
324 Error (NULL
, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");
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
);
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");
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]);
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");
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]);
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]);
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.");
370 if ((stricmp (argv
[0], "-c") == 0) || (stricmp (argv
[0], "--capsule") == 0)) {
377 if (stricmp (argv
[0], "--capheadsize") == 0) {
379 // Get Capsule Image Header Size
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]);
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
);
393 if (stricmp (argv
[0], "--capflag") == 0) {
395 // Get Capsule Header
397 if (argv
[1] == NULL
) {
398 Error (NULL
, 0, 1003, "Option value is not set", "%s = %s", argv
[0], argv
[1]);
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
;
408 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
411 DebugMsg (NULL
, 0, 9, "Capsule Flag", argv
[1]);
417 if (stricmp (argv
[0], "--capguid") == 0) {
419 // Get the Capsule Guid
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]);
426 DebugMsg (NULL
, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING
, argv
[1]);
432 if ((stricmp (argv
[0], "-g") == 0) || (stricmp (argv
[0], "--guid") == 0)) {
434 // Get the Capsule or Fv Guid
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]);
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]);
450 if (stricmp (argv
[0], "--FvNameGuid") == 0) {
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]);
459 mFvDataInfo
.FvNameGuidSet
= TRUE
;
460 DebugMsg (NULL
, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING
, argv
[1]);
466 if ((stricmp (argv
[0], "-p") == 0) || (stricmp (argv
[0], "--dump") == 0)) {
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");
484 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
485 SetPrintLevel (VERBOSE_LOG_LEVEL
);
486 VerboseMsg ("Verbose output Mode Set!");
492 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
493 SetPrintLevel (KEY_LOG_LEVEL
);
494 KeyMsg ("Quiet output Mode Set!");
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]);
507 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel
);
510 SetPrintLevel (LogLevel
);
511 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
518 // Don't recognize the parameter.
520 Error (NULL
, 0, 1000, "Unknown option", "%s", argv
[0]);
524 VerboseMsg ("%s tool start.", UTILITY_NAME
);
527 // check input parameter, InfFileName can be NULL
529 if (InfFileName
== NULL
&& DumpCapsule
) {
530 Error (NULL
, 0, 1001, "Missing option", "Input Capsule Image");
533 VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName
);
535 if (!DumpCapsule
&& OutFileName
== NULL
) {
536 Error (NULL
, 0, 1001, "Missing option", "Output File");
539 if (OutFileName
!= NULL
) {
540 VerboseMsg ("the output file name is %s", OutFileName
);
544 // Read the INF file image
546 if (InfFileName
!= NULL
) {
547 Status
= GetFileImage (InfFileName
, &InfFileImage
, &InfFileSize
);
548 if (EFI_ERROR (Status
)) {
554 VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName
);
556 // Dump Capsule Image Header Information
558 CapsuleHeader
= (EFI_CAPSULE_HEADER
*) InfFileImage
;
559 if (OutFileName
== NULL
) {
562 FpFile
= fopen (OutFileName
, "w");
563 if (FpFile
== NULL
) {
564 Error (NULL
, 0, 0001, "Error opening file", OutFileName
);
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
);
585 } else if (CapsuleFlag
) {
586 VerboseMsg ("Create capsule image");
588 // Call the GenerateCapImage to generate Capsule Image
590 for (Index
= 0; mFvDataInfo
.FvFiles
[Index
][0] != '\0'; Index
++) {
591 strcpy (mCapDataInfo
.CapFiles
[Index
], mFvDataInfo
.FvFiles
[Index
]);
594 Status
= GenerateCapImage (
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
);
605 // Call the GenerateFvImage to generate Fv Image
607 Status
= GenerateFvImage (
616 // free InfFileImage memory
618 if (InfFileImage
!= NULL
) {
623 // update boot driver address and runtime driver address in address file
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
);
631 fprintf (FpFile
, FV_BASE_ADDRESS_STRING
);
632 fprintf (FpFile
, "\n");
633 for (Index
= 0; Index
< mFvBaseAddressNumber
; Index
++) {
637 (unsigned long long)mFvBaseAddress
[Index
]
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
));
650 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME
, GetUtilityStatus ());
652 return GetUtilityStatus ();