genfvimagelib.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,197 行 · 第 1/5 页

C
2,197
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  GenFvImageLib.c

Abstract:

  This file contains functions required to generate a Firmware Volume.

--*/

//
// Include files
//
#include "GenFvImageLib.h"
#include "GenFvImageLibInternal.h"
#include <string.h>
#include EFI_GUID_DEFINITION (FirmwareFileSystem)
#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
#include "EfiFirmwareFileSystem.h"
#include "EfiWorkingBlockHeader.h"
#include "EfiVariable.h"
#include <io.h>
#include <assert.h>
#include "CommonLib.h"
#include "FvLib.h"
#include "EfiImage.h"
#include "crc32.h"
#include "EfiUtilityMsgs.h"

//
// Define the PE/COFF loader
//
extern EFI_PEI_PE_COFF_LOADER_PROTOCOL  mPeCoffLoader;

//
// Local function prototypes
//
EFI_STATUS
GetPe32Info (
  IN UINT8                  *Pe32,
  OUT UINT32                *EntryPoint,
  OUT UINT32                *BaseOfCode,
  OUT UINT16                *MachineType
  );

//
// Local function implementations.
//
EFI_GUID  FfsGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID;
EFI_GUID  DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f };

//
// This data array will be located at the base of the Firmware Volume Header (FVH)
// in the boot block.  It must not exceed 14 bytes of code.  The last 2 bytes
// will be used to keep the FVH checksum consistent.
// This code will be run in response to a starutp IPI for HT-enabled systems.
//
#define SIZEOF_STARTUP_DATA_ARRAY 0x10

UINT8                                   m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {
  //
  // EA D0 FF 00 F0               ; far jmp F000:FFD0
  // 0, 0, 0, 0, 0, 0, 0, 0, 0,   ; Reserved bytes
  // 0, 0                         ; Checksum Padding
  //
  0xEA,
  0xD0,
  0xFF,
  0x0,
  0xF0,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00
};

UINT8                                   m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {
  //
  // EB CE                               ; jmp short ($-0x30)
  // ; (from offset 0x0 to offset 0xFFD0)
  // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes
  // 0, 0                                ; Checksum Padding
  //
  0xEB,
  0xCE,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00
};

EFI_STATUS
ParseFvInf (
  IN MEMORY_FILE  *InfFile,
  IN FV_INFO      *FvInfo
  )
/*++

Routine Description:

  This function parses a FV.INF file and copies info into a FV_INFO structure.

Arguments:

  InfFile         Memory file image.
  FvInfo          Information read from INF file.

Returns:

  EFI_SUCCESS       INF file information successfully retrieved.
  EFI_ABORTED       INF file has an invalid format.
  EFI_NOT_FOUND     A required string was not found in the INF file.
--*/
{
  CHAR8       Value[_MAX_PATH];
  UINT64      Value64;
  UINTN       Index;
  EFI_STATUS  Status;

  //
  // Initialize FV info
  //
  memset (FvInfo, 0, sizeof (FV_INFO));

  //
  // Read the FV base address
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Get the base address
    //
    Status = AsciiStringToUint64 (Value, FALSE, &Value64);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "invalid value");
      return EFI_ABORTED;
    }

    FvInfo->BaseAddress = Value64;
  } else {
    Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "could not find value");
    return EFI_ABORTED;
  }
  //
  // Read the FV Guid
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_GUID_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Get the guid value
    //
    Status = StringToGuid (Value, &FvInfo->FvGuid);
    if (EFI_ERROR (Status)) {
      memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID));
    }
  } else {
    memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID));
  }
  //
  // Read the FV file name
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // copy the file name
    //
    strcpy (FvInfo->FvName, Value);
  } else {
    Error (NULL, 0, 0, EFI_FV_FILE_NAME_STRING, "value not specified");
    return EFI_ABORTED;
  }
  //
  // Read the Sym file name
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_SYM_FILE_NAME_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // copy the file name
    //
    strcpy (FvInfo->SymName, Value);
  } else {
    //
    // Symbols not required, so init to NULL.
    //
    strcpy (FvInfo->SymName, "");
  }
  //
  // Read the read disabled capability attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_DISABLED_CAP_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the read disabled flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_READ_DISABLED_CAP;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "value not specified");
    return Status;
  }
  //
  // Read the read enabled capability attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_ENABLED_CAP_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the read disabled flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_READ_ENABLED_CAP;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "value not specified");
    return Status;
  }
  //
  // Read the read status attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_STATUS_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the read disabled flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_READ_STATUS;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "value not specified");
    return Status;
  }
  //
  // Read the write disabled capability attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_DISABLED_CAP_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the write disabled flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_WRITE_DISABLED_CAP;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "value not specified");
    return Status;
  }
  //
  // Read the write enabled capability attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_ENABLED_CAP_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the write disabled flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_WRITE_ENABLED_CAP;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "value not specified");
    return Status;
  }
  //
  // Read the write status attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_STATUS_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the write disabled flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_WRITE_STATUS;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "value not specified");
    return Status;
  }
  //
  // Read the lock capability attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_CAP_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the attribute flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_LOCK_CAP;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "value not specified");
    return Status;
  }
  //
  // Read the lock status attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_STATUS_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the attribute flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_LOCK_STATUS;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "value not specified");
    return Status;
  }
  //
  // Read the sticky write attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_STICKY_WRITE_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the attribute flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_STICKY_WRITE;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "value not specified");
    return Status;
  }
  //
  // Read the memory mapped attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_MEMORY_MAPPED_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the attribute flag
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_MEMORY_MAPPED;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "value not specified");
    return Status;
  }
  //
  // Read the erase polarity attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ERASE_POLARITY_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update the attribute flag
    //
    if (strcmp (Value, ONE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_ERASE_POLARITY;
    } else if (strcmp (Value, ZERO_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);
      return EFI_ABORTED;
    }
  } else {
    Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "value not specified");
    return Status;
  }
  //
  // Read the alignment capabilities attribute
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_CAP_STRING, 0, Value);

  if (Status == EFI_SUCCESS) {
    //
    // Update attribute
    //
    if (strcmp (Value, TRUE_STRING) == 0) {
      FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_CAP;
    } else if (strcmp (Value, FALSE_STRING) != 0) {
      Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?