📄 efirom.c
字号:
//
// Process until no more arguments
//
while (Argc > 0) {
if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) {
//
// To simplify string comparisons, replace slashes with dashes
//
Argv[0][0] = '-';
//
// Vendor ID specified with -v
//
if (stricmp (Argv[0], "-v") == 0) {
//
// Make sure there's another parameter
//
if (Argc > 1) {
Options->VendId = (UINT16) strtol (Argv[1], NULL, 16);
Options->VendIdValid = 1;
} else {
fprintf (stdout, "ERROR: Missing Vendor ID with %s\n\n",
Argv[0]);
Usage();
return STATUS_ERROR;
}
Argv++;
Argc--;
} else if (stricmp (Argv[0], "-d") == 0) {
//
// Device ID specified with -d
// Make sure there's another parameter
//
if (Argc > 1) {
Options->DevId = (UINT16)strtol (Argv[1], NULL, 16);
Options->DevIdValid = 1;
} else {
fprintf (stdout, "ERROR: Missing Device ID with %s\n\n",
Argv[0]);
Usage();
return STATUS_ERROR;
}
Argv++;
Argc--;
} else if (stricmp (Argv[0], "-o") == 0) {
//
// Output filename specified with -o
// Make sure there's another parameter
//
if (Argc > 1) {
strcpy (Options->OutFileName, Argv[1]);
} else {
fprintf (stdout, "ERROR: Missing output file name with %s\n\n",
Argv[0]);
Usage ();
return STATUS_ERROR;
}
Argv++;
Argc--;
} else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {
//
// Help option
//
Usage();
return STATUS_ERROR;
} else if (stricmp (Argv[0], "-b") == 0) {
//
// Specify binary files with -b
//
FileFlags = (FileFlags & ~FILE_FLAG_EFI) | FILE_FLAG_BINARY;
} else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) {
//
// Specify EFI files with -e. Specify EFI-compressed with -ec.
//
FileFlags = (FileFlags & ~FILE_FLAG_BINARY) | FILE_FLAG_EFI;
if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) {
FileFlags |= FILE_FLAG_COMPRESS;
}
//
// Specify not to set the LAST bit in the last file with -l
//
} else if (stricmp (Argv[0], "-l") == 0) {
Options->NoLast = 1;
} else if (stricmp (Argv[0], "-p") == 0) {
//
// -v for verbose would have been nicer, but it's already used. Let's use
// -p for prolix (wordy) output
//
Options->Verbose = 1;
} else if (stricmp (Argv[0], "-dump") == 0) {
//
// -dump for dumping a ROM image. In this case, say that the device id
// and vendor id are valid so we don't have to specify bogus ones on the
// command line.
//
Options->DumpOption = 1;
Options->VendIdValid = 1;
Options->DevIdValid = 1;
FileFlags = FILE_FLAG_BINARY;
} else if (stricmp (Argv[0], "-cc") == 0) {
//
// Class code value for the next file in the list.
// Make sure there's another parameter
//
if (Argc > 1) {
//
// No error checking on the return value. Could check for LONG_MAX,
// LONG_MIN, or 0 class code value if desired. Check range (3 bytes)
// at least.
//
ClassCode = (UINT32)strtol (Argv[1], NULL, 16);
if (ClassCode & 0xFF000000) {
fprintf (stdout, "ERROR: Class code %s out of range\n", Argv[1]);
return STATUS_ERROR;
}
} else {
fprintf (stdout, "ERROR: Missing class code value with %s\n\n",
Argv[0]);
Usage ();
return STATUS_ERROR;
}
Argv++;
Argc--;
} else if (stricmp (Argv[0], "-rev") == 0) {
//
// Code revision in the PCI data structure. The value is for the next
// file in the list.
// Make sure there's another parameter
//
if (Argc > 1) {
//
// No error checking on the return value. Could check for LONG_MAX,
// LONG_MIN, or 0 value if desired. Check range (2 bytes)
// at least.
//
CodeRevision = (UINT32)strtol (Argv[1], NULL, 16);
if (CodeRevision & 0xFFFF0000) {
fprintf (stdout, "ERROR: Code revision %s out of range\n", Argv[1]);
return STATUS_ERROR;
}
} else {
fprintf (stdout, "ERROR: Missing code revision value with %s\n\n",
Argv[0]);
Usage ();
return STATUS_ERROR;
}
Argv++;
Argc--;
} else {
fprintf(stdout, "ERROR: Invalid option specified: %s\n\n", Argv[0]);
Usage ();
return STATUS_ERROR;
}
} else {
//
// Not a slash-option argument. Must be a file name. Make sure they've specified
// -e or -b already.
//
if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) {
fprintf (stdout, "ERROR: Missing -e or -b with input file %s\n", Argv[0]);
return STATUS_ERROR;
}
//
// Create a new file structure
//
FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST));
if (FileList == NULL) {
fprintf (stdout, "ERROR: Memory allocation failure\n");
return STATUS_ERROR;
}
memset ((char *)FileList, 0, sizeof (FILE_LIST));
FileList->FileName = Argv[0];
FileList->FileFlags = FileFlags;
if (Options->FileList == NULL) {
Options->FileList = FileList;
} else {
PrevFileList->Next = FileList;
}
PrevFileList = FileList;
//
// Set the class code and code revision for this file, then reset the values.
//
FileList->ClassCode = ClassCode;
FileList->CodeRevision = (UINT16)CodeRevision;
ClassCode = 0;
CodeRevision = 0;
}
//
// Next argument
//
Argv++;
Argc--;
}
//
// Make sure they specified a device ID and vendor ID
//
if (!Options->VendIdValid) {
fprintf (stdout, "ERROR: Missing Vendor ID on command line\n\n");
Usage ();
return STATUS_ERROR;
}
if (!Options->DevIdValid) {
fprintf (stdout, "ERROR: Missing Device ID on command line\n\n");
Usage ();
return STATUS_ERROR;
}
//
// Must have specified some files
//
if (Options->FileList == NULL ) {
fprintf (stdout, "ERROR: Missing input file name\n");
Usage ();
return STATUS_ERROR;
}
return 0;
}
static
void
Usage ()
/*++
Routine Description:
Print usage information for this utility.
Arguments:
None.
Returns:
Nothing.
--*/
{
int i;
static const char *Msg[] = {
"EfiRom " UTILITY_VERSION " - Intel EFI Make Option ROM utility",
" Copyright (C), 1999-2002 Intel Coproration\n",
" Create an option ROM image from a list of input files",
" Usage: efirom {-p} [-v VendorId] [-d DeviceId] {-o OutFileName} ",
" [-e|-b] [FileName(s)]",
" where:",
" VendorId - required hex PCI Vendor ID for the device",
" DeviceId - required hex PCI Device ID for the device",
" OutFileName - optional output file name. Default is the first input",
" file name with a " DEFAULT_OUTPUT_EXTENSION " file extension",
" FileNames - input PE32 or binary file name(s)",
" BinFileName - input binary file name(s)",
" -p - for verbose output",
" -l - to not automatically set the LAST bit on the last file",
" -b - following FileNames are binary files",
" -e - following FileNames are EFI PE32 image files",
" -ec - following FileNames are EFI PE32 image files, and should",
" be compressed by this utility",
" -cc ClassCode - to use hex ClassCode in the PCI data structure header for",
" the following FileName",
" -rev Revision - to use hex Revision in the PCI data structure header for",
" the following FileName",
" -dump - to dump the headers of an existing option ROM image",
"",
"Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ",
"",
NULL
};
for (i = 0; Msg[i] != NULL; i++) {
fprintf (stdout, "%s\n", Msg[i]);
}
}
static
void
DumpImage (
FILE_LIST *InFile
)
{
PCI_EXPANSION_ROM_HEADER PciRomHdr;
FILE *InFptr;
UINT32 ImageStart;
UINT32 ImageCount;
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr;
PCI_DATA_STRUCTURE PciDs;
//
// Open the input file
//
if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) {
fprintf (stdout, "ERROR: Could not open input file %s\n",
InFile->FileName);
return;
}
//
// Go through the image and dump the header stuff for each
//
ImageCount = 0;
for (;;) {
//
// Save our postition in the file, since offsets in the headers
// are relative to the particular image.
//
ImageStart = ftell (InFptr);
ImageCount++;
//
// Read the option ROM header. Have to assume a raw binary image for now.
//
if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) {
fprintf(stdout, "ERROR: Failed to read PCI ROM header from file\n");
goto BailOut;
}
//
// Dump the contents of the header
//
fprintf (stdout, "Image %d -- Offset 0x%X\n", ImageCount, ImageStart);
fprintf (stdout, " ROM header contents\n");
fprintf (stdout, " Signature 0x%04X\n", (UINT32)PciRomHdr.Signature);
fprintf (stdout, " PCIR offset 0x%04X\n", (UINT32)PciRomHdr.PcirOffset);
//
// Find PCI data structure
//
if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) {
fprintf (stdout, "ERROR: Failed to seek to PCI data structure\n");
goto BailOut;
}
//
// Read and dump the PCI data structure
//
if (fread (&PciDs, sizeof (PciDs), 1, InFptr) != 1) {
fprintf(stdout, "ERROR: Failed to read PCI data structure from file\n");
goto BailOut;
}
fprintf (stdout, " PCI Data Structure\n");
fprintf (stdout, " Signature %c%c%c%c\n",
(char) PciDs.Signature,
(char )(PciDs.Signature >> 8),
(char )(PciDs.Signature >> 16),
(char )(PciDs.Signature >> 24));
fprintf (stdout, " Vendor ID 0x%04X\n", PciDs.VendorId);
fprintf (stdout, " Device ID 0x%04X\n", PciDs.DeviceId);
fprintf (stdout, " Class Code 0x%06X\n",
(UINT32) (PciDs.ClassCode[0] |
(PciDs.ClassCode[1] << 8) |
(PciDs.ClassCode[2] << 16)));
fprintf (stdout, " Image size 0x%X\n", PciDs.ImageLength * 512);
fprintf (stdout, " Code revision: 0x%04X\n", PciDs.CodeRevision);
fprintf (stdout, " Indicator 0x%02X", (UINT32)PciDs.Indicator);
//
// Print the indicator, used to flag the last image
//
if (PciDs.Indicator == INDICATOR_LAST) {
fprintf( stdout, " (last image)\n");
} else {
fprintf (stdout, "\n");
}
//
// Print the code type. If EFI code, then we can provide more info.
//
fprintf (stdout, " Code type 0x%02X", (UINT32)PciDs.CodeType);
if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
fprintf (stdout, " (EFI image)\n");
//
// Re-read the header as an EFI ROM header, then dump more info
//
fprintf (stdout, " EFI ROM header contents\n");
if (fseek (InFptr, ImageStart, SEEK_SET)) {
fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n");
goto BailOut;
}
if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) {
fprintf(stdout, "ERROR: Failed to read EFI PCI ROM header from file\n");
goto BailOut;
}
//
// Now dump more info
//
fprintf (stdout, " EFI Signature 0x%04X\n", EfiRomHdr.EfiSignature);
fprintf (stdout, " Compression Type 0x%04X ", (UINT32)
EfiRomHdr.CompressionType);
if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
fprintf (stdout, "(compressed)\n");
} else {
fprintf (stdout, "(not compressed)\n");
}
fprintf (stdout, " Machine type 0x%04X (%s)\n",
EfiRomHdr.EfiMachineType,
GetMachineTypeStr (EfiRomHdr.EfiMachineType));
fprintf (stdout, " Subsystem 0x%04X (%s)\n",
EfiRomHdr.EfiSubsystem,
GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem));
fprintf (stdout, " EFI image offset 0x%04X (@0x%X)\n",
(UINT32)EfiRomHdr.EfiImageHeaderOffset,
(UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart));
} else {
//
// Not an EFI image
//
fprintf (stdout, "\n");
}
//
// If code type is EFI image, then dump it as well?
//
// if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
// }
//
// If last image, then we're done
//
if (PciDs.Indicator == INDICATOR_LAST) {
goto BailOut;
}
//
// Seek to the start of the next image
//
if (fseek (InFptr, ImageStart + (PciDs.ImageLength * 512), SEEK_SET)) {
fprintf (stdout, "ERROR: Failed to seek to next image\n");
goto BailOut;
}
}
BailOut:
fclose (InFptr);
}
char *
GetMachineTypeStr (
UINT16 MachineType
)
{
int i;
for (i = 0; mMachineTypes[i].Name != NULL; i++) {
if (mMachineTypes[i].Value == MachineType) {
return mMachineTypes[i].Name;
}
}
return "unknown";
}
static
char *
GetSubsystemTypeStr (
UINT16 SubsystemType
)
{
int i;
for (i = 0; mSubsystemTypes[i].Name != NULL; i++) {
if (mSubsystemTypes[i].Value == SubsystemType) {
return mSubsystemTypes[i].Name;
}
}
return "unknown";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -