12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760 |
- /*++
- Copyright (c) 2014 Minoca Corp. All Rights Reserved
- Module Name:
- genffs.c
- Abstract:
- This module implements a build tool that generates one EFI FFS file.
- Author:
- Evan Green 6-Mar-2014
- Environment:
- Build
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <unistd.h>
- #include "uefifw.h"
- #include "efiffs.h"
- #include "peimage.h"
- //
- // --------------------------------------------------------------------- Macros
- //
- #define GFFS_LOG_ERROR(...) \
- fprintf(stderr, __VA_ARGS__); GffsErrorOccurred = TRUE;
- #define GFFS_LOG_VERBOSE(...) \
- if (GffsDebugLevel >= LOG_LEVEL_VERBOSE) { \
- fprintf(stderr, __VA_ARGS__); \
- }
- #define GFFS_LOG_DEBUG(...) \
- if (GffsDebugLevel >= LOG_LEVEL_DEBUG) { \
- fprintf(stderr, __VA_ARGS__); \
- }
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define STATUS_SUCCESS 0
- #define STATUS_WARNING 1
- #define STATUS_ERROR 2
- #define UTILITY_NAME "GenFfs"
- #define UTILITY_MAJOR_VERSION 0
- #define UTILITY_MINOR_VERSION 1
- #define MAXIMUM_INPUT_FILE_COUNT 10
- #define LOG_LEVEL_QUIET 0
- #define LOG_LEVEL_DEFAULT 1
- #define LOG_LEVEL_VERBOSE 2
- #define LOG_LEVEL_DEBUG 3
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- EFI_STATUS
- GffsGetSectionContents (
- CHAR8 **InputFileName,
- UINT32 *InputFileAlignment,
- UINT8 *InputFileSectionType,
- UINT32 InputFileCount,
- UINT8 *FileBuffer,
- UINT32 *BufferLength,
- UINT32 *MaxAlignment
- );
- UINT8
- GffsStringToType (
- CHAR8 *String
- );
- UINT8
- GffsStringToSectionType (
- CHAR8 *String
- );
- EFI_STATUS
- GffsStringtoAlignment (
- CHAR8 *AlignBuffer,
- UINT32 *AlignNumber
- );
- EFI_STATUS
- GffsStringToGuid (
- CHAR8 *AsciiGuidBuffer,
- EFI_GUID *GuidBuffer
- );
- VOID
- GffsConvertAsciiStringToUnicode (
- CHAR8 *String,
- CHAR16 *UnicodeString
- );
- VOID
- GffsCreateRandomGuid (
- EFI_GUID *Guid
- );
- UINT8
- GffsCalculateChecksum8 (
- UINT8 *Buffer,
- UINTN Size
- );
- UINT8
- GffsCalculateSum8 (
- UINT8 *Buffer,
- UINTN Size
- );
- BOOLEAN
- GffsCompareGuids (
- EFI_GUID *FirstGuid,
- EFI_GUID *SecondGuid
- );
- VOID
- GffsPrintVersion (
- VOID
- );
- VOID
- GffsPrintUsage (
- VOID
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- CHAR8 *GffsFileTypes[] = {
- NULL,
- "EFI_FV_FILETYPE_RAW",
- "EFI_FV_FILETYPE_FREEFORM",
- "EFI_FV_FILETYPE_SECURITY_CORE",
- "EFI_FV_FILETYPE_PEI_CORE",
- "EFI_FV_FILETYPE_DXE_CORE",
- "EFI_FV_FILETYPE_PEIM",
- "EFI_FV_FILETYPE_DRIVER",
- "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER",
- "EFI_FV_FILETYPE_APPLICATION",
- "EFI_FV_FILETYPE_SMM",
- "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE",
- "EFI_FV_FILETYPE_COMBINED_SMM_DXE",
- "EFI_FV_FILETYPE_SMM_CORE"
- };
- CHAR8 *GffsFileSectionTypes[] = {
- NULL,
- "EFI_SECTION_COMPRESSION",
- "EFI_SECTION_GUID_DEFINED",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "EFI_SECTION_PE32",
- "EFI_SECTION_PIC",
- "EFI_SECTION_TE",
- "EFI_SECTION_DXE_DEPEX",
- "EFI_SECTION_VERSION",
- "EFI_SECTION_USER_INTERFACE",
- "EFI_SECTION_COMPATIBILITY16",
- "EFI_SECTION_FIRMWARE_VOLUME_IMAGE",
- "EFI_SECTION_FREEFORM_SUBTYPE_GUID",
- "EFI_SECTION_RAW",
- NULL,
- "EFI_SECTION_PEI_DEPEX",
- "EFI_SECTION_SMM_DEPEX"
- };
- CHAR8 *GffsAlignmentStrings[] = {
- "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
- "1K", "2K", "4K", "8K", "16K", "32K", "64K"
- };
- CHAR8 *GffsValidAlignmentStrings[] = {
- "8", "16", "128", "512", "1K", "4K", "32K", "64K"
- };
- UINT32 GffsValidAlignments[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536};
- EFI_GUID GffsZeroGuid = {0};
- UINTN GffsDebugLevel = LOG_LEVEL_DEFAULT;
- BOOLEAN GffsErrorOccurred = FALSE;
- //
- // ------------------------------------------------------------------ Functions
- //
- int
- main (
- int ArgumentCount,
- CHAR8 *Arguments[]
- )
- /*++
- Routine Description:
- This routine is the main entry point into the GenFFS utility, which creates
- a single FFS file from an input file.
- Arguments:
- ArgumentCount - Supplies the number of command line parameters.
- Arguments - Supplies the array of pointers to parameter strings.
- Return Value:
- STATUS_SUCCESS - Utility exits successfully.
- STATUS_ERROR- Some error occurred during execution.
- --*/
- {
- CHAR8 *AfterScan;
- UINT32 Alignment;
- EFI_FFS_FILE_ATTRIBUTES Attributes;
- UINT32 DefaultFileAlignment;
- UINT8 DefaultFileSectionType;
- FILE *FfsFile;
- EFI_FFS_FILE_HEADER2 FfsFileHeader;
- UINT8 *FileBuffer;
- EFI_GUID FileGuid;
- UINT32 FileSize;
- EFI_FV_FILETYPE FileType;
- UINT32 HeaderSize;
- UINT32 Index;
- UINT32 *InputFileAlignment;
- UINT32 InputFileCount;
- CHAR8 **InputFileName;
- UINT8 *InputFileSectionType;
- UINT64 LogLevel;
- UINT32 MaxAlignment;
- UINTN NewSize;
- CHAR8 *OutputFileName;
- EFI_STATUS Status;
- LogLevel = 0;
- Index = 0;
- Attributes = 0;
- Alignment = 0;
- DefaultFileSectionType = 0;
- DefaultFileAlignment = 0;
- FileType = EFI_FV_FILETYPE_ALL;
- OutputFileName = NULL;
- InputFileCount = 0;
- InputFileName = NULL;
- InputFileAlignment = NULL;
- InputFileSectionType = NULL;
- FileBuffer = NULL;
- FileSize = 0;
- MaxAlignment = 1;
- FfsFile = NULL;
- Status = EFI_SUCCESS;
- srand(time(NULL) ^ getpid());
- memset(&FileGuid, 0, sizeof(EFI_GUID));
- if (ArgumentCount == 1) {
- GFFS_LOG_ERROR("Missing options.\n");
- GffsPrintUsage();
- return STATUS_ERROR;
- }
- //
- // Parse the arguments.
- //
- ArgumentCount -= 1;
- Arguments += 1;
- if ((strcasecmp(Arguments[0], "-h") == 0) ||
- (strcasecmp(Arguments[0], "--help") == 0)) {
- GffsPrintVersion();
- GffsPrintUsage();
- return STATUS_SUCCESS;
- }
- if (strcasecmp(Arguments[0], "--version") == 0) {
- GffsPrintVersion();
- return STATUS_SUCCESS;
- }
- while (ArgumentCount > 0) {
- if ((strcasecmp(Arguments[0], "-t") == 0) ||
- (strcasecmp(Arguments[0], "--filetype") == 0)) {
- if ((Arguments[1] == NULL) || Arguments[1][0] == '-') {
- GFFS_LOG_ERROR("file type is missing for -t option");
- goto mainEnd;
- }
- FileType = GffsStringToType(Arguments[1]);
- if (FileType == EFI_FV_FILETYPE_ALL) {
- GFFS_LOG_ERROR("%s is not a valid file type.\n", Arguments[1]);
- goto mainEnd;
- }
- ArgumentCount -= 2;
- Arguments += 2;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-o") == 0) ||
- (strcasecmp(Arguments[0], "--outputfile") == 0)) {
- if ((Arguments[1] == NULL) || (Arguments[1][0] == '-')) {
- GFFS_LOG_ERROR("Output file is missing for -o options.\n");
- goto mainEnd;
- }
- OutputFileName = Arguments[1];
- ArgumentCount -= 2;
- Arguments += 2;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-g") == 0) ||
- (strcasecmp(Arguments[0], "--fileguid") == 0)) {
- Status = GffsStringToGuid(Arguments[1], &FileGuid);
- if (EFI_ERROR(Status)) {
- GFFS_LOG_ERROR("Invalid option value %s = %s.\n",
- Arguments[0],
- Arguments[1]);
- goto mainEnd;
- }
- ArgumentCount -= 2;
- Arguments += 2;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-x") == 0) ||
- (strcasecmp(Arguments[0], "--fixed") == 0)) {
- Attributes |= FFS_ATTRIB_FIXED;
- ArgumentCount -= 1;
- Arguments += 1;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-s") == 0) ||
- (strcasecmp(Arguments[0], "--checksum") == 0)) {
- Attributes |= FFS_ATTRIB_CHECKSUM;
- ArgumentCount -= 1;
- Arguments += 1;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-a") == 0) ||
- (strcasecmp(Arguments[0], "--align") == 0)) {
- if ((Arguments[1] == NULL) || (Arguments[1][0] == '-')) {
- GFFS_LOG_ERROR("Align value is missing for -a option.\n");
- goto mainEnd;
- }
- for (Index = 0;
- Index < sizeof(GffsValidAlignmentStrings) / sizeof(CHAR8 *);
- Index += 1) {
- if (strcasecmp(Arguments[1],
- GffsValidAlignmentStrings[Index]) == 0) {
- break;
- }
- }
- if (Index == sizeof(GffsValidAlignmentStrings) / sizeof(CHAR8 *)) {
- if ((strcasecmp(Arguments[1], "1") == 0) ||
- (strcasecmp(Arguments[1], "2") == 0) ||
- (strcasecmp(Arguments[1], "4") == 0)) {
- //
- // 1, 2, 4 byte alignment same to 8 byte alignment
- //
- Index = 0;
- } else {
- GFFS_LOG_ERROR(
- "Invalid option %s = %s.\n",
- Arguments[0],
- Arguments[1]);
- goto mainEnd;
- }
- }
- Alignment = Index;
- ArgumentCount -= 2;
- Arguments += 2;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-n") == 0) ||
- (strcasecmp(Arguments[0], "--sectionalign") == 0)) {
- Arguments += 1;
- ArgumentCount -= 1;
- if (ArgumentCount == 0) {
- GFFS_LOG_ERROR("Error: -n requires an argument.\n");
- goto mainEnd;
- }
- Status = GffsStringtoAlignment(Arguments[0],
- &DefaultFileAlignment);
- if (EFI_ERROR(Status)) {
- GFFS_LOG_ERROR("Invalid default alignment.\n");
- goto mainEnd;
- }
- Arguments += 1;
- ArgumentCount -= 1;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-r") == 0) ||
- (strcasecmp(Arguments[0], "--sectiontype") == 0)) {
- Arguments += 1;
- ArgumentCount -= 1;
- if (ArgumentCount == 0) {
- GFFS_LOG_ERROR("Error: -n requires an argument.\n");
- goto mainEnd;
- }
- DefaultFileSectionType = GffsStringToSectionType(Arguments[0]);
- if (DefaultFileSectionType == 0) {
- GFFS_LOG_ERROR("Invalid section type %s.\n",
- Arguments[0]);
- goto mainEnd;
- }
- Arguments += 1;
- ArgumentCount -= 1;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-v") == 0) ||
- (strcasecmp(Arguments[0], "--verbose") == 0)) {
- GffsDebugLevel = LOG_LEVEL_VERBOSE;
- GFFS_LOG_VERBOSE("Verbose output Mode Set!\n");
- ArgumentCount -= 1;
- Arguments += 1;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-q") == 0) ||
- (strcasecmp(Arguments[0], "--quiet") == 0)) {
- GffsDebugLevel = LOG_LEVEL_QUIET;
- ArgumentCount -= 1;
- Arguments += 1;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-d") == 0) ||
- (strcasecmp(Arguments[0], "--debug") == 0)) {
- LogLevel = strtoul(Arguments[1], &AfterScan, 0);
- if (AfterScan == Arguments[1]) {
- GFFS_LOG_ERROR(
- "Invalid option value %s = %s.\n",
- Arguments[0],
- Arguments[1]);
- goto mainEnd;
- }
- if (LogLevel > 9) {
- GFFS_LOG_ERROR(
- "Debug Level range is 0-9, current input level is %d",
- (int)LogLevel);
- goto mainEnd;
- }
- GffsDebugLevel = LOG_LEVEL_DEBUG;
- GFFS_LOG_DEBUG("Debug Output Mode Level %s is set!\n",
- Arguments[1]);
- ArgumentCount -= 2;
- Arguments += 2;
- continue;
- }
- if ((strcasecmp(Arguments[0], "-i") == 0) ||
- (strcasecmp(Arguments[0], "--sectionfile") == 0) ||
- (Arguments[0][0] != '-')) {
- if (Arguments[0][0] == '-') {
- Arguments += 1;
- ArgumentCount -= 1;
- }
- //
- // Get the input file name and its alignment.
- //
- if ((ArgumentCount == 0) || (Arguments[0][0] == '-')) {
- GFFS_LOG_ERROR("Input section file is missing for -i "
- "option.\n");
- goto mainEnd;
- }
- //
- // Allocate Input file name buffer and its alignment buffer.
- //
- if (InputFileCount % MAXIMUM_INPUT_FILE_COUNT == 0) {
- NewSize = (InputFileCount + MAXIMUM_INPUT_FILE_COUNT) *
- sizeof(CHAR8 *);
- InputFileName = (CHAR8 **)realloc(InputFileName, NewSize);
- if (InputFileName == NULL) {
- GffsErrorOccurred = TRUE;
- goto mainEnd;
- }
- memset(&(InputFileName[InputFileCount]),
- 0,
- (MAXIMUM_INPUT_FILE_COUNT * sizeof(CHAR8 *)));
- NewSize = (InputFileCount + MAXIMUM_INPUT_FILE_COUNT) *
- sizeof(UINT32);
- InputFileAlignment = (UINT32 *)realloc(InputFileAlignment,
- NewSize);
- if (InputFileAlignment == NULL) {
- GffsErrorOccurred = TRUE;
- goto mainEnd;
- }
- memset(&(InputFileAlignment[InputFileCount]),
- 0,
- (MAXIMUM_INPUT_FILE_COUNT * sizeof(UINT32)));
- NewSize = (InputFileCount + MAXIMUM_INPUT_FILE_COUNT) *
- sizeof(UINT8);
- InputFileSectionType = (UINT8 *)realloc(InputFileSectionType,
- NewSize);
- if (InputFileSectionType == NULL) {
- GffsErrorOccurred = TRUE;
- goto mainEnd;
- }
- memset(&(InputFileSectionType[InputFileCount]),
- 0,
- (MAXIMUM_INPUT_FILE_COUNT * sizeof(UINT8)));
- }
- InputFileName[InputFileCount] = Arguments[0];
- ArgumentCount -= 1;
- Arguments += 1;
- //
- // Assign the default alignment and type.
- //
- InputFileAlignment[InputFileCount] = DefaultFileAlignment;
- InputFileSectionType[InputFileCount] = DefaultFileSectionType;
- if (ArgumentCount <= 0) {
- InputFileCount += 1;
- break;
- }
- //
- // Process a section file alignment requirement.
- //
- if ((strcasecmp(Arguments[0], "-n") == 0) ||
- (strcasecmp(Arguments[0], "--sectionalign") == 0)) {
- Status = GffsStringtoAlignment(
- Arguments[1],
- &(InputFileAlignment[InputFileCount]));
- if (EFI_ERROR(Status)) {
- GFFS_LOG_ERROR("Invalid option value %s = %s.\n",
- Arguments[0],
- Arguments[1]);
- goto mainEnd;
- }
- ArgumentCount -= 2;
- Arguments += 2;
- }
- //
- // Process a section type.
- //
- if ((strcasecmp(Arguments[0], "-r") == 0) ||
- (strcasecmp(Arguments[0], "--sectiontype") == 0)) {
- InputFileSectionType[InputFileCount] =
- GffsStringToSectionType(Arguments[1]);
- if (InputFileSectionType[InputFileCount] == 0) {
- GFFS_LOG_ERROR("Invalid section type %s.\n",
- Arguments[1]);
- goto mainEnd;
- }
- ArgumentCount -= 2;
- Arguments += 2;
- }
- InputFileCount += 1;
- continue;
- }
- GFFS_LOG_ERROR("Unknown option %s.\n", Arguments[0]);
- goto mainEnd;
- }
- GFFS_LOG_VERBOSE("%s tool start.", UTILITY_NAME);
- //
- // Check the complete input paramters.
- //
- if (FileType == EFI_FV_FILETYPE_ALL) {
- GFFS_LOG_ERROR("Missing option filetype.\n");
- goto mainEnd;
- }
- if (GffsCompareGuids(&FileGuid, &GffsZeroGuid) != FALSE) {
- GFFS_LOG_VERBOSE("Creating random GUID for the file.\n");
- GffsCreateRandomGuid(&FileGuid);
- }
- if (InputFileCount == 0) {
- GFFS_LOG_ERROR("Missing option input files.\n");
- goto mainEnd;
- }
- //
- // Output input parameter information
- //
- GFFS_LOG_VERBOSE("Fv File type is %s\n", GffsFileTypes[FileType]);
- GFFS_LOG_VERBOSE("Output file name is %s\n", OutputFileName);
- GFFS_LOG_VERBOSE("FFS File Guid is "
- "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
- (unsigned)FileGuid.Data1,
- FileGuid.Data2,
- FileGuid.Data3,
- FileGuid.Data4[0],
- FileGuid.Data4[1],
- FileGuid.Data4[2],
- FileGuid.Data4[3],
- FileGuid.Data4[4],
- FileGuid.Data4[5],
- FileGuid.Data4[6],
- FileGuid.Data4[7]);
- if ((Attributes & FFS_ATTRIB_FIXED) != 0) {
- GFFS_LOG_VERBOSE("FFS File has the fixed file attribute\n");
- }
- if ((Attributes & FFS_ATTRIB_CHECKSUM) != 0) {
- GFFS_LOG_VERBOSE("FFS File requires the checksum of the whole file\n");
- }
- GFFS_LOG_VERBOSE("FFS file alignment is %s\n",
- GffsValidAlignmentStrings[Alignment]);
- for (Index = 0; Index < InputFileCount; Index += 1) {
- if (InputFileAlignment[Index] == 0) {
- InputFileAlignment[Index] = 1;
- }
- GFFS_LOG_VERBOSE("the %dth input section name is %s and section "
- "alignment s %u\n",
- Index,
- InputFileName[Index],
- (unsigned)InputFileAlignment[Index]);
- }
- //
- // Calculate the size of all input section files.
- //
- Status = GffsGetSectionContents(InputFileName,
- InputFileAlignment,
- InputFileSectionType,
- InputFileCount,
- FileBuffer,
- &FileSize,
- &MaxAlignment);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FileBuffer = (UINT8 *)malloc(FileSize);
- if (FileBuffer == NULL) {
- goto mainEnd;
- }
- memset(FileBuffer, 0, FileSize);
- //
- // Read all input file contents into a buffer.
- //
- Status = GffsGetSectionContents(InputFileName,
- InputFileAlignment,
- InputFileSectionType,
- InputFileCount,
- FileBuffer,
- &FileSize,
- &MaxAlignment);
- }
- if (EFI_ERROR(Status)) {
- goto mainEnd;
- }
- //
- // Create the Ffs file header.
- //
- memset(&FfsFileHeader, 0, sizeof(EFI_FFS_FILE_HEADER2));
- memcpy(&(FfsFileHeader.Name), &FileGuid, sizeof(EFI_GUID));
- FfsFileHeader.Type = FileType;
- //
- // Update the FFS Alignment based on the max alignment required by input
- // section files.
- //
- GFFS_LOG_VERBOSE("the max alignment of all input sections is %u\n",
- (unsigned)MaxAlignment);
- for (Index = 0;
- Index < sizeof(GffsValidAlignments) / sizeof(UINT32) - 1;
- Index += 1) {
- if ((MaxAlignment > GffsValidAlignments[Index]) &&
- (MaxAlignment <= GffsValidAlignments[Index + 1])) {
- break;
- }
- }
- if (Alignment < Index) {
- Alignment = Index;
- }
- GFFS_LOG_VERBOSE("the alignment of the generated FFS file is %u\n",
- (unsigned)GffsValidAlignments[Alignment + 1]);
- //
- // Now the file size includes the EFI_FFS_FILE_HEADER.
- //
- if (FileSize + sizeof(EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
- HeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
- FileSize += sizeof(EFI_FFS_FILE_HEADER2);
- FfsFileHeader.ExtendedSize = FileSize;
- Attributes |= FFS_ATTRIB_LARGE_FILE;
- } else {
- HeaderSize = sizeof(EFI_FFS_FILE_HEADER);
- FileSize += sizeof(EFI_FFS_FILE_HEADER);
- FfsFileHeader.Size[0] = (UINT8)(FileSize & 0xFF);
- FfsFileHeader.Size[1] = (UINT8)((FileSize & 0xFF00) >> 8);
- FfsFileHeader.Size[2] = (UINT8)((FileSize & 0xFF0000) >> 16);
- }
- GFFS_LOG_VERBOSE("the size of the generated FFS file is %u bytes\n",
- (unsigned)FileSize);
- FfsFileHeader.Attributes =
- (EFI_FFS_FILE_ATTRIBUTES)(Attributes | (Alignment << 3));
- //
- // Fill in checksums and state, these must be zero for checksumming
- //
- // FileHeader.IntegrityCheck.Checksum.Header = 0;
- // FileHeader.IntegrityCheck.Checksum.File = 0;
- // FileHeader.State = 0;
- //
- assert((FfsFileHeader.IntegrityCheck.Checksum.Header == 0) &&
- (FfsFileHeader.IntegrityCheck.Checksum.File == 0) &&
- (FfsFileHeader.State == 0));
- FfsFileHeader.IntegrityCheck.Checksum.Header = GffsCalculateChecksum8(
- (UINT8 *)&FfsFileHeader,
- HeaderSize);
- if ((FfsFileHeader.Attributes & FFS_ATTRIB_CHECKSUM) != 0) {
- //
- // The Ffs header checksum is zero, so just calculate the CRC on the
- // FFS body.
- //
- FfsFileHeader.IntegrityCheck.Checksum.File = GffsCalculateChecksum8(
- FileBuffer,
- FileSize - HeaderSize);
- } else {
- FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
- }
- FfsFileHeader.State = EFI_FILE_HEADER_CONSTRUCTION |
- EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
- if (OutputFileName == NULL) {
- GFFS_LOG_ERROR("Error: output file was not specified.\n");
- goto mainEnd;
- }
- FfsFile = fopen(OutputFileName, "wb");
- if (FfsFile == NULL) {
- GFFS_LOG_ERROR("Error opening output file %s.\n", OutputFileName);
- goto mainEnd;
- }
- //
- // Write the header.
- //
- fwrite(&FfsFileHeader, 1, HeaderSize, FfsFile);
- //
- // Write the data.
- //
- fwrite(FileBuffer, 1, FileSize - HeaderSize, FfsFile);
- fclose(FfsFile);
- mainEnd:
- if (InputFileName != NULL) {
- free(InputFileName);
- }
- if (InputFileAlignment != NULL) {
- free(InputFileAlignment);
- }
- if (InputFileSectionType != NULL) {
- free(InputFileSectionType);
- }
- if (FileBuffer != NULL) {
- free(FileBuffer);
- }
- //
- // If any errors were reported via the standard error reporting
- // routines, then the status has been saved. Get the value and
- // return it to the caller.
- //
- GFFS_LOG_VERBOSE("%s tool done with return code is 0x%x.\n",
- UTILITY_NAME,
- GffsErrorOccurred);
- return GffsErrorOccurred;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- EFI_STATUS
- GffsGetSectionContents (
- CHAR8 **InputFileName,
- UINT32 *InputFileAlignment,
- UINT8 *InputFileSectionType,
- UINT32 InputFileCount,
- UINT8 *FileBuffer,
- UINT32 *BufferLength,
- UINT32 *MaxAlignment
- )
- /*++
- Routine Description:
- This routine gets the contents of all the given section files.
- Arguments:
- InputFileName - Supplies the name of the input file.
- InputFileAlignment - Supplies an array of alignments for each input file.
- InputFileSectionType - Supplies an array of section types for each input
- file.
- InputFileCount - Supplies the number of input files. This should be at
- least 1.
- FileBuffer - Supplies buffer where the data will be returned.
- BufferLength - Supplies a pointer that on input contains the size of the
- file buffer. On output, this is the actual length of the data.
- MaxAlignment - Supplies the max alignment required by all the input file
- datas.
- Return Value:
- EFI_SUCCESS on successful return.
- EFI_INVALID_PARAMETER if the input file count is less than 1 or buffer
- length pointer is NULL.
- EFI_ABORTED if unable to open input file.
- EFI_BUFFER_TOO_SMALL if the file buffer is not enough to contain all file
- data.
- --*/
- {
- UINT32 FileSize;
- UINT32 HeaderSize;
- UINT32 Index;
- FILE *InFile;
- size_t ItemsRead;
- EFI_COMMON_SECTION_HEADER2 *SectionHeader;
- UINT32 SectionSize;
- UINT32 Size;
- EFI_VERSION_SECTION *VersionSection;
- Size = 0;
- //
- // Go through the array of file names and copy their contents to the output
- // buffer.
- //
- for (Index = 0; Index < InputFileCount; Index += 1) {
- //
- // Make sure the section ends on a DWORD boundary.
- //
- while ((Size & 0x03) != 0) {
- Size += 1;
- }
- //
- // Get the Max alignment of all input file data.
- //
- if (*MaxAlignment < InputFileAlignment[Index]) {
- *MaxAlignment = InputFileAlignment[Index];
- }
- InFile = NULL;
- if (InputFileAlignment[Index] != 1) {
- GFFS_LOG_ERROR("Error: File alignment is not supported.\n");
- return EFI_UNSUPPORTED;
- }
- //
- // Compute the header size.
- //
- switch (InputFileSectionType[Index]) {
- case 0:
- GFFS_LOG_ERROR("Error: File %s missing section type.\n",
- InputFileName[Index]);
- return EFI_UNSUPPORTED;
- case EFI_SECTION_COMPRESSION:
- case EFI_SECTION_GUID_DEFINED:
- GFFS_LOG_ERROR("Error: Encapsulation sections not supported.\n");
- return EFI_UNSUPPORTED;
- case EFI_SECTION_PE32:
- case EFI_SECTION_PIC:
- case EFI_SECTION_TE:
- case EFI_SECTION_DXE_DEPEX:
- case EFI_SECTION_COMPATIBILITY16:
- case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
- case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
- case EFI_SECTION_RAW:
- case EFI_SECTION_PEI_DEPEX:
- //
- // Open the file and read its contents.
- //
- InFile = fopen(InputFileName[Index], "rb");
- if (InFile == NULL) {
- GFFS_LOG_ERROR("Error opening file %s.\n",
- InputFileName[Index]);
- return EFI_ABORTED;
- }
- fseek(InFile, 0, SEEK_END);
- FileSize = ftell(InFile);
- fseek(InFile, 0, SEEK_SET);
- GFFS_LOG_DEBUG("the input section name is %s and the size is %u "
- "bytes.\n",
- InputFileName[Index],
- (unsigned)FileSize);
- if (FileSize >= MAX_FFS_SIZE) {
- HeaderSize = sizeof(EFI_COMMON_SECTION_HEADER2);
- } else {
- HeaderSize = sizeof(EFI_COMMON_SECTION_HEADER);
- }
- //
- // Write the section header out to the buffer.
- //
- if ((FileBuffer != NULL) && (Size + HeaderSize <= *BufferLength)) {
- SectionHeader =
- (EFI_COMMON_SECTION_HEADER2 *)(FileBuffer + Size);
- SectionSize = FileSize + HeaderSize;
- if (FileSize >= MAX_FFS_SIZE) {
- SectionHeader->Elements.ExtendedSize = FileSize;
- } else {
- SectionHeader->AsUint32 = SectionSize & 0x00FFFFFF;
- }
- SectionHeader->Elements.Type = InputFileSectionType[Index];
- }
- Size += HeaderSize;
- //
- // Write the file contents out to the buffer.
- //
- if ((FileSize > 0) && (FileBuffer != NULL) &&
- ((Size + FileSize) <= *BufferLength)) {
- ItemsRead = fread(FileBuffer + Size,
- (size_t)FileSize,
- 1,
- InFile);
- if (ItemsRead != 1) {
- GFFS_LOG_ERROR("Error reading file %s.\n",
- InputFileName[Index]);
- fclose(InFile);
- return EFI_ABORTED;
- }
- }
- fclose(InFile);
- Size += FileSize;
- break;
- //
- // For version sections, the file name is actually the version
- // information.
- //
- case EFI_SECTION_VERSION:
- HeaderSize = sizeof(EFI_VERSION_SECTION);
- FileSize = (strlen(InputFileName[Index]) + 1) * sizeof(CHAR16);
- SectionSize = HeaderSize + FileSize;
- if ((FileBuffer != NULL) && (Size + HeaderSize <= *BufferLength)) {
- VersionSection = (EFI_VERSION_SECTION *)(FileBuffer + Size);
- VersionSection->CommonHeader.AsUint32 =
- SectionSize & 0x00FFFFFF;
- VersionSection->CommonHeader.Elements.Type =
- EFI_SECTION_VERSION;
- VersionSection->BuildNumber = strtoul(InputFileName[Index],
- NULL,
- 0);
- }
- Size += HeaderSize;
- if ((FileSize > 0) && (FileBuffer != NULL) &&
- ((Size + FileSize) <= *BufferLength)) {
- GffsConvertAsciiStringToUnicode(InputFileName[Index],
- (CHAR16 *)(FileBuffer + Size));
- }
- Size += FileSize;
- break;
- //
- // For user interface sections, the file name is the value of the
- // section.
- //
- case EFI_SECTION_USER_INTERFACE:
- HeaderSize = sizeof(EFI_COMMON_SECTION_HEADER);
- FileSize = (strlen(InputFileName[Index]) + 1) * sizeof(CHAR16);
- SectionSize = HeaderSize + FileSize;
- if ((FileBuffer != NULL) && (Size + HeaderSize <= *BufferLength)) {
- SectionHeader =
- (EFI_COMMON_SECTION_HEADER2 *)(FileBuffer + Size);
- SectionHeader->AsUint32 = SectionSize & 0x00FFFFFF;
- SectionHeader->Elements.Type = InputFileSectionType[Index];
- }
- Size += HeaderSize;
- if ((FileSize > 0) && (FileBuffer != NULL) &&
- ((Size + FileSize) <= *BufferLength)) {
- GffsConvertAsciiStringToUnicode(InputFileName[Index],
- (CHAR16 *)(FileBuffer + Size));
- }
- Size += FileSize;
- break;
- default:
- GFFS_LOG_ERROR("Error: Unsupported section type %d.\n",
- InputFileSectionType[Index]);
- return EFI_UNSUPPORTED;
- }
- }
- //
- // Set the actual length of the data.
- //
- if (Size > *BufferLength) {
- *BufferLength = Size;
- return EFI_BUFFER_TOO_SMALL;
- }
- *BufferLength = Size;
- return EFI_SUCCESS;
- }
- UINT8
- GffsStringToType (
- CHAR8 *String
- )
- /*++
- Routine Description:
- This routine converts a file type string to a file type value. The value
- EFI_FV_FILETYPE_ALL indicates that an unrecognized file type was specified.
- Arguments:
- String - Supplies the file type string.
- Return Value:
- Returns the file type value.
- --*/
- {
- UINTN Index;
- if (String == NULL) {
- return EFI_FV_FILETYPE_ALL;
- }
- for (Index = 0;
- Index < sizeof(GffsFileTypes) / sizeof(CHAR8 *);
- Index += 1) {
- if ((GffsFileTypes[Index] != NULL) &&
- (strcasecmp(String, GffsFileTypes[Index]) == 0)) {
- return Index;
- }
- }
- return EFI_FV_FILETYPE_ALL;
- }
- UINT8
- GffsStringToSectionType (
- CHAR8 *String
- )
- /*++
- Routine Description:
- This routine converts a file section type string to a file section value.
- Arguments:
- String - Supplies the file section string.
- Return Value:
- Returns the file section value.
- --*/
- {
- UINTN Index;
- if (String == NULL) {
- return EFI_FV_FILETYPE_ALL;
- }
- for (Index = 0;
- Index < sizeof(GffsFileSectionTypes) / sizeof(CHAR8 *);
- Index += 1) {
- if ((GffsFileSectionTypes[Index] != NULL) &&
- (strcasecmp(String, GffsFileSectionTypes[Index]) == 0)) {
- return Index;
- }
- }
- return 0;
- }
- EFI_STATUS
- GffsStringtoAlignment (
- CHAR8 *AlignBuffer,
- UINT32 *AlignNumber
- )
- /*++
- Routine Description:
- This routine converts an alignment string to an alignment value in the
- range of 1 to 64K.
- Arguments:
- AlignBuffer - Supplies a pointer to the alignment string.
- AlignNumber - Supplies a pointer where the alignment value will be returned
- on success.
- Return Value:
- EFI_SUCCESS if a value was converted successfully.
- EFI_INVALID_PARAMETER if the alignment string is invalid or align value is
- not in scope.
- --*/
- {
- UINT32 Index;
- if (AlignBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- for (Index = 0;
- Index < sizeof(GffsAlignmentStrings) / sizeof(CHAR8 *);
- Index += 1) {
- if (strcasecmp(AlignBuffer, GffsAlignmentStrings[Index]) == 0) {
- *AlignNumber = 1 << Index;
- return EFI_SUCCESS;
- }
- }
- return EFI_INVALID_PARAMETER;
- }
- EFI_STATUS
- GffsStringToGuid (
- CHAR8 *AsciiGuidBuffer,
- EFI_GUID *GuidBuffer
- )
- /*++
- Routine Description:
- This routine converts a string to an EFI_GUID. The string must be in the
- xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
- Arguments:
- AsciiGuidBuffer - Supplies a pointer to ascii string.
- GuidBuffer - Supplies a pointer where the GUID will be returned on
- success.
- Return Value:
- EFI_ABORTED if the string could not be converted.
- EFI_SUCCESS if the string was successfully converted.
- EFI_INVALID_PARAMETER if the input parameter is not valid.
- --*/
- {
- unsigned Data1;
- unsigned Data2;
- unsigned Data3;
- unsigned Data4[8];
- INT32 Index;
- if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Check that the Guid Format is strictly
- // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- //
- for (Index = 0;
- (AsciiGuidBuffer[Index] != '\0') && (Index < 37);
- Index += 1) {
- if ((Index == 8) || (Index == 13) || (Index == 18) || (Index == 23)) {
- if (AsciiGuidBuffer[Index] != '-') {
- break;
- }
- } else {
- if (((AsciiGuidBuffer[Index] >= '0') &&
- (AsciiGuidBuffer[Index] <= '9')) ||
- ((AsciiGuidBuffer[Index] >= 'a') &&
- (AsciiGuidBuffer[Index] <= 'f')) ||
- ((AsciiGuidBuffer[Index] >= 'A') &&
- (AsciiGuidBuffer[Index] <= 'F'))) {
- continue;
- } else {
- break;
- }
- }
- }
- if ((Index < 36) || (AsciiGuidBuffer[36] != '\0')) {
- GFFS_LOG_ERROR("Incorrect GUID \"%s\"\n"
- "Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-"
- "xxxxxxxxxxxx\".\n",
- AsciiGuidBuffer);
- return EFI_ABORTED;
- }
- //
- // Scan the guid string into the buffer.
- //
- Index = sscanf(AsciiGuidBuffer,
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- &Data1,
- &Data2,
- &Data3,
- &Data4[0],
- &Data4[1],
- &Data4[2],
- &Data4[3],
- &Data4[4],
- &Data4[5],
- &Data4[6],
- &Data4[7]);
- //
- // Verify the correct number of items were scanned.
- //
- if (Index != 11) {
- GFFS_LOG_ERROR("Incorrect GUID \"%s\"\n"
- "Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-"
- "xxxxxxxxxxxx\".\n",
- AsciiGuidBuffer);
- return EFI_ABORTED;
- }
- //
- // Copy the data into the output GUID.
- //
- GuidBuffer->Data1 = (UINT32)Data1;
- GuidBuffer->Data2 = (UINT16)Data2;
- GuidBuffer->Data3 = (UINT16)Data3;
- GuidBuffer->Data4[0] = (UINT8)Data4[0];
- GuidBuffer->Data4[1] = (UINT8)Data4[1];
- GuidBuffer->Data4[2] = (UINT8)Data4[2];
- GuidBuffer->Data4[3] = (UINT8)Data4[3];
- GuidBuffer->Data4[4] = (UINT8)Data4[4];
- GuidBuffer->Data4[5] = (UINT8)Data4[5];
- GuidBuffer->Data4[6] = (UINT8)Data4[6];
- GuidBuffer->Data4[7] = (UINT8)Data4[7];
- return EFI_SUCCESS;
- }
- VOID
- GffsConvertAsciiStringToUnicode (
- CHAR8 *String,
- CHAR16 *UnicodeString
- )
- /*++
- Routine Description:
- This routine converts and ASCII string into a unicode string.
- Arguments:
- String - Supplies a pointer to the ASCII string.
- UnicodeString - Supplies a pointer to the Unicode string.
- Return Value:
- None.
- --*/
- {
- while (*String != '\0') {
- *UnicodeString = (CHAR16)*String;
- String += 1;
- UnicodeString += 1;
- }
- *UnicodeString = L'\0';
- }
- VOID
- GffsCreateRandomGuid (
- EFI_GUID *Guid
- )
- /*++
- Routine Description:
- This routine creates a random GUID.
- Arguments:
- Guid - Supplies a pointer where the GUID will be returned.
- Return Value:
- None.
- --*/
- {
- UINT16 *Buffer;
- UINTN BufferSize;
- int Value;
- Buffer = (UINT16 *)Guid;
- BufferSize = sizeof(EFI_GUID) / sizeof(UINT16);
- while (BufferSize != 0) {
- Value = rand();
- *Buffer = Value;
- Buffer += 1;
- BufferSize -= 1;
- }
- return;
- }
- UINT8
- GffsCalculateChecksum8 (
- UINT8 *Buffer,
- UINTN Size
- )
- /*++
- Routine Description:
- This routine calculates the value needed for a valid UINT8 checksum.
- Arguments:
- Buffer - Supplies a pointer to a buffer containing byte data.
- Size - Supplies the size of the buffer.
- Return Value:
- Returns the 8-bit checksum of the field.
- --*/
- {
- return (UINT8)(0x100 - GffsCalculateSum8(Buffer, Size));
- }
- UINT8
- GffsCalculateSum8 (
- UINT8 *Buffer,
- UINTN Size
- )
- /*++
- Routine Description:
- This routine calculates the sum of the bytes in the given buffer.
- Arguments:
- Buffer - Supplies a pointer to a buffer containing byte data.
- Size - Supplies the size of the buffer.
- Return Value:
- Returns the 8-bit sum of each byte in the buffer.
- --*/
- {
- UINTN Index;
- UINT8 Sum;
- Sum = 0;
- for (Index = 0; Index < Size; Index += 1) {
- Sum = (UINT8)(Sum + Buffer[Index]);
- }
- return Sum;
- }
- BOOLEAN
- GffsCompareGuids (
- EFI_GUID *FirstGuid,
- EFI_GUID *SecondGuid
- )
- /*++
- Routine Description:
- This routine compares two GUIDs.
- Arguments:
- FirstGuid - Supplies a pointer to the first GUID.
- SecondGuid - Supplies a pointer to the second GUID.
- Return Value:
- TRUE if the GUIDs are equal.
- FALSE if the GUIDs are different.
- --*/
- {
- UINT32 *FirstPointer;
- UINT32 *SecondPointer;
- //
- // Compare GUIDs 32 bits at a time.
- //
- FirstPointer = (UINT32 *)FirstGuid;
- SecondPointer = (UINT32 *)SecondGuid;
- if ((FirstPointer[0] == SecondPointer[0]) &&
- (FirstPointer[1] == SecondPointer[1]) &&
- (FirstPointer[2] == SecondPointer[2]) &&
- (FirstPointer[3] == SecondPointer[3])) {
- return TRUE;
- }
- return FALSE;
- }
- VOID
- GffsPrintVersion (
- VOID
- )
- /*++
- Routine Description:
- This routine prints the utility version information.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- fprintf(stdout,
- "%s Version %d.%d\n",
- UTILITY_NAME,
- UTILITY_MAJOR_VERSION,
- UTILITY_MINOR_VERSION);
- return;
- }
- VOID
- GffsPrintUsage (
- VOID
- )
- /*++
- Routine Description:
- This routine prints application usage information.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- fprintf(stdout,
- "\n%s Creates a single FFS file from one or more input files.\n",
- UTILITY_NAME);
- fprintf(stdout, "\nUsage: %s [options] [files...]\n\n", UTILITY_NAME);
- fprintf(stdout, "Options:\n");
- fprintf(stdout,
- " -r SectionType, --sectiontype SectionType\n"
- "Define the section type of the input file just specified. \n"
- "Valid values are EFI_SECTION_COMPRESSION, \n"
- "EFI_SECTION_GUID_DEFINED, EFI_SECTION_PE32, EFI_SECTION_PIC, \n"
- "EFI_SECTION_TE, EFI_SECTION_DXE_DEPEX, \n"
- "EFI_SECTION_COMPATIBILITY16, EFI_SECTION_USER_INTERFACE, \n"
- "EFI_SECTION_VERSION, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \n"
- "EFI_SECTION_RAW, EFI_SECTION_FREEFORM_SUBTYPE_GUID, \n"
- "EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\n"
- " -o FileName, --outputfile FileName\n"
- "File is FFS file to be created.\n"
- " -t Type, --filetype Type\n"
- "Type is one FV file type defined in PI spec, which is\n"
- "EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FREEFORM,\n"
- "EFI_FV_FILETYPE_SECURITY_CORE, EFI_FV_FILETYPE_PEIM,\n"
- "EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,\n"
- "EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION,\n"
- "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\n"
- "EFI_FV_FILETYPE_SMM, EFI_FV_FILETYPE_SMM_CORE,\n"
- "EFI_FV_FILETYPE_COMBINED_SMM_DXE, \n"
- "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE.\n\n"
- " -g FileGuid, --fileguid FileGuid\n"
- "FileGuid is one module guid.\n"
- "Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n"
- " -x, --fixed Indicates that the file may not be moved\n"
- "from its present location.\n"
- " -s, --checksum Indicates to calculate file checksum.\n"
- " -a FileAlign, --align FileAlign\n"
- "FileAlign points to file alignment, which only support\n"
- "the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n"
- " -i SectionFile, --sectionfile SectionFile\n"
- "Section file will be contained in this FFS file.\n"
- " -n SectionAlign, --sectionalign SectionAlign\n"
- "SectionAlign points to section alignment, which support\n"
- "the alignment scope 1~64K. It is specified together\n"
- "with sectionfile to point its alignment in FFS file.\n"
- " -v, --verbose Turn on verbose output with informational "
- "messages.\n"
- " -q, --quiet Disable all messages except key message "
- "and fatal error\n"
- " -d, --debug level Enable debug messages, at input debug "
- "level.\n"
- " --version Show program's version number "
- "and exit.\n"
- " -h, --help Show this help message and exit.\n");
- return;
- }
|