Home | History | Annotate | Download | only in GenFv
      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 - 2014, Intel Corporation. All rights reserved.<BR>
      8 This program and the accompanying materials
      9 are licensed and made available under the terms and conditions of the BSD License
     10 which accompanies this distribution.  The full text of the license may be found at
     11 http://opensource.org/licenses/bsd-license.php
     12 
     13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 //
     19 // File included in build
     20 //
     21 #include <stdio.h>
     22 #include <string.h>
     23 #include <stdlib.h>
     24 #include "GenFvInternalLib.h"
     25 
     26 //
     27 // Utility Name
     28 //
     29 #define UTILITY_NAME  "GenFv"
     30 
     31 //
     32 // Utility version information
     33 //
     34 #define UTILITY_MAJOR_VERSION 0
     35 #define UTILITY_MINOR_VERSION 1
     36 
     37 EFI_GUID  mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;
     38 EFI_GUID  mEfiFirmwareFileSystem3Guid = EFI_FIRMWARE_FILE_SYSTEM3_GUID;
     39 
     40 STATIC
     41 VOID
     42 Version (
     43   VOID
     44 )
     45 /*++
     46 
     47 Routine Description:
     48 
     49   Displays the standard utility information to SDTOUT
     50 
     51 Arguments:
     52 
     53   None
     54 
     55 Returns:
     56 
     57   None
     58 
     59 --*/
     60 {
     61   fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
     62 }
     63 
     64 STATIC
     65 VOID
     66 Usage (
     67   VOID
     68   )
     69 /*++
     70 
     71 Routine Description:
     72 
     73   Displays the utility usage syntax to STDOUT
     74 
     75 Arguments:
     76 
     77   None
     78 
     79 Returns:
     80 
     81   None
     82 
     83 --*/
     84 {
     85   //
     86   // Summary usage
     87   //
     88   fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
     89 
     90   //
     91   // Copyright declaration
     92   //
     93   fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
     94 
     95   //
     96   // Details Option
     97   //
     98   fprintf (stdout, "Options:\n");
     99   fprintf (stdout, "  -o FileName, --outputfile FileName\n\
    100                         File is the FvImage or CapImage to be created.\n");
    101   fprintf (stdout, "  -i FileName, --inputfile FileName\n\
    102                         File is the input FV.inf or Cap.inf to specify\n\
    103                         how to construct FvImage or CapImage.\n");
    104   fprintf (stdout, "  -b BlockSize, --blocksize BlockSize\n\
    105                         BlockSize is one HEX or DEC format value\n\
    106                         BlockSize is required by Fv Image.\n");
    107   fprintf (stdout, "  -n NumberBlock, --numberblock NumberBlock\n\
    108                         NumberBlock is one HEX or DEC format value\n\
    109                         NumberBlock is one optional parameter.\n");
    110   fprintf (stdout, "  -f FfsFile, --ffsfile FfsFile\n\
    111                         FfsFile is placed into Fv Image\n\
    112                         multi files can input one by one\n");
    113   fprintf (stdout, "  -s FileTakenSize, --filetakensize FileTakenSize\n\
    114                         FileTakenSize specifies the size of the required\n\
    115                         space that the input file is placed in Fvimage.\n\
    116                         It is specified together with the input file.\n");
    117   fprintf (stdout, "  -r Address, --baseaddr Address\n\
    118                         Address is the rebase start address for drivers that\n\
    119                         run in Flash. It supports DEC or HEX digital format.\n\
    120                         If it is set to zero, no rebase action will be taken\n");
    121   fprintf (stdout, "  -F ForceRebase, --force-rebase ForceRebase\n\
    122                         If value is TRUE, will always take rebase action\n\
    123                         If value is FALSE, will always not take reabse action\n\
    124                         If not specified, will take rebase action if rebase address greater than zero, \n\
    125                         will not take rebase action if rebase address is zero.\n");
    126   fprintf (stdout, "  -a AddressFile, --addrfile AddressFile\n\
    127                         AddressFile is one file used to record the child\n\
    128                         FV base address when current FV base address is set.\n");
    129   fprintf (stdout, "  -m logfile, --map logfile\n\
    130                         Logfile is the output fv map file name. if it is not\n\
    131                         given, the FvName.map will be the default map file name\n");
    132   fprintf (stdout, "  -g Guid, --guid Guid\n\
    133                         GuidValue is one specific capsule guid value\n\
    134                         or fv file system guid value.\n\
    135                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
    136   fprintf (stdout, "  --FvNameGuid Guid     Guid is used to specify Fv Name.\n\
    137                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
    138   fprintf (stdout, "  --capflag CapFlag     Capsule Reset Flag can be PersistAcrossReset,\n\
    139                         or PopulateSystemTable or InitiateReset or not set\n");
    140   fprintf (stdout, "  --capoemflag CapOEMFlag\n\
    141                         Capsule OEM Flag is an integer between 0x0000 and 0xffff\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   mFvDataInfo.ForceRebase = -1;
    236 
    237   //
    238   // Parse command line
    239   //
    240   argc --;
    241   argv ++;
    242 
    243   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
    244     Version ();
    245     Usage ();
    246     return STATUS_SUCCESS;
    247   }
    248 
    249   if (stricmp (argv[0], "--version") == 0) {
    250     Version ();
    251     return STATUS_SUCCESS;
    252   }
    253 
    254   while (argc > 0) {
    255     if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {
    256       InfFileName = argv[1];
    257       if (InfFileName == NULL) {
    258         Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");
    259         return STATUS_ERROR;
    260       }
    261       argc -= 2;
    262       argv += 2;
    263       continue;
    264     }
    265 
    266     if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {
    267       AddrFileName = argv[1];
    268       if (AddrFileName == NULL) {
    269         Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");
    270         return STATUS_ERROR;
    271       }
    272       argc -= 2;
    273       argv += 2;
    274       continue;
    275     }
    276 
    277     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
    278       OutFileName = argv[1];
    279       if (OutFileName == NULL) {
    280         Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
    281         return STATUS_ERROR;
    282       }
    283       argc -= 2;
    284       argv += 2;
    285       continue;
    286     }
    287 
    288     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {
    289       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
    290       if (EFI_ERROR (Status)) {
    291         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    292         return STATUS_ERROR;
    293       }
    294       mFvDataInfo.BaseAddress    = TempNumber;
    295       mFvDataInfo.BaseAddressSet = TRUE;
    296       argc -= 2;
    297       argv += 2;
    298       continue;
    299     }
    300 
    301     if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {
    302       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
    303       if (EFI_ERROR (Status)) {
    304         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    305         return STATUS_ERROR;
    306       }
    307       if (TempNumber == 0) {
    308         Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");
    309         return STATUS_ERROR;
    310       }
    311       mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;
    312       DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%llx", EFI_BLOCK_SIZE_STRING, (unsigned long long) TempNumber);
    313       argc -= 2;
    314       argv += 2;
    315       continue;
    316     }
    317 
    318     if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {
    319       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
    320       if (EFI_ERROR (Status)) {
    321         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    322         return STATUS_ERROR;
    323       }
    324       if (TempNumber == 0) {
    325         Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");
    326         return STATUS_ERROR;
    327       }
    328       mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;
    329       DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%llx", EFI_NUM_BLOCKS_STRING, (unsigned long long) TempNumber);
    330       argc -= 2;
    331       argv += 2;
    332       continue;
    333     }
    334 
    335     if ((strcmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {
    336       if (argv[1] == NULL) {
    337         Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");
    338         return STATUS_ERROR;
    339       }
    340       strcpy (mFvDataInfo.FvFiles[Index], argv[1]);
    341       DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index + 1, argv[1]);
    342       argc -= 2;
    343       argv += 2;
    344 
    345       if (argc > 0) {
    346 		    if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
    347 		      if (argv[1] == NULL) {
    348 		        Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");
    349 		        return STATUS_ERROR;
    350 		      }
    351 		      Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
    352 		      if (EFI_ERROR (Status)) {
    353 		        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    354 		        return STATUS_ERROR;
    355 		      }
    356 		      mFvDataInfo.SizeofFvFiles[Index] = (UINT32) TempNumber;
    357 	      	DebugMsg (NULL, 0, 9, "FV component file size", "the %uth size is %s", (unsigned) Index + 1, argv[1]);
    358 	      	argc -= 2;
    359 	      	argv += 2;
    360         }
    361       }
    362       Index ++;
    363       continue;
    364     }
    365 
    366     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
    367       Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");
    368       return STATUS_ERROR;
    369     }
    370 
    371     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {
    372       CapsuleFlag = TRUE;
    373       argc --;
    374       argv ++;
    375       continue;
    376     }
    377 
    378     if ((strcmp (argv[0], "-F") == 0) || (stricmp (argv[0], "--force-rebase") == 0)) {
    379       if (argv[1] == NULL) {
    380         Error (NULL, 0, 1003, "Invalid option value", "Froce rebase flag can't be null");
    381         return STATUS_ERROR;
    382       }
    383 
    384       if (stricmp (argv[1], "TRUE") == 0) {
    385         mFvDataInfo.ForceRebase = 1;
    386       } else if (stricmp (argv[1], "FALSE") == 0) {
    387         mFvDataInfo.ForceRebase = 0;
    388       } else {
    389         Error (NULL, 0, 1003, "Invalid option value", "froce rebase flag value must be \"TRUE\" or \"FALSE\"");
    390         return STATUS_ERROR;
    391       }
    392 
    393       argc -= 2;
    394       argv += 2;
    395       continue;
    396     }
    397 
    398     if (stricmp (argv[0], "--capheadsize") == 0) {
    399       //
    400       // Get Capsule Image Header Size
    401       //
    402       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
    403       if (EFI_ERROR (Status)) {
    404         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    405         return STATUS_ERROR;
    406       }
    407       mCapDataInfo.HeaderSize = (UINT32) TempNumber;
    408       DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%llx", EFI_CAPSULE_HEADER_SIZE_STRING, (unsigned long long) TempNumber);
    409       argc -= 2;
    410       argv += 2;
    411       continue;
    412     }
    413 
    414     if (stricmp (argv[0], "--capflag") == 0) {
    415       //
    416       // Get Capsule Header
    417       //
    418       if (argv[1] == NULL) {
    419         Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);
    420         return STATUS_ERROR;
    421       }
    422       if (strcmp (argv[1], "PopulateSystemTable") == 0) {
    423         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
    424       } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {
    425         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
    426       } else if (strcmp (argv[1], "InitiateReset") == 0) {
    427         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET;
    428       } else {
    429         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    430         return STATUS_ERROR;
    431       }
    432       DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);
    433       argc -= 2;
    434       argv += 2;
    435       continue;
    436     }
    437 
    438     if (stricmp (argv[0], "--capoemflag") == 0) {
    439       if (argv[1] == NULL) {
    440         Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag can't be null");
    441       }
    442       Status = AsciiStringToUint64(argv[1], FALSE, &TempNumber);
    443       if (EFI_ERROR (Status) || TempNumber > 0xffff) {
    444         Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag value must be integer value between 0x0000 and 0xffff");
    445         return STATUS_ERROR;
    446       }
    447       mCapDataInfo.Flags |= TempNumber;
    448       DebugMsg( NULL, 0, 9, "Capsule OEM Flags", argv[1]);
    449       argc -= 2;
    450       argv += 2;
    451       continue;
    452     }
    453 
    454     if (stricmp (argv[0], "--capguid") == 0) {
    455       //
    456       // Get the Capsule Guid
    457       //
    458       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
    459       if (EFI_ERROR (Status)) {
    460         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
    461         return STATUS_ERROR;
    462       }
    463       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
    464       argc -= 2;
    465       argv += 2;
    466       continue;
    467     }
    468 
    469     if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {
    470       //
    471       // Get the Capsule or Fv Guid
    472       //
    473       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
    474       if (EFI_ERROR (Status)) {
    475         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
    476         return STATUS_ERROR;
    477       }
    478       memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));
    479       mFvDataInfo.FvFileSystemGuidSet = TRUE;
    480       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
    481       DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);
    482       argc -= 2;
    483       argv += 2;
    484       continue;
    485     }
    486 
    487     if (stricmp (argv[0], "--FvNameGuid") == 0) {
    488       //
    489       // Get Fv Name Guid
    490       //
    491       Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);
    492       if (EFI_ERROR (Status)) {
    493         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
    494         return STATUS_ERROR;
    495       }
    496       mFvDataInfo.FvNameGuidSet = TRUE;
    497       DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);
    498       argc -= 2;
    499       argv += 2;
    500       continue;
    501     }
    502 
    503     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {
    504       DumpCapsule = TRUE;
    505       argc --;
    506       argv ++;
    507       continue;
    508     }
    509 
    510     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {
    511       MapFileName = argv[1];
    512       if (MapFileName == NULL) {
    513         Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");
    514         return STATUS_ERROR;
    515       }
    516       argc -= 2;
    517       argv += 2;
    518       continue;
    519     }
    520 
    521     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
    522       SetPrintLevel (VERBOSE_LOG_LEVEL);
    523       VerboseMsg ("Verbose output Mode Set!");
    524       argc --;
    525       argv ++;
    526       continue;
    527     }
    528 
    529     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
    530       SetPrintLevel (KEY_LOG_LEVEL);
    531       KeyMsg ("Quiet output Mode Set!");
    532       argc --;
    533       argv ++;
    534       continue;
    535     }
    536 
    537     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
    538       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
    539       if (EFI_ERROR (Status)) {
    540         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
    541         return STATUS_ERROR;
    542       }
    543       if (LogLevel > 9) {
    544         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
    545         return STATUS_ERROR;
    546       }
    547       SetPrintLevel (LogLevel);
    548       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
    549       argc -= 2;
    550       argv += 2;
    551       continue;
    552     }
    553 
    554     //
    555     // Don't recognize the parameter.
    556     //
    557     Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);
    558     return STATUS_ERROR;
    559   }
    560 
    561   VerboseMsg ("%s tool start.", UTILITY_NAME);
    562 
    563   //
    564   // check input parameter, InfFileName can be NULL
    565   //
    566   if (InfFileName == NULL && DumpCapsule) {
    567     Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");
    568     return STATUS_ERROR;
    569   }
    570   VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);
    571 
    572   if (!DumpCapsule && OutFileName == NULL) {
    573     Error (NULL, 0, 1001, "Missing option", "Output File");
    574     return STATUS_ERROR;
    575   }
    576   if (OutFileName != NULL) {
    577     VerboseMsg ("the output file name is %s", OutFileName);
    578   }
    579 
    580   //
    581   // Read the INF file image
    582   //
    583   if (InfFileName != NULL) {
    584     Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);
    585     if (EFI_ERROR (Status)) {
    586       return STATUS_ERROR;
    587     }
    588   }
    589 
    590   if (DumpCapsule) {
    591     VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);
    592     //
    593     // Dump Capsule Image Header Information
    594     //
    595     CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;
    596     if (OutFileName == NULL) {
    597       FpFile = stdout;
    598     } else {
    599       FpFile = fopen (LongFilePath (OutFileName), "w");
    600       if (FpFile == NULL) {
    601         Error (NULL, 0, 0001, "Error opening file", OutFileName);
    602         return STATUS_ERROR;
    603       }
    604     }
    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   } else if (CapsuleFlag) {
    623     VerboseMsg ("Create capsule image");
    624     //
    625     // Call the GenerateCapImage to generate Capsule Image
    626     //
    627     for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {
    628       strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);
    629     }
    630 
    631     Status = GenerateCapImage (
    632               InfFileImage,
    633               InfFileSize,
    634               OutFileName
    635               );
    636   } else {
    637     VerboseMsg ("Create Fv image and its map file");
    638     //
    639     // Will take rebase action at below situation:
    640     // 1. ForceRebase Flag specified to TRUE;
    641     // 2. ForceRebase Flag not specified, BaseAddress greater than zero.
    642     //
    643     if (((mFvDataInfo.BaseAddress > 0) && (mFvDataInfo.ForceRebase == -1)) || (mFvDataInfo.ForceRebase == 1)) {
    644       VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);
    645     }
    646     //
    647     // Call the GenerateFvImage to generate Fv Image
    648     //
    649     Status = GenerateFvImage (
    650               InfFileImage,
    651               InfFileSize,
    652               OutFileName,
    653               MapFileName
    654               );
    655   }
    656 
    657   //
    658   // free InfFileImage memory
    659   //
    660   if (InfFileImage != NULL) {
    661     free (InfFileImage);
    662   }
    663 
    664   //
    665   //  update boot driver address and runtime driver address in address file
    666   //
    667   if (Status == EFI_SUCCESS && AddrFileName != NULL && mFvBaseAddressNumber > 0) {
    668     FpFile = fopen (LongFilePath (AddrFileName), "w");
    669     if (FpFile == NULL) {
    670       Error (NULL, 0, 0001, "Error opening file", AddrFileName);
    671       return STATUS_ERROR;
    672     }
    673     fprintf (FpFile, FV_BASE_ADDRESS_STRING);
    674     fprintf (FpFile, "\n");
    675     for (Index = 0; Index < mFvBaseAddressNumber; Index ++) {
    676       fprintf (
    677         FpFile,
    678         "0x%llx\n",
    679         (unsigned long long)mFvBaseAddress[Index]
    680         );
    681     }
    682     fflush (FpFile);
    683     fclose (FpFile);
    684   }
    685 
    686   if (Status == EFI_SUCCESS) {
    687     DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
    688     DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);
    689     DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));
    690   }
    691 
    692   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
    693 
    694   return GetUtilityStatus ();
    695 }
    696