genfvimagelib.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,197 行 · 第 1/5 页
C
2,197 行
FvInfo->FvComponents[Index].Size = (UINTN) Value64;
} else {
printf ("WARNING: Could not read %s.\n", EFI_NV_VARIABLE_STRING);
}
Index++;
//
// Read component FV_EVENT_LOG
//
Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_EVENT_LOG_STRING, 0, Value);
if (Status == EFI_SUCCESS) {
//
// Add the component
//
strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING);
Status = AsciiStringToUint64 (Value, FALSE, &Value64);
if (EFI_ERROR (Status)) {
printf ("ERROR: %s is not a valid integer.\n", EFI_NV_EVENT_LOG_STRING);
return EFI_ABORTED;
}
FvInfo->FvComponents[Index].Size = (UINTN) Value64;
} else {
printf ("WARNING: Could not read %s.\n", EFI_NV_EVENT_LOG_STRING);
}
Index++;
//
// Read component FV_FTW_WORKING
//
Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_WORKING_STRING, 0, Value);
if (Status == EFI_SUCCESS) {
//
// Add the component
//
strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING);
Status = AsciiStringToUint64 (Value, FALSE, &Value64);
if (EFI_ERROR (Status)) {
printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_WORKING_STRING);
return EFI_ABORTED;
}
FvInfo->FvComponents[Index].Size = (UINTN) Value64;
} else {
printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_WORKING_STRING);
}
Index++;
//
// Read component FV_FTW_SPARE
//
Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_SPARE_STRING, 0, Value);
if (Status == EFI_SUCCESS) {
//
// Add the component
//
strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING);
Status = AsciiStringToUint64 (Value, FALSE, &Value64);
if (EFI_ERROR (Status)) {
printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_SPARE_STRING);
return EFI_ABORTED;
}
FvInfo->FvComponents[Index].Size = (UINTN) Value64;
} else {
printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_SPARE_STRING);
}
}
//
// Compute size for easy access later
//
FvInfo->Size = 0;
for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) {
FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].BlockLength;
}
return EFI_SUCCESS;
}
VOID
UpdateFfsFileState (
IN EFI_FFS_FILE_HEADER *FfsFile,
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
)
/*++
Routine Description:
This function changes the FFS file attributes based on the erase polarity
of the FV.
Arguments:
FfsFile File header.
FvHeader FV header.
Returns:
None
--*/
{
if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
FfsFile->State = (UINT8)~(FfsFile->State);
}
}
EFI_STATUS
ReadFfsAlignment (
IN EFI_FFS_FILE_HEADER *FfsFile,
IN OUT UINT32 *Alignment
)
/*++
Routine Description:
This function determines the alignment of the FFS input file from the file
attributes.
Arguments:
FfsFile FFS file to parse
Alignment The minimum required alignment of the FFS file, in bytes
Returns:
EFI_SUCCESS The function completed successfully.
EFI_INVALID_PARAMETER One of the input parameters was invalid.
EFI_ABORTED An error occurred.
--*/
{
//
// Verify input parameters.
//
if (FfsFile == NULL || Alignment == NULL) {
return EFI_INVALID_PARAMETER;
}
switch ((FfsFile->Attributes >> 3) & 0x07) {
case 0:
//
// 1 byte alignment
//
*Alignment = (1 << 0);
break;
case 1:
//
// 16 byte alignment
//
*Alignment = (1 << 4);
break;
case 2:
//
// 128 byte alignment
//
*Alignment = (1 << 7);
break;
case 3:
//
// 512 byte alignment
//
*Alignment = (1 << 9);
break;
case 4:
//
// 1K byte alignment
//
*Alignment = (1 << 10);
break;
case 5:
//
// 4K byte alignment
//
*Alignment = (1 << 12);
break;
case 6:
//
// 32K byte alignment
//
*Alignment = (1 << 15);
break;
case 7:
//
// 64K byte alignment
//
*Alignment = (1 << 16);
break;
default:
Error (NULL, 0, 0, "nvalid file attribute calculated, this is most likely a utility error", NULL);
return EFI_ABORTED;
}
return EFI_SUCCESS;
}
EFI_STATUS
AddPadFile (
IN OUT MEMORY_FILE *FvImage,
IN UINT32 DataAlignment
)
/*++
Routine Description:
This function adds a pad file to the FV image if it required to align the
data of the next file.
Arguments:
FvImage The memory image of the FV to add it to. The current offset
must be valid.
DataAlignment The data alignment of the next FFS file.
Returns:
EFI_SUCCESS The function completed successfully.
EFI_INVALID_PARAMETER One of the input parameters was invalid.
EFI_OUT_OF_RESOURCES Insufficient resources exist in the FV to complete
the pad file add.
--*/
{
EFI_FFS_FILE_HEADER *PadFile;
UUID PadFileGuid;
UINTN PadFileSize;
//
// Verify input parameters.
//
if (FvImage == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Basic assumption is we start from an 8 byte aligned address
// and our file header is a multiple of 8 bytes
//
assert ((UINTN) FvImage->CurrentFilePointer % 8 == 0);
assert (sizeof (EFI_FFS_FILE_HEADER) % 8 == 0);
//
// Check if a pad file is necessary
//
if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER)) % DataAlignment == 0) {
return EFI_SUCCESS;
}
//
// Write pad file header
//
PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;
//
// Verify that we have enough space for the file header
//
if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) {
return EFI_OUT_OF_RESOURCES;
}
UuidCreate (&PadFileGuid);
memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER));
memcpy (&PadFile->Name, &PadFileGuid, sizeof (EFI_GUID));
PadFile->Type = EFI_FV_FILETYPE_FFS_PAD;
PadFile->Attributes = 0;
//
// Calculate the pad file size
//
//
// This is the earliest possible valid offset (current plus pad file header
// plus the next file header)
//
PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2);
//
// Add whatever it takes to get to the next aligned address
//
while ((PadFileSize % DataAlignment) != 0) {
PadFileSize++;
}
//
// Subtract the next file header size
//
PadFileSize -= sizeof (EFI_FFS_FILE_HEADER);
//
// Subtract the starting offset to get size
//
PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;
//
// Write pad file size (calculated size minus next file header size)
//
PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF);
PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF);
PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF);
//
// Fill in checksums and state, they must be 0 for checksumming.
//
PadFile->IntegrityCheck.Checksum.Header = 0;
PadFile->IntegrityCheck.Checksum.File = 0;
PadFile->State = 0;
PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER));
if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) {
PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, PadFileSize);
} else {
PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
}
PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
UpdateFfsFileState (
(EFI_FFS_FILE_HEADER *) PadFile,
(EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
);
//
// Verify that we have enough space (including the padding
//
if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) {
return EFI_OUT_OF_RESOURCES;
}
//
// Update the current FV pointer
//
FvImage->CurrentFilePointer += PadFileSize;
return EFI_SUCCESS;
}
BOOLEAN
IsVtfFile (
IN EFI_FFS_FILE_HEADER *FileBuffer
)
/*++
Routine Description:
This function checks the header to validate if it is a VTF file
Arguments:
FileBuffer Buffer in which content of a file has been read.
Returns:
TRUE If this is a VTF file
FALSE If this is not a VTF file
--*/
{
EFI_GUID VtfGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
if (!memcmp (&FileBuffer->Name, &VtfGuid, sizeof (EFI_GUID))) {
return TRUE;
} else {
return FALSE;
}
}
EFI_STATUS
FfsRebaseImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINT32 *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
Arguments:
FileHandle - The handle to the PE/COFF file
FileOffset - The offset, in bytes, into the file to read
ReadSize - The number of bytes to read from the file starting at FileOffset
Buffer - A pointer to the buffer to read the data into.
Returns:
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
--*/
{
CHAR8 *Destination8;
CHAR8 *Source8;
UINT32 Length;
Destination8 = Buffer;
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
Length = *ReadSize;
while (Length--) {
*(Destination8++) = *(Source8++);
}
return EFI_SUCCESS;
}
EFI_STATUS
RebaseFfsFile (
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
/*++
Routine Description:
This function determines if a file is XIP and should be rebased. It will
rebase any PE32 sections found in the file using the base address.
Arguments:
FfsFile A pointer to Ffs file image.
BaseAddress The base address to use for rebasing the file image.
Returns:
EFI_SUCCESS The image was properly rebased.
EFI_INVALID_PARAMETER An input parameter is invalid.
EFI_ABORTED An error occurred while rebasing the input file image.
EFI_OUT_OF_RESOURCES Could not allocate a required resource.
--*/
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?