diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-07-27 13:50:19 +0000 |
---|---|---|
committer | abiesheuvel <abiesheuvel@Edk2> | 2015-07-27 13:50:19 +0000 |
commit | 46d0f3f871420269de54dc495e43872fcdd83f86 (patch) | |
tree | 31bc1891afdc976a707202906d20f7dbd1f355e4 /BaseTools/Source | |
parent | 02a5421f57cd76daf2544ecd2b35ea0d4d65337a (diff) | |
download | edk2-platforms-46d0f3f871420269de54dc495e43872fcdd83f86.tar.xz |
BaseTools: use GUID identifiable section for FFS alignment padding
Instead of using an anonymous section of type EFI_SECTION_RAW to pad
out the first aligned FFS section to its required alignment, use a
section with a dedicated GUID if the size of the padding permits it.
This allows for more flexibility when placing such FFS images in a
firmware volume, because we will now be able to remove padding rather
than add more, by shrinking the size of this section instead of
padding out the start of the FFS image to file alignment.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18079 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source')
-rw-r--r-- | BaseTools/Source/C/GenFfs/GenFfs.c | 99 | ||||
-rw-r--r-- | BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h | 22 |
2 files changed, 84 insertions, 37 deletions
diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index 52092e36e7..433b608cb9 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Common/UefiBaseTypes.h>
#include <Common/PiFirmwareFile.h>
#include <IndustryStandard/PeImage.h>
+#include <Guid/FfsSectionAlignmentPadding.h>
#include "CommonLib.h"
#include "ParseInf.h"
@@ -58,6 +59,8 @@ STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536}; STATIC EFI_GUID mZeroGuid = {0};
+STATIC EFI_GUID mEfiFfsSectionAlignmentPaddingGuid = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;
+
STATIC
VOID
Version (
@@ -230,13 +233,14 @@ Returns: STATIC
EFI_STATUS
GetSectionContents (
- IN CHAR8 **InputFileName,
- IN UINT32 *InputFileAlign,
- IN UINT32 InputFileNum,
- OUT UINT8 *FileBuffer,
- OUT UINT32 *BufferLength,
- OUT UINT32 *MaxAlignment,
- OUT UINT8 *PESectionNum
+ IN CHAR8 **InputFileName,
+ IN UINT32 *InputFileAlign,
+ IN UINT32 InputFileNum,
+ IN EFI_FFS_FILE_ATTRIBUTES FfsAttrib,
+ OUT UINT8 *FileBuffer,
+ OUT UINT32 *BufferLength,
+ OUT UINT32 *MaxAlignment,
+ OUT UINT8 *PESectionNum
)
/*++
@@ -270,22 +274,24 @@ Returns: EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
--*/
{
- UINT32 Size;
- UINT32 Offset;
- UINT32 FileSize;
- UINT32 Index;
- FILE *InFile;
- EFI_COMMON_SECTION_HEADER *SectHeader;
- EFI_COMMON_SECTION_HEADER2 TempSectHeader;
- EFI_TE_IMAGE_HEADER TeHeader;
- UINT32 TeOffset;
- EFI_GUID_DEFINED_SECTION GuidSectHeader;
- EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
- UINT32 HeaderSize;
-
- Size = 0;
- Offset = 0;
- TeOffset = 0;
+ UINT32 Size;
+ UINT32 Offset;
+ UINT32 FileSize;
+ UINT32 Index;
+ FILE *InFile;
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION *SectHeader;
+ EFI_COMMON_SECTION_HEADER2 TempSectHeader;
+ EFI_TE_IMAGE_HEADER TeHeader;
+ UINT32 TeOffset;
+ EFI_GUID_DEFINED_SECTION GuidSectHeader;
+ EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
+ UINT32 HeaderSize;
+ UINT32 MaxEncounteredAlignment;
+
+ Size = 0;
+ Offset = 0;
+ TeOffset = 0;
+ MaxEncounteredAlignment = 1;
//
// Go through our array of file names and copy their contents
@@ -299,13 +305,6 @@ Returns: Size++;
}
- //
- // Get the Max alignment of all input file datas
- //
- if (*MaxAlignment < InputFileAlign [Index]) {
- *MaxAlignment = InputFileAlign [Index];
- }
-
//
// Open file and read contents
//
@@ -373,7 +372,7 @@ Returns: }
//
- // make sure section data meet its alignment requirement by adding one raw pad section.
+ // make sure section data meet its alignment requirement by adding one pad section.
// But the different sections have the different section header. Necessary or not?
// Based on section type to adjust offset? Todo
//
@@ -386,11 +385,26 @@ Returns: // The maximal alignment is 64K, the raw section size must be less than 0xffffff
//
memset (FileBuffer + Size, 0, Offset);
- SectHeader = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);
- SectHeader->Type = EFI_SECTION_RAW;
- SectHeader->Size[0] = (UINT8) (Offset & 0xff);
- SectHeader->Size[1] = (UINT8) ((Offset & 0xff00) >> 8);
- SectHeader->Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);
+ SectHeader = (EFI_FREEFORM_SUBTYPE_GUID_SECTION *) (FileBuffer + Size);
+ SectHeader->CommonHeader.Size[0] = (UINT8) (Offset & 0xff);
+ SectHeader->CommonHeader.Size[1] = (UINT8) ((Offset & 0xff00) >> 8);
+ SectHeader->CommonHeader.Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);
+
+ //
+ // Only add a special reducible padding section if
+ // - this FFS has the FFS_ATTRIB_FIXED attribute,
+ // - none of the preceding sections have alignment requirements,
+ // - the size of the padding is sufficient for the
+ // EFI_SECTION_FREEFORM_SUBTYPE_GUID header.
+ //
+ if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0 &&
+ MaxEncounteredAlignment <= 1 &&
+ Offset >= sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION)) {
+ SectHeader->CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID;
+ SectHeader->SubTypeGuid = mEfiFfsSectionAlignmentPaddingGuid;
+ } else {
+ SectHeader->CommonHeader.Type = EFI_SECTION_RAW;
+ }
}
DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment",
"Pad Raw section size is %u", (unsigned) Offset);
@@ -399,6 +413,13 @@ Returns: }
//
+ // Get the Max alignment of all input file datas
+ //
+ if (MaxEncounteredAlignment < InputFileAlign [Index]) {
+ MaxEncounteredAlignment = InputFileAlign [Index];
+ }
+
+ //
// Now read the contents of the file into the buffer
// Buffer must be enough to contain the file content.
//
@@ -413,7 +434,9 @@ Returns: fclose (InFile);
Size += FileSize;
}
-
+
+ *MaxAlignment = MaxEncounteredAlignment;
+
//
// Set the actual length of the data.
//
@@ -774,6 +797,7 @@ Returns: InputFileName,
InputFileAlign,
InputFileNum,
+ FfsAttrib,
FileBuffer,
&FileSize,
&MaxAlignment,
@@ -810,6 +834,7 @@ Returns: InputFileName,
InputFileAlign,
InputFileNum,
+ FfsAttrib,
FileBuffer,
&FileSize,
&MaxAlignment,
diff --git a/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h b/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h new file mode 100644 index 0000000000..0ad9d8ce0e --- /dev/null +++ b/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h @@ -0,0 +1,22 @@ +/** @file
+ Copyright (c) 2015, Linaro Ltd. 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
+ 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.
+
+**/
+
+#ifndef __FFS_SECTION_ALIGNMENT_PADDING_GUID_H__
+#define __FFS_SECTION_ALIGNMENT_PADDING_GUID_H__
+
+#define EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID \
+ { \
+ 0x04132C8D, 0x0A22, 0x4FA8, {0x82, 0x6E, 0x8B, 0xBF, 0xEF, 0xDB, 0x83, 0x6C } \
+ }
+
+#endif
|