Add core FFS3 support, FwVolDxe and SectionExtraction.

Signed-off-by: lzeng14
Reviewed-by: lgao4

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12585 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lzeng14 2011-10-27 10:46:50 +00:00
parent 6c85d16217
commit 23491d5cc2
8 changed files with 510 additions and 267 deletions

View File

@ -239,7 +239,11 @@ VerifyHeaderChecksum (
{
UINT8 HeaderChecksum;
HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
if (IS_FFS_FILE2 (FfsHeader)) {
HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2));
} else {
HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
}
HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
if (HeaderChecksum == 0) {
@ -265,18 +269,19 @@ VerifyFileChecksum (
{
UINT8 FileChecksum;
EFI_FV_FILE_ATTRIBUTES Attributes;
UINT32 FileSize;
Attributes = FfsHeader->Attributes;
if ((Attributes & FFS_ATTRIB_CHECKSUM) != 0) {
FileSize = *(UINT32 *) FfsHeader->Size & 0x00FFFFFF;
//
// Check checksum of FFS data
//
FileChecksum = CalculateSum8 ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FileSize - sizeof (EFI_FFS_FILE_HEADER));
if (IS_FFS_FILE2 (FfsHeader)) {
FileChecksum = CalculateSum8 ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER2));
} else {
FileChecksum = CalculateSum8 ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER));
}
FileChecksum = (UINT8) (FileChecksum + FfsHeader->IntegrityCheck.Checksum.File);
if (FileChecksum == 0) {
@ -388,10 +393,18 @@ GetNextPossibleFileHeader (
//
// Skip this header
//
return (EFI_PHYSICAL_ADDRESS) (UINTN) FfsHeader + sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FfsHeader)) {
return (EFI_PHYSICAL_ADDRESS) (UINTN) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2);
} else {
return (EFI_PHYSICAL_ADDRESS) (UINTN) FfsHeader + sizeof (EFI_FFS_FILE_HEADER);
}
}
FileLength = *(UINT32 *) FfsHeader->Size & 0x00FFFFFF;
if (IS_FFS_FILE2 (FfsHeader)) {
FileLength = FFS_FILE2_SIZE (FfsHeader);
} else {
FileLength = FFS_FILE_SIZE (FfsHeader);
}
//
// Since FileLength is not multiple of 8, we need skip some bytes
@ -593,33 +606,3 @@ IsValidFFSFile (
return TRUE;
}
/**
Locate the first file in FV.
@param FvDevice Cached FV image.
@param FirstFile Points to the got first FFS file header.
@retval EFI_NOT_FOUND No FFS file is found in FV.
@retval EFI_SUCCESS The first FFS file is got.
**/
EFI_STATUS
FvLocateFirstFile (
IN FV_DEVICE *FvDevice,
OUT EFI_FFS_FILE_HEADER **FirstFile
)
{
FFS_FILE_LIST_ENTRY *TmpFileList;
LIST_ENTRY *Link;
Link = FvDevice->FfsFileListHeader.ForwardLink;
if (Link == &FvDevice->FfsFileListHeader) {
return EFI_NOT_FOUND;
}
TmpFileList = (FFS_FILE_LIST_ENTRY *) Link;
*FirstFile = (EFI_FFS_FILE_HEADER *) TmpFileList->FfsHeader;
return EFI_SUCCESS;
}

View File

