⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 efirom.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 3 页
字号:

  //
  // 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 + -