From b279ac9f36e1b386c8c8a761657c6e6d0f1dfa1d Mon Sep 17 00:00:00 2001 From: Phil Noh Date: Thu, 6 Mar 2025 14:15:35 -0600 Subject: BaseTools/GenFv: Ensure the minimum pad file size for the FV with VTF In case of the FV with VTF, the left size should be enough to add the minimum pad file size (EFI_FFS_FILE_HEADER, 0x18). It prevents the build error, "GenFv: ERROR 0006: invalid FFS file header checksum" caused by the pad file overwriting some header data in VTF. This includes these updates for CalculateFvSize() function. 1. If NumBlocks is not defined, ensure the minimum pad file size for the left size (if the pad file is required as VTF is not bottom aligned at end of block, insert EFI_FFS_FILE_HEADER to ensure the pad file size) 2. If NumBlocks is defined, report more clear error message (the required fv image size = 0x%x. the set fv image size = 0x%x. Free space left is not enough to add a pad file (0x18)) 3. Remove MaxPadFileSize, which is reported when the taken size is same as the total size. It can not be the actual left size to add an FFS file. It causes confusion when referring to the build log (FV Space Information) Signed-off-by: Phil Noh --- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 43 +++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'BaseTools/Source') diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 3f982c5..44be413 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3153,7 +3153,6 @@ Returns: --*/ { UINTN CurrentOffset; - UINTN OrigOffset; UINTN Index; FILE *fpin; UINTN FfsFileSize; @@ -3162,11 +3161,11 @@ Returns: UINT32 FfsHeaderSize; EFI_FFS_FILE_HEADER FfsHeader; UINTN VtfFileSize; - UINTN MaxPadFileSize; + UINTN VtfPadSize; FvExtendHeaderSize = 0; - MaxPadFileSize = 0; VtfFileSize = 0; + VtfPadSize = 0; fpin = NULL; Index = 0; @@ -3274,12 +3273,8 @@ Returns: // // Only EFI_FFS_FILE_HEADER is needed for a pad section. // - OrigOffset = CurrentOffset; CurrentOffset = (CurrentOffset + FfsHeaderSize + sizeof(EFI_FFS_FILE_HEADER) + FfsAlignment - 1) & ~(FfsAlignment - 1); CurrentOffset -= FfsHeaderSize; - if ((CurrentOffset - OrigOffset) > MaxPadFileSize) { - MaxPadFileSize = CurrentOffset - OrigOffset; - } } } @@ -3304,9 +3299,18 @@ Returns: if (FvInfoPtr->Size == 0) { // + // Vtf file should be bottom aligned at end of block. + // If it is not aligned, insert EFI_FFS_FILE_HEADER to ensure the minimum pad file size for left space. + // + if ((VtfFileSize > 0) && (CurrentOffset % FvInfoPtr->FvBlocks[0].Length)) { + VtfPadSize = sizeof (EFI_FFS_FILE_HEADER); + } + + // // Update FvInfo data // - FvInfoPtr->FvBlocks[0].NumBlocks = CurrentOffset / FvInfoPtr->FvBlocks[0].Length + ((CurrentOffset % FvInfoPtr->FvBlocks[0].Length)?1:0); + FvInfoPtr->FvBlocks[0].NumBlocks = ((CurrentOffset + VtfPadSize) / FvInfoPtr->FvBlocks[0].Length) + + (((CurrentOffset + VtfPadSize) % FvInfoPtr->FvBlocks[0].Length) ? 1 : 0); FvInfoPtr->Size = FvInfoPtr->FvBlocks[0].NumBlocks * FvInfoPtr->FvBlocks[0].Length; FvInfoPtr->FvBlocks[1].NumBlocks = 0; FvInfoPtr->FvBlocks[1].Length = 0; @@ -3316,6 +3320,23 @@ Returns: // Error (NULL, 0, 3000, "Invalid", "the required fv image size 0x%x exceeds the set fv image size 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size); return EFI_INVALID_PARAMETER; + } else if ((VtfFileSize > 0) && + (FvInfoPtr->Size > CurrentOffset) && + ((FvInfoPtr->Size - CurrentOffset) < sizeof (EFI_FFS_FILE_HEADER))) + { + // + // Not invalid + // + Error ( + NULL, + 0, + 3000, + "Invalid", + "the required fv image size = 0x%x. the set fv image size = 0x%x. Free space left is not enough to add a pad file (0x18)", + (unsigned)CurrentOffset, + (unsigned)FvInfoPtr->Size + ); + return EFI_INVALID_PARAMETER; } // @@ -3323,12 +3344,6 @@ Returns: // mFvTotalSize = FvInfoPtr->Size; mFvTakenSize = CurrentOffset; - if ((mFvTakenSize == mFvTotalSize) && (MaxPadFileSize > 0)) { - // - // This FV means TOP FFS has been taken. Then, check whether there is padding data for use. - // - mFvTakenSize = mFvTakenSize - MaxPadFileSize; - } return EFI_SUCCESS; } -- cgit v1.1