@ -27,17 +27,22 @@ SetPadFileChecksum (
IN EFI_FFS_FILE_HEADER *PadFileHeader
)
{
UINT32 PadFileLength;
if ((PadFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) {
PadFileLength = *(UINT32 *) PadFileHeader->Size & 0x00FFFFFF;
if (IS_FFS_FILE2 (PadFileHeader)) {
//
// Calculate checksum of Pad File Data
//
PadFileHeader->IntegrityCheck.Checksum.File =
CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2));
//
// Calculate checksum of Pad File Data
//
PadFileHeader->IntegrityCheck.Checksum.File =
CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER), PadFileLength - sizeof (EFI_FFS_FILE_HEADER));
} else {
//
// Calculate checksum of Pad File Data
//
PadFileHeader->IntegrityCheck.Checksum.File =
CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER));
}
} else {
@ -76,8 +81,17 @@ FvCreatePadFileInFreeSpace (
UINTN StateOffset;
UINT8 *StartPos;
FFS_FILE_LIST_ENTRY *FfsFileEntry;
UINTN HeaderSize;
UINTN FileSize;
if (FreeSpaceEntry->Length < Size + sizeof (EFI_FFS_FILE_HEADER)) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
FileSize = Size + HeaderSize;
if (FileSize > 0x00FFFFFF) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
FileSize = Size + HeaderSize;
}
if (FreeSpaceEntry->Length < FileSize) {
return EFI_OUT_OF_RESOURCES;
}
@ -93,7 +107,7 @@ FvCreatePadFileInFreeSpace (
if (!IsBufferErased (
FvDevice->ErasePolarity,
StartPos,
Size + sizeof (EFI_FFS_FILE_HEADER)
FileSize
)) {
return EFI_DEVICE_ERROR;
}
@ -122,8 +136,8 @@ FvCreatePadFileInFreeSpace (
//
// Update Free Space Entry, since header is allocated
//
FreeSpaceEntry->Length -= sizeof (EFI_FFS_FILE_HEADER);
FreeSpaceEntry->StartingAddress += sizeof (EFI_FFS_FILE_HEADER);
FreeSpaceEntry->Length -= HeaderSize;
FreeSpaceEntry->StartingAddress += HeaderSize;
//
// Fill File Name Guid, here we assign a NULL-GUID to Pad files
@ -135,15 +149,21 @@ FvCreatePadFileInFreeSpace (
//
PadFileHeader->Type = EFI_FV_FILETYPE_FFS_PAD;
PadFileHeader->Attributes = 0;
*(UINT32 *) PadFileHeader->Size &= 0xFF000000;
*(UINT32 *) PadFileHeader->Size |= (Size + sizeof (EFI_FFS_FILE_HEADER));
if ((FileSize) > 0x00FFFFFF) {
((EFI_FFS_FILE_HEADER2 *) PadFileHeader)->ExtendedSize = (UINT32) FileSize;
*(UINT32 *) PadFileHeader->Size &= 0xFF000000;
PadFileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
} else {
*(UINT32 *) PadFileHeader->Size &= 0xFF000000;
*(UINT32 *) PadFileHeader->Size |= FileSize;
}
SetHeaderChecksum (PadFileHeader);
SetPadFileChecksum (PadFileHeader);
Offset = (UINTN) (StartPos - FvDevice->CachedFv);
NumBytesWritten = sizeof (EFI_FFS_FILE_HEADER);
NumBytesWritten = HeaderSize;
Status = FvcWrite (
FvDevice,
Offset,
@ -220,8 +240,14 @@ FvFillPadFile (
//
PadFileHeader->Type = EFI_FV_FILETYPE_FFS_PAD;
PadFileHeader->Attributes = 0;
*(UINT32 *) PadFileHeader->Size &= 0xFF000000;
*(UINT32 *) PadFileHeader->Size |= PadFileLength;
if (PadFileLength > 0x00FFFFFF) {
((EFI_FFS_FILE_HEADER2 *) PadFileHeader)->ExtendedSize = (UINT32) PadFileLength;
*(UINT32 *) PadFileHeader->Size &= 0xFF000000;
PadFileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
} else {
*(UINT32 *) PadFileHeader->Size &= 0xFF000000;
*(UINT32 *) PadFileHeader->Size |= PadFileLength;
}
SetHeaderChecksum (PadFileHeader);
SetPadFileChecksum (PadFileHeader);
@ -286,8 +312,14 @@ FvFillFfsFile (
TmpFileHeader->Attributes = TmpFileAttribute;
*(UINT32 *) TmpFileHeader->Size &= 0xFF000000;
*(UINT32 *) TmpFileHeader->Size |= ActualFileSize;
if (ActualFileSize > 0x00FFFFFF) {
((EFI_FFS_FILE_HEADER2 *) FileHeader)->ExtendedSize = (UINT32) ActualFileSize;
*(UINT32 *) FileHeader->Size &= 0xFF000000;
FileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
} else {
*(UINT32 *) FileHeader->Size &= 0xFF000000;
*(UINT32 *) FileHeader->Size |= ActualFileSize;
}
SetHeaderChecksum (TmpFileHeader);
SetFileChecksum (TmpFileHeader, ActualFileSize);
@ -319,12 +351,14 @@ FvAdjustFfsFile (
IN UINTN ExtraLength
)
{
UINTN FileLength;
UINT8 *Ptr;
UINT8 PadingByte;
FileLength = *(UINT32 *) FileHeader->Size & 0x00FFFFFF;
Ptr = (UINT8 *) FileHeader + FileLength;
if (IS_FFS_FILE2 (FileHeader)) {
Ptr = (UINT8 *) FileHeader + FFS_FILE2_SIZE (FileHeader);
} else {
Ptr = (UINT8 *) FileHeader + FFS_FILE_SIZE (FileHeader);
}
if (ErasePolarity == 0) {
PadingByte = 0;
@ -461,11 +495,15 @@ FvCreateNewFileInsidePadFile (
//
InitializeListHead (&NewFileList);
PadAreaLength = (*(UINT32 *) OldPadFileHeader->Size & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (OldPadFileHeader)) {
PadAreaLength = FFS_FILE2_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
} else {
PadAreaLength = FFS_FILE_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER));
}
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER));
if (RequiredAlignment != 8) {
if (PadSize != 0) {
//
// Insert a PAD file before to achieve required alignment
//
@ -488,6 +526,7 @@ FvCreateNewFileInsidePadFile (
FileAttributes
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
return Status;
}
@ -527,7 +566,11 @@ FvCreateNewFileInsidePadFile (
//
// Start writing to FV
//
StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (OldPadFileHeader)) {
StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2);
} else {
StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER);
}
Offset = (UINTN) (StartPos - FvDevice->CachedFv);
@ -540,6 +583,7 @@ FvCreateNewFileInsidePadFile (
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
FvDevice->CurrentFfsFile = NULL;
return Status;
}
@ -562,6 +606,8 @@ FvCreateNewFileInsidePadFile (
);
if (EFI_ERROR (Status)) {
SetFileState (EFI_FILE_HEADER_INVALID, OldPadFileHeader);
FreeFileList (&NewFileList);
FvDevice->CurrentFfsFile = NULL;
return Status;
}
@ -657,7 +703,11 @@ FvCreateMultipleFilesInsidePadFile (
NewFileListEntry = NULL;
OldPadFileHeader = (EFI_FFS_FILE_HEADER *) PadFileEntry->FfsHeader;
PadAreaLength = (*(UINT32 *) OldPadFileHeader->Size & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (OldPadFileHeader)) {
PadAreaLength = FFS_FILE2_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
} else {
PadAreaLength = FFS_FILE_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
}
Status = UpdateHeaderBit (
FvDevice,
@ -671,7 +721,11 @@ FvCreateMultipleFilesInsidePadFile (
// Update PAD area
//
TotalSize = 0;
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER));
if (IS_FFS_FILE2 (OldPadFileHeader)) {
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
} else {
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER));
}
FileHeader = PadFileHeader;
for (Index = 0; Index < NumOfFiles; Index++) {
@ -679,6 +733,7 @@ FvCreateMultipleFilesInsidePadFile (
FvFillPadFile (PadFileHeader, PadSize[Index]);
NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
if (NewFileListEntry == NULL) {
FreeFileList (&NewFileList);
return EFI_OUT_OF_RESOURCES;
}
@ -697,6 +752,7 @@ FvCreateMultipleFilesInsidePadFile (
FileData[Index].FileAttributes
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
return Status;
}
@ -729,6 +785,7 @@ FvCreateMultipleFilesInsidePadFile (
NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
if (NewFileListEntry == NULL) {
FreeFileList (&NewFileList);
FvDevice->CurrentFfsFile = NULL;
return EFI_OUT_OF_RESOURCES;
}
@ -749,7 +806,11 @@ FvCreateMultipleFilesInsidePadFile (
//
// Start writing to FV
//
StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (OldPadFileHeader)) {
StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2);
} else {
StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER);
}
Offset = (UINTN) (StartPos - FvDevice->CachedFv);
@ -762,6 +823,7 @@ FvCreateMultipleFilesInsidePadFile (
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
FvDevice->CurrentFfsFile = NULL;
return Status;
}
@ -772,6 +834,7 @@ FvCreateMultipleFilesInsidePadFile (
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
FvDevice->CurrentFfsFile = NULL;
return Status;
}
@ -795,6 +858,136 @@ FvCreateMultipleFilesInsidePadFile (
return EFI_SUCCESS;
}
/**
Create multiple files within the Free Space.
@param FvDevice Firmware Volume Device.
@param FreeSpaceEntry Indicating in which Free Space(Cache) the multiple files will be inserted.
@param NumOfFiles Total File number to be written.
@param BufferSize The array of buffer size of each FfsBuffer.
@param ActualFileSize The array of actual file size.
@param PadSize The array of leading pad file size for each FFS File
@param FfsBuffer The array of Ffs Buffer pointer.
@param FileData The array of EFI_FV_WRITE_FILE_DATA structure,
used to get name, attributes, type, etc.
@retval EFI_SUCCESS Add the input multiple files into PAD file area.
@retval EFI_OUT_OF_RESOURCES No enough memory is allocated.
@retval other error Files can't be added into PAD file area.
**/
EFI_STATUS
FvCreateMultipleFilesInsideFreeSpace (
IN FV_DEVICE *FvDevice,
IN FREE_SPACE_ENTRY *FreeSpaceEntry,
IN UINTN NumOfFiles,
IN UINTN *BufferSize,
IN UINTN *ActualFileSize,
IN UINTN *PadSize,
IN UINT8 **FfsBuffer,
IN EFI_FV_WRITE_FILE_DATA *FileData
)
{
EFI_STATUS Status;
UINTN Index;
EFI_FFS_FILE_HEADER *PadFileHeader;
EFI_FFS_FILE_HEADER *FileHeader;
UINTN TotalSize;
LIST_ENTRY NewFileList;
FFS_FILE_LIST_ENTRY *NewFileListEntry;
UINTN Offset;
UINTN NumBytesWritten;
UINT8 *StartPos;
InitializeListHead (&NewFileList);
NewFileListEntry = NULL;
TotalSize = 0;
StartPos = FreeSpaceEntry->StartingAddress;
PadFileHeader = (EFI_FFS_FILE_HEADER *) StartPos;
FileHeader = PadFileHeader;
for (Index = 0; Index < NumOfFiles; Index++) {
if (PadSize[Index] != 0) {
FvFillPadFile (PadFileHeader, PadSize[Index]);
NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
if (NewFileListEntry == NULL) {
FreeFileList (&NewFileList);
return EFI_OUT_OF_RESOURCES;
}
NewFileListEntry->FfsHeader = (UINT8 *) PadFileHeader;
InsertTailList (&NewFileList, &NewFileListEntry->Link);
}
FileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) PadFileHeader + PadSize[Index]);
Status = FvFillFfsFile (
FileHeader,
FfsBuffer[Index],
BufferSize[Index],
ActualFileSize[Index],
FileData[Index].NameGuid,
FileData[Index].Type,
FileData[Index].FileAttributes
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
return Status;
}
NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY));
if (NewFileListEntry == NULL) {
FreeFileList (&NewFileList);
return EFI_OUT_OF_RESOURCES;
}
NewFileListEntry->FfsHeader = (UINT8 *) FileHeader;
InsertTailList (&NewFileList, &NewFileListEntry->Link);
PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FileHeader + BufferSize[Index]);
TotalSize += PadSize[Index];
TotalSize += BufferSize[Index];
}
if (FreeSpaceEntry->Length < TotalSize) {
FreeFileList (&NewFileList);
return EFI_OUT_OF_RESOURCES;
}
FvDevice->CurrentFfsFile = NewFileListEntry;
//
// Start writing to FV
//
Offset = (UINTN) (StartPos - FvDevice->CachedFv);
NumBytesWritten = TotalSize;
Status = FvcWrite (
FvDevice,
Offset,
&NumBytesWritten,
StartPos
);
if (EFI_ERROR (Status)) {
FreeFileList (&NewFileList);
FvDevice->CurrentFfsFile = NULL;
return Status;
}
FreeSpaceEntry->Length -= TotalSize;
FreeSpaceEntry->StartingAddress += TotalSize;
NewFileListEntry = (FFS_FILE_LIST_ENTRY *) (NewFileList.ForwardLink);
while (NewFileListEntry != (FFS_FILE_LIST_ENTRY *) &NewFileList) {
InsertTailList (&FvDevice->FfsFileListHeader, &NewFileListEntry->Link);
NewFileListEntry = (FFS_FILE_LIST_ENTRY *) (NewFileListEntry->Link.ForwardLink);
}
return EFI_SUCCESS;
}
/**
Write multiple files into FV in reliable method.
@ -838,6 +1031,7 @@ FvCreateMultipleFiles (
FFS_FILE_LIST_ENTRY *OldFfsFileEntry[MAX_FILES];
EFI_FFS_FILE_HEADER *OldFileHeader[MAX_FILES];
BOOLEAN IsCreateFile;
UINTN HeaderSize;
//
// To use this function, we must ensure that the NumOfFiles is great
@ -863,10 +1057,15 @@ FvCreateMultipleFiles (
// Adjust file size
//
for (Index1 = 0; Index1 < NumOfFiles; Index1++) {
ActualFileSize[Index1] = FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER);
HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
ActualFileSize[Index1] = FileData[Index1].BufferSize + HeaderSize;
if (ActualFileSize[Index1] > 0x00FFFFFF) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
ActualFileSize[Index1] = FileData[Index1].BufferSize + HeaderSize;
}
BufferSize[Index1] = ActualFileSize[Index1];
if (BufferSize[Index1] == sizeof (EFI_FFS_FILE_HEADER)) {
if (BufferSize[Index1] == HeaderSize) {
//
// clear file attributes, zero-length file does not have any attributes
//
@ -883,18 +1082,18 @@ FvCreateMultipleFiles (
// Copy File Data into FileBuffer
//
CopyMem (
FfsBuffer[Index1] + sizeof (EFI_FFS_FILE_HEADER),
FfsBuffer[Index1] + HeaderSize,
FileData[Index1].Buffer,
FileData[Index1].BufferSize
);
if (FvDevice->ErasePolarity == 1) {
for (Index2 = 0; Index2 < sizeof (EFI_FFS_FILE_HEADER); Index2++) {
for (Index2 = 0; Index2 < HeaderSize; Index2++) {
FfsBuffer[Index1][Index2] = (UINT8)~FfsBuffer[Index1][Index2];
}
}
if ((FileData[Index1].FileAttributes & FFS_ATTRIB_DATA_ALIGNMENT) != 0) {
if ((FileData[Index1].FileAttributes & EFI_FV_FILE_ATTRIB_ALIGNMENT) != 0) {
RequiredAlignment[Index1] = GetRequiredAlignment (FileData[Index1].FileAttributes);
}
//
@ -954,7 +1153,6 @@ FvCreateMultipleFiles (
if (Status == EFI_NOT_FOUND) {
//
// Try to find a free space that can hold these files
// and create a suitable PAD file in this free space
//
Status = FvSearchSuitableFreeSpace (
FvDevice,
@ -969,35 +1167,33 @@ FvCreateMultipleFiles (
FreeFfsBuffer (NumOfFiles, FfsBuffer);
return EFI_OUT_OF_RESOURCES;
}
//
// Create a PAD file in that space
//
Status = FvCreatePadFileInFreeSpace (
Status = FvCreateMultipleFilesInsideFreeSpace (
FvDevice,
FreeSpaceEntry,
TotalSizeNeeded,
&PadFileEntry
NumOfFiles,
BufferSize,
ActualFileSize,
PadSize,
FfsBuffer,
FileData
);
if (EFI_ERROR (Status)) {
FreeFfsBuffer (NumOfFiles, FfsBuffer);
return Status;
}
} else {
//
// Create multiple files inside such a pad file
// to achieve lock-step update
//
Status = FvCreateMultipleFilesInsidePadFile (
FvDevice,
PadFileEntry,
NumOfFiles,
BufferSize,
ActualFileSize,
PadSize,
FfsBuffer,
FileData
);
}
//
// Create multiple files inside such a pad file
// to achieve lock-step update
//
Status = FvCreateMultipleFilesInsidePadFile (
FvDevice,
PadFileEntry,
NumOfFiles,
BufferSize,
ActualFileSize,
PadSize,
FfsBuffer,
FileData
);
FreeFfsBuffer (NumOfFiles, FfsBuffer);

View File

@ -4,7 +4,7 @@
Layers on top of Firmware Block protocol to produce a file abstraction
of FV based files.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -206,7 +206,6 @@ FvCheck (
UINT8 *FreeStart;
UINTN FreeSize;
UINT8 ErasePolarity;
UINTN FileLength;
EFI_FFS_FILE_STATE FileState;
UINT8 *TopFvAddress;
UINTN TestLength;
@ -230,6 +229,8 @@ FvCheck (
}
ASSERT (FwVolHeader != NULL);
FvDevice->IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
//
// Double Check firmware volume header here
//
@ -412,7 +413,14 @@ FvCheck (
(EFI_FFS_FILE_HEADER *) Ptr
);
if ((FileState == EFI_FILE_HEADER_INVALID) || (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
Ptr += sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (Ptr)) {
if (!FvDevice->IsFfs3Fv) {
DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name));
}
Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER2);
} else {
Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER);
}
continue;
@ -425,8 +433,22 @@ FvCheck (
}
}
if (IS_FFS_FILE2 (Ptr)) {
ASSERT (FFS_FILE2_SIZE (Ptr) > 0x00FFFFFF);
if (!FvDevice->IsFfs3Fv) {
DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name));
Ptr = Ptr + FFS_FILE2_SIZE (Ptr);
//
// Adjust Ptr to the next 8-byte aligned boundry.
//
while (((UINTN) Ptr & 0x07) != 0) {
Ptr++;
}
continue;
}
}
if (IsValidFFSFile (FvDevice, (EFI_FFS_FILE_HEADER *) Ptr)) {
FileLength = *(UINT32 *) ((EFI_FFS_FILE_HEADER *) Ptr)->Size & 0x00FFFFFF;
FileState = GetFileState (
FvDevice->ErasePolarity,
(EFI_FFS_FILE_HEADER *) Ptr
@ -449,7 +471,11 @@ FvCheck (
InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
}
Ptr += FileLength;
if (IS_FFS_FILE2 (Ptr)) {
Ptr = Ptr + FFS_FILE2_SIZE (Ptr);
} else {
Ptr = Ptr + FFS_FILE_SIZE (Ptr);
}
//
// Adjust Ptr to the next 8-byte aligned boundry.
@ -513,9 +539,7 @@ FwVolDriverInit (
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Get FV with gEfiFirmwareFileSystemGuid
//
for (Index = 0; Index < HandleCount; Index += 1) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
@ -536,10 +560,8 @@ FwVolDriverInit (
// Check to see that the file system is indeed formatted in a way we can
// understand it...
//
if (!CompareGuid (
&FwVolHeader->FileSystemGuid,
&gEfiFirmwareFileSystem2Guid
)) {
if ((!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid)) &&
(!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid))) {
FreePool (FwVolHeader);
continue;
}

View File

@ -1,7 +1,7 @@
/** @file
Common defines and definitions for a FwVolDxe driver.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -20,6 +20,7 @@
#include <PiDxe.h>
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/FirmwareFileSystem3.h>
#include <Protocol/SectionExtraction.h>
#include <Protocol/FaultTolerantWrite.h>
#include <Protocol/FirmwareVolume2.h>
@ -92,7 +93,7 @@ typedef struct {
LIST_ENTRY FfsFileListHeader;
FFS_FILE_LIST_ENTRY *CurrentFfsFile;
BOOLEAN IsFfs3Fv;
} FV_DEVICE;
#define FV_DEVICE_FROM_THIS(a) CR (a, FV_DEVICE, Fv, FV_DEVICE_SIGNATURE)
@ -489,22 +490,6 @@ GetFwVolHeader (
OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
);
/**
Locate the first file in FV.
@param FvDevice Cached FV image.
@param FirstFile Points to the got first FFS file header.
@retval EFI_NOT_FOUND No FFS file is found in FV.
@retval EFI_SUCCESS The first FFS file is got.
**/
EFI_STATUS
FvLocateFirstFile (
IN FV_DEVICE *FvDevice,
OUT EFI_FFS_FILE_HEADER **FirstFile
);
/**
Convert the Buffer Address to LBA Entry Address.

View File

@ -57,6 +57,7 @@
[Guids]
gEfiFirmwareVolumeTopFileGuid ## CONSUMES
gEfiFirmwareFileSystem2Guid ## CONSUMES
gEfiFirmwareFileSystem3Guid ## CONSUMES
[Protocols]
gEfiSectionExtractionProtocolGuid ## CONSUMES

View File

@ -1,7 +1,7 @@
/** @file
Implements functions to read firmware file.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -100,7 +100,6 @@ FvGetNextFile (
UINTN *KeyValue;
LIST_ENTRY *Link;
FFS_FILE_LIST_ENTRY *FfsFileEntry;
UINTN FileLength;
FvDevice = FV_DEVICE_FROM_THIS (This);
@ -202,12 +201,14 @@ FvGetNextFile (
CopyGuid (NameGuid, &FfsFileHeader->Name);
*Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
FileLength = *(UINT32 *) FfsFileHeader->Size & 0x00FFFFFF;
//
// we need to substract the header size
//
*Size = FileLength - sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FfsFileHeader)) {
*Size = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
} else {
*Size = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
}
if (CompareGuid (&gEfiFirmwareVolumeTopFileGuid, NameGuid)) {
//
@ -216,8 +217,11 @@ FvGetNextFile (
UINT8 *SrcPtr;
UINT32 Tmp;
SrcPtr = (UINT8 *) FfsFileHeader;
SrcPtr += sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FfsFileHeader)) {
SrcPtr = ((UINT8 *) FfsFileHeader) + sizeof (EFI_FFS_FILE_HEADER2);
} else {
SrcPtr = ((UINT8 *) FfsFileHeader) + sizeof (EFI_FFS_FILE_HEADER);
}
while (*Size >= 4) {
Tmp = *(UINT32 *) SrcPtr;
@ -362,8 +366,11 @@ FvReadFile (
//
// Get File Size of the cached file
//
FileSize = *(UINT32 *) FfsHeader->Size & 0x00FFFFFF;
FileSize -= sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FfsHeader)) {
FileSize = FFS_FILE2_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER2);
} else {
FileSize = FFS_FILE_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER);
}
}
//
// Get file info
@ -380,8 +387,11 @@ FvReadFile (
return EFI_SUCCESS;
}
SrcPtr = (UINT8 *) FfsHeader;
SrcPtr += sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FfsHeader)) {
SrcPtr = ((UINT8 *) FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);
} else {
SrcPtr = ((UINT8 *) FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
}
if (CompareGuid (&gEfiFirmwareVolumeTopFileGuid, NameGuid)) {
//

View File

@ -28,7 +28,6 @@ SetHeaderChecksum (
)
{
EFI_FFS_FILE_STATE State;
UINT8 HeaderChecksum;
UINT8 FileChecksum;
//
@ -42,12 +41,17 @@ SetHeaderChecksum (
FfsHeader->IntegrityCheck.Checksum.Header = 0;
HeaderChecksum = CalculateSum8 (
(UINT8 *)FfsHeader,
sizeof (EFI_FFS_FILE_HEADER)
);
FfsHeader->IntegrityCheck.Checksum.Header = (UINT8) (~HeaderChecksum + 1);
if (IS_FFS_FILE2 (FfsHeader)) {
FfsHeader->IntegrityCheck.Checksum.Header = CalculateCheckSum8 (
(UINT8 *) FfsHeader,
sizeof (EFI_FFS_FILE_HEADER2)
);
} else {
FfsHeader->IntegrityCheck.Checksum.Header = CalculateCheckSum8 (
(UINT8 *) FfsHeader,
sizeof (EFI_FFS_FILE_HEADER)
);
}
FfsHeader->State = State;
FfsHeader->IntegrityCheck.Checksum.File = FileChecksum;
@ -68,29 +72,21 @@ SetFileChecksum (
IN UINTN ActualFileSize
)
{
EFI_FFS_FILE_STATE State;
UINT8 FileChecksum;
if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) {
//
// The file state is not included
//
State = FfsHeader->State;
FfsHeader->State = 0;
FfsHeader->IntegrityCheck.Checksum.File = 0;
//
// File checksum
//
FileChecksum = CalculateSum8 (
(UINT8 *)(FfsHeader + 1),
ActualFileSize - sizeof (EFI_FFS_FILE_HEADER)
);
FfsHeader->IntegrityCheck.Checksum.File = (UINT8) (~FileChecksum + 1);
FfsHeader->State = State;
if (IS_FFS_FILE2 (FfsHeader)) {
FfsHeader->IntegrityCheck.Checksum.File = CalculateCheckSum8 (
(UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2),
ActualFileSize - sizeof (EFI_FFS_FILE_HEADER2)
);
} else {
FfsHeader->IntegrityCheck.Checksum.File = CalculateCheckSum8 (
(UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER),
ActualFileSize - sizeof (EFI_FFS_FILE_HEADER)
);
}
} else {
@ -138,6 +134,7 @@ GetRequiredAlignment (
@param FvDevice Cached Firmware Volume.
@param StartAddress The starting address to write the FFS File.
@param BufferSize The FFS File Buffer Size.
@param RequiredAlignment FFS File Data alignment requirement.
@return The required Pad File Size.
@ -147,6 +144,7 @@ UINTN
CaculatePadFileSize (
IN FV_DEVICE *FvDevice,
IN EFI_PHYSICAL_ADDRESS StartAddress,
IN UINTN BufferSize,
IN UINTN RequiredAlignment
)
{
@ -154,7 +152,11 @@ CaculatePadFileSize (
UINTN RelativePos;
UINTN PadSize;
DataStartPos = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER);
if (BufferSize > 0x00FFFFFF) {
DataStartPos = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER2);
} else {
DataStartPos = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER);
}
RelativePos = DataStartPos - (UINTN) FvDevice->CachedFv;
PadSize = 0;
@ -331,6 +333,7 @@ FvLocateFreeSpaceEntry (
PadFileSize = CaculatePadFileSize (
FvDevice,
(EFI_PHYSICAL_ADDRESS) (UINTN) FreeSpaceListEntry->StartingAddress,
Size,
RequiredAlignment
);
if (FreeSpaceListEntry->Length >= Size + PadFileSize) {
@ -346,54 +349,6 @@ FvLocateFreeSpaceEntry (
}
/**
Locate a free space that can hold this file.
@param FvDevice Cached Firmware Volume.
@param Size On input, it is the required size.
On output, it is the actual size of free space.
@param RequiredAlignment FFS File Data alignment requirement.
@param PadSize Pointer to the size of leading Pad File.
@param StartingAddress The starting address of the Free Space Entry
that meets the requirement.
@retval EFI_SUCCESS The free space is found.
@retval EFI_NOT_FOUND The free space can't be found.
**/
EFI_STATUS
FvLocateFreeSpace (
IN FV_DEVICE *FvDevice,
IN OUT UINTN *Size,
IN UINTN RequiredAlignment,
OUT UINTN *PadSize,
OUT EFI_PHYSICAL_ADDRESS *StartingAddress
)
{
EFI_STATUS Status;
FREE_SPACE_ENTRY *FreeSpaceEntry;
//
// First find the free space entry
//
Status = FvLocateFreeSpaceEntry (
FvDevice,
*Size,
RequiredAlignment,
PadSize,
&FreeSpaceEntry
);
if (EFI_ERROR (Status)) {
return Status;
}
*Size = FreeSpaceEntry->Length;
*StartingAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) FreeSpaceEntry->StartingAddress;
return EFI_SUCCESS;
}
/**
Locate Pad File for writing, this is got from FV Cache.
@ -419,9 +374,9 @@ FvLocatePadFile (
FFS_FILE_LIST_ENTRY *FileEntry;
EFI_FFS_FILE_STATE FileState;
EFI_FFS_FILE_HEADER *FileHeader;
UINTN FileLength;
UINTN PadAreaLength;
UINTN PadFileSize;
UINTN HeaderSize;
FileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink;
@ -437,12 +392,18 @@ FvLocatePadFile (
//
// we find one valid pad file, check its free area length
//
FileLength = *(UINT32 *) FileHeader->Size & 0x00FFFFFF;
PadAreaLength = FileLength - sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FileHeader)) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
PadAreaLength = FFS_FILE2_SIZE (FileHeader) - HeaderSize;
} else {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
PadAreaLength = FFS_FILE_SIZE (FileHeader) - HeaderSize;
}
PadFileSize = CaculatePadFileSize (
FvDevice,
(EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER),
(EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + HeaderSize,
Size,
RequiredAlignment
);
if (PadAreaLength >= (Size + PadFileSize)) {
@ -487,10 +448,10 @@ FvSearchSuitablePadFile (
FFS_FILE_LIST_ENTRY *FileEntry;
EFI_FFS_FILE_STATE FileState;
EFI_FFS_FILE_HEADER *FileHeader;
UINTN FileLength;
UINTN PadAreaLength;
UINTN TotalSize;
UINTN Index;
UINTN HeaderSize;
FileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink;
@ -506,14 +467,20 @@ FvSearchSuitablePadFile (
//
// we find one valid pad file, check its length
//
FileLength = *(UINT32 *) FileHeader->Size & 0x00FFFFFF;
PadAreaLength = FileLength - sizeof (EFI_FFS_FILE_HEADER);
if (IS_FFS_FILE2 (FileHeader)) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
PadAreaLength = FFS_FILE2_SIZE (FileHeader) - HeaderSize;
} else {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
PadAreaLength = FFS_FILE_SIZE (FileHeader) - HeaderSize;
}
TotalSize = 0;
for (Index = 0; Index < NumOfFiles; Index++) {
PadSize[Index] = CaculatePadFileSize (
FvDevice,
(EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER) + TotalSize,
(EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + HeaderSize + TotalSize,
BufferSize[Index],
RequiredAlignment[Index]
);
TotalSize += PadSize[Index];
@ -589,6 +556,7 @@ FvSearchSuitableFreeSpace (
PadSize[Index] = CaculatePadFileSize (
FvDevice,
(EFI_PHYSICAL_ADDRESS) (UINTN) StartAddr + TotalSize,
BufferSize[Index],
RequiredAlignment[Index]
);
@ -803,6 +771,7 @@ FvCreateNewFile (
FFS_FILE_LIST_ENTRY *PadFileEntry;
EFI_FFS_FILE_ATTRIBUTES TmpFileAttribute;
FFS_FILE_LIST_ENTRY *FfsFileEntry;
UINTN HeaderSize;
//
// File Type: 0x0E~0xE0 are reserved
@ -869,6 +838,11 @@ FvCreateNewFile (
// Write Name, IntegrityCheck.Header, Type, Attributes, and Size
//
FileHeader = (EFI_FFS_FILE_HEADER *) FfsFileBuffer;
if (ActualFileSize > 0x00FFFFFF) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
} else {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
}
SetFileState (EFI_FILE_HEADER_CONSTRUCTION, FileHeader);
Offset = (UINTN) (BufferPtr - FvDevice->CachedFv);
@ -890,14 +864,14 @@ FvCreateNewFile (
CopyMem (
(UINT8 *) (UINTN) BufferPtr,
FileHeader,
sizeof (EFI_FFS_FILE_HEADER)
HeaderSize
);
//
// update Free Space Entry, now need to substract the EFI_FFS_FILE_HEADER
// update Free Space Entry, now need to substract the file header length
//
FreeSpaceEntry->StartingAddress += sizeof (EFI_FFS_FILE_HEADER);
FreeSpaceEntry->Length -= sizeof (EFI_FFS_FILE_HEADER);
FreeSpaceEntry->StartingAddress += HeaderSize;
FreeSpaceEntry->Length -= HeaderSize;
CopyGuid (&FileHeader->Name, FileName);
FileHeader->Type = FileType;
@ -912,14 +886,20 @@ FvCreateNewFile (
//
// File size is including the FFS File Header.
//
*(UINT32 *) FileHeader->Size &= 0xFF000000;
*(UINT32 *) FileHeader->Size |= ActualFileSize;
if (ActualFileSize > 0x00FFFFFF) {
((EFI_FFS_FILE_HEADER2 *) FileHeader)->ExtendedSize = (UINT32) ActualFileSize;
*(UINT32 *) FileHeader->Size &= 0xFF000000;
FileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE;
} else {
*(UINT32 *) FileHeader->Size &= 0xFF000000;
*(UINT32 *) FileHeader->Size |= ActualFileSize;
}
SetHeaderChecksum (FileHeader);
Offset = (UINTN) (BufferPtr - FvDevice->CachedFv);
NumBytesWritten = sizeof (EFI_FFS_FILE_HEADER);
NumBytesWritten = HeaderSize;
Status = FvcWrite (
FvDevice,
Offset,
@ -935,7 +915,7 @@ FvCreateNewFile (
CopyMem (
(UINT8 *) (UINTN) BufferPtr,
FileHeader,
sizeof (EFI_FFS_FILE_HEADER)
HeaderSize
);
//
@ -966,14 +946,14 @@ FvCreateNewFile (
CopyMem (
(UINT8 *) (UINTN) BufferPtr,
FileHeader,
sizeof (EFI_FFS_FILE_HEADER)
HeaderSize
);
//
// update Free Space Entry, now need to substract the file data length
//
FreeSpaceEntry->StartingAddress += (BufferSize - sizeof (EFI_FFS_FILE_HEADER));
FreeSpaceEntry->Length -= (BufferSize - sizeof (EFI_FFS_FILE_HEADER));
FreeSpaceEntry->StartingAddress += (BufferSize - HeaderSize);
FreeSpaceEntry->Length -= (BufferSize - HeaderSize);
//
// Caculate File Checksum
@ -1025,7 +1005,7 @@ FvCreateNewFile (
CopyMem (
(UINT8 *) (UINTN) BufferPtr,
FileHeader,
sizeof (EFI_FFS_FILE_HEADER)
HeaderSize
);
//
@ -1381,6 +1361,7 @@ FvWriteFile (
UINTN NumDelete;
EFI_FV_ATTRIBUTES FvAttributes;
UINT32 AuthenticationStatus;
UINTN HeaderSize;
if (NumberOfFiles > MAX_FILES) {
return EFI_UNSUPPORTED;
@ -1416,6 +1397,15 @@ FvWriteFile (
//
NumDelete = 0;
for (Index1 = 0; Index1 < NumberOfFiles; Index1++) {
if ((FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER) > 0x00FFFFFF) && !FvDevice->IsFfs3Fv) {
//
// Found a file needs a FFS3 formatted file to store it, but it is in a non-FFS3 formatted FV.
//
DEBUG ((EFI_D_ERROR, "FFS3 formatted file can't be written in a non-FFS3 formatted FV.\n"));
return EFI_INVALID_PARAMETER;
}
if (FileData[Index1].BufferSize == 0) {
//
// Here we will delete this file
@ -1525,7 +1515,12 @@ FvWriteFile (
//
// Making Buffersize QWORD boundry, and add file tail.
//
ActualSize = FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER);
HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
ActualSize = FileData[Index1].BufferSize + HeaderSize;
if (ActualSize > 0x00FFFFFF) {
HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
ActualSize = FileData[Index1].BufferSize + HeaderSize;
}
BufferSize = ActualSize;
while ((BufferSize & 0x07) != 0) {
@ -1540,7 +1535,7 @@ FvWriteFile (
// Copy File Data into FileBuffer
//
CopyMem (
FileBuffer + sizeof (EFI_FFS_FILE_HEADER),
FileBuffer + HeaderSize,
FileData[Index1].Buffer,
FileData[Index1].BufferSize
);
@ -1549,7 +1544,7 @@ FvWriteFile (
//
// Fill the file header and padding byte with Erase Byte
//
for (Index2 = 0; Index2 < sizeof (EFI_FFS_FILE_HEADER); Index2++) {
for (Index2 = 0; Index2 < HeaderSize; Index2++) {
FileBuffer[Index2] = (UINT8)~FileBuffer[Index2];
}

View File

@ -27,7 +27,7 @@
3) A support protocol is not found, and the data is not available to be read
without it. This results in EFI_PROTOCOL_ERROR.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
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
@ -278,7 +278,11 @@ IsValidSectionStream (
SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream;
while (TotalLength < SectionStreamLength) {
SectionLength = SECTION_SIZE (SectionHeader);
if (IS_SECTION2 (SectionHeader)) {
SectionLength = SECTION2_SIZE (SectionHeader);
} else {
SectionLength = SECTION_SIZE (SectionHeader);
}
TotalLength += SectionLength;
if (TotalLength == SectionStreamLength) {
@ -462,7 +466,11 @@ ChildIsType (
return TRUE;
}
GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream);
return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);
if (IS_SECTION2 (GuidedSection)) {
return CompareGuid (&(((EFI_GUID_DEFINED_SECTION2 *) GuidedSection)->SectionDefinitionGuid), SectionDefinitionGuid);
} else {
return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);
}
}
/**
@ -580,7 +588,7 @@ NotifyGuidedExtraction (
);
ASSERT_EFI_ERROR (Status);
//
// OR in the parent stream's aggregagate status.
// OR in the parent stream's aggregate status.
//
AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;
Status = OpenSectionStreamEx (
@ -674,7 +682,11 @@ CreateChildNode (
UINT32 ScratchSize;
UINTN NewStreamBufferSize;
UINT32 AuthenticationStatus;
UINT32 SectionLength;
VOID *CompressionSource;
UINT32 CompressionSourceSize;
UINT32 UncompressedLength;
UINT8 CompressionType;
UINT16 GuidedSectionAttributes;
FRAMEWORK_SECTION_CHILD_NODE *Node;
@ -694,7 +706,11 @@ CreateChildNode (
//
Node->Signature = FRAMEWORK_SECTION_CHILD_SIGNATURE;
Node->Type = SectionHeader->Type;
Node->Size = SECTION_SIZE (SectionHeader);
if (IS_SECTION2 (SectionHeader)) {
Node->Size = SECTION2_SIZE (SectionHeader);
} else {
Node->Size = SECTION_SIZE (SectionHeader);
}
Node->OffsetInStream = ChildOffset;
Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE;
Node->EncapsulationGuid = NULL;
@ -710,24 +726,36 @@ CreateChildNode (
ASSERT (Node->Size >= sizeof (EFI_COMPRESSION_SECTION));
CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader;
if (IS_SECTION2 (CompressionHeader)) {
CompressionSource = (VOID *) ((UINT8 *) CompressionHeader + sizeof (EFI_COMPRESSION_SECTION2));
CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionHeader) - sizeof (EFI_COMPRESSION_SECTION2));
UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionHeader)->UncompressedLength;
CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionHeader)->CompressionType;
} else {
CompressionSource = (VOID *) ((UINT8 *) CompressionHeader + sizeof (EFI_COMPRESSION_SECTION));
CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionHeader) - sizeof (EFI_COMPRESSION_SECTION));
UncompressedLength = CompressionHeader->UncompressedLength;
CompressionType = CompressionHeader->CompressionType;
}
//
// Allocate space for the new stream
//
if (CompressionHeader->UncompressedLength > 0) {
NewStreamBufferSize = CompressionHeader->UncompressedLength;
if (UncompressedLength > 0) {
NewStreamBufferSize = UncompressedLength;
NewStreamBuffer = AllocatePool (NewStreamBufferSize);
if (NewStreamBuffer == NULL) {
FreePool (Node);
return EFI_OUT_OF_RESOURCES;
}
if (CompressionHeader->CompressionType == EFI_NOT_COMPRESSED) {
if (CompressionType == EFI_NOT_COMPRESSED) {
//
// stream is not actually compressed, just encapsulated. So just copy it.
//
CopyMem (NewStreamBuffer, CompressionHeader + 1, NewStreamBufferSize);
} else if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION) {
CopyMem (NewStreamBuffer, CompressionSource, NewStreamBufferSize);
} else if (CompressionType == EFI_STANDARD_COMPRESSION) {
//
// Only support the EFI_SATNDARD_COMPRESSION algorithm.
//
@ -741,13 +769,13 @@ CreateChildNode (
Status = Decompress->GetInfo (
Decompress,
CompressionHeader + 1,
Node->Size - sizeof (EFI_COMPRESSION_SECTION),
CompressionSource,
CompressionSourceSize,
(UINT32 *)&NewStreamBufferSize,
&ScratchSize
);
ASSERT_EFI_ERROR (Status);
ASSERT (NewStreamBufferSize == CompressionHeader->UncompressedLength);
ASSERT (NewStreamBufferSize == UncompressedLength);
ScratchBuffer = AllocatePool (ScratchSize);
if (ScratchBuffer == NULL) {
@ -758,8 +786,8 @@ CreateChildNode (
Status = Decompress->Decompress (
Decompress,
CompressionHeader + 1,
Node->Size - sizeof (EFI_COMPRESSION_SECTION),
CompressionSource,
CompressionSourceSize,
NewStreamBuffer,
(UINT32)NewStreamBufferSize,
ScratchBuffer,
@ -789,7 +817,13 @@ CreateChildNode (
case EFI_SECTION_GUID_DEFINED:
GuidedHeader = (EFI_GUID_DEFINED_SECTION *) SectionHeader;
Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;
if (IS_SECTION2 (GuidedHeader)) {
Node->EncapsulationGuid = &(((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->SectionDefinitionGuid);
GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->Attributes;
} else {
Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;
GuidedSectionAttributes = GuidedHeader->Attributes;
}
Status = gBS->LocateProtocol (Node->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);
if (!EFI_ERROR (Status)) {
//
@ -812,7 +846,7 @@ CreateChildNode (
// Make sure we initialize the new stream with the correct
// authentication status for both aggregate and local status fields.
//
if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
//
// OR in the parent stream's aggregate status.
//
@ -841,7 +875,7 @@ CreateChildNode (
//
// There's no GUIDed section extraction protocol available.
//
if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == EFI_GUIDED_SECTION_PROCESSING_REQUIRED) {
if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == EFI_GUIDED_SECTION_PROCESSING_REQUIRED) {
//
// If the section REQUIRES an extraction protocol, register for RPN
// when the required GUIDed extraction protocol becomes available.
@ -853,7 +887,7 @@ CreateChildNode (
// Figure out the proper authentication status
//
AuthenticationStatus = Stream->AuthenticationStatus;
if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
//
// The local status of the new stream is contained in
// AuthenticaionStatus. This value needs to be ORed into the
@ -871,14 +905,23 @@ CreateChildNode (
AuthenticationStatus |= AuthenticationStatus >> 16;
}
SectionLength = SECTION_SIZE (GuidedHeader);
Status = OpenSectionStreamEx (
SectionLength - GuidedHeader->DataOffset,
(UINT8 *) GuidedHeader + GuidedHeader->DataOffset,
TRUE,
AuthenticationStatus,
&Node->EncapsulatedStreamHandle
);
if (IS_SECTION2 (GuidedHeader)) {
Status = OpenSectionStreamEx (
SECTION2_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset,
(UINT8 *) GuidedHeader + ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset,
TRUE,
AuthenticationStatus,
&Node->EncapsulatedStreamHandle
);
} else {
Status = OpenSectionStreamEx (
SECTION_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION *) GuidedHeader)->DataOffset,
(UINT8 *) GuidedHeader + ((EFI_GUID_DEFINED_SECTION *) GuidedHeader)->DataOffset,
TRUE,
AuthenticationStatus,
&Node->EncapsulatedStreamHandle
);
}
if (EFI_ERROR (Status)) {
FreePool (Node);
return Status;
@ -1177,6 +1220,7 @@ GetSection (
UINTN Instance;
UINT8 *CopyBuffer;
UINTN SectionSize;
EFI_COMMON_SECTION_HEADER *Section;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
@ -1219,8 +1263,15 @@ GetSection (
}
ASSERT (ChildNode != NULL);
ASSERT (ChildStreamNode != NULL);
CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER);
CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER);
Section = (EFI_COMMON_SECTION_HEADER *) (ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream);
if (IS_SECTION2 (Section)) {
CopySize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
CopyBuffer = (UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2);
} else {
CopySize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
CopyBuffer = (UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER);
}
*AuthenticationStatus = ExtractedAuthenticationStatus;
}