diff --git a/BootloaderCommonPkg/Include/Library/MultibootLib.h b/BootloaderCommonPkg/Include/Library/MultibootLib.h index 60575a71..185cc732 100644 --- a/BootloaderCommonPkg/Include/Library/MultibootLib.h +++ b/BootloaderCommonPkg/Include/Library/MultibootLib.h @@ -296,6 +296,20 @@ SetupMultibootInfo ( IN OUT MULTIBOOT_IMAGE *MultiBoot ); +/** + Align multiboot modules if requested by header. + + @param[in,out] MultiBoot Point to loaded Multiboot image structure + + @retval RETURN_SUCCESS Align modules successfully + @retval Others There is error when align image +**/ +EFI_STATUS +EFIAPI +CheckAndAlignMultibootModules ( + IN OUT MULTIBOOT_IMAGE *MultiBoot + ); + /** ASM inline function that goes from payload to a Multiboot enabled OS. @param[in] State Boot state structure @@ -346,6 +360,20 @@ SetupMultiboot2Info ( IN OUT MULTIBOOT_IMAGE *MultiBoot ); +/** + Align multiboot modules if requested by module alignment tag. + + @param[in,out] MultiBoot Point to loaded Multiboot image structure + + @retval RETURN_SUCCESS Align modules successfully + @retval Others There is error when align image +**/ +EFI_STATUS +EFIAPI +CheckAndAlignMultiboot2Modules ( + IN OUT MULTIBOOT_IMAGE *MultiBoot + ); + /** Update the memory info inside the Multiboot-2 info. diff --git a/BootloaderCommonPkg/Library/MultibootLib/Multiboot.c b/BootloaderCommonPkg/Library/MultibootLib/Multiboot.c index 8e5d1a2c..2d1d93a2 100644 --- a/BootloaderCommonPkg/Library/MultibootLib/Multiboot.c +++ b/BootloaderCommonPkg/Library/MultibootLib/Multiboot.c @@ -346,6 +346,41 @@ AlignMultibootModules ( return RETURN_SUCCESS; } +/** + Align multiboot modules if requested by header. + + @param[in,out] MultiBoot Point to loaded Multiboot image structure + + @retval RETURN_SUCCESS Align modules successfully + @retval Others There is error when align image +**/ +EFI_STATUS +EFIAPI +CheckAndAlignMultibootModules ( + IN OUT MULTIBOOT_IMAGE *MultiBoot + ) +{ + EFI_STATUS Status; + CONST MULTIBOOT_HEADER *MbHeader; + + if (MultiBoot == NULL) { + return RETURN_INVALID_PARAMETER; + } + + MbHeader = GetMultibootHeader (MultiBoot->BootFile.Addr); + if (MbHeader == NULL) { + return RETURN_LOAD_ERROR; + } + + if ((MbHeader->Flags & MULTIBOOT_HEADER_MODS_ALIGNED) != 0) { + // Modules should be page (4KB) aligned + Status = AlignMultibootModules (MultiBoot); + if (EFI_ERROR (Status)) { + return Status; + } + } + return EFI_SUCCESS; +} /** Setup Multiboot image and its boot info. diff --git a/BootloaderCommonPkg/Library/MultibootLib/Multiboot2.c b/BootloaderCommonPkg/Library/MultibootLib/Multiboot2.c index 7d113559..f17ee6c7 100644 --- a/BootloaderCommonPkg/Library/MultibootLib/Multiboot2.c +++ b/BootloaderCommonPkg/Library/MultibootLib/Multiboot2.c @@ -423,6 +423,54 @@ ParseMultiboot2Header ( return (tags_needed ? RETURN_UNSUPPORTED : RETURN_SUCCESS); } +/** + Align multiboot modules if requested by module alignment tag. + + @param[in,out] MultiBoot Point to loaded Multiboot image structure + + @retval RETURN_SUCCESS Align modules successfully + @retval Others There is error when align image +**/ +EFI_STATUS +EFIAPI +CheckAndAlignMultiboot2Modules ( + IN OUT MULTIBOOT_IMAGE *MultiBoot + ) +{ + EFI_STATUS Status; + BOOLEAN AlignModules; + UINT8 *HeaderAddr; + UINT8 *LoadAddr; + UINT8 *LoadEnd; + UINT8 *BssEnd; + UINT32 EntryPoint; + CONST struct multiboot2_header *MbHeader; + + if (MultiBoot == NULL) { + return RETURN_INVALID_PARAMETER; + } + + MbHeader = GetMultiboot2Header (MultiBoot->BootFile.Addr); + if (MbHeader == NULL) { + return RETURN_LOAD_ERROR; + } + + Status = ParseMultiboot2Header (MbHeader, &AlignModules, &HeaderAddr, &LoadAddr, &LoadEnd, &BssEnd, &EntryPoint); + if (EFI_ERROR (Status)) { + return Status; + } + + if (AlignModules) { + // Modules should be page (4KB) aligned + Status = AlignMultibootModules (MultiBoot); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} + /** Setup Multiboot image and its boot info. diff --git a/PayloadPkg/OsLoader/OsLoader.c b/PayloadPkg/OsLoader/OsLoader.c index 4b9b405f..ed9c7400 100644 --- a/PayloadPkg/OsLoader/OsLoader.c +++ b/PayloadPkg/OsLoader/OsLoader.c @@ -497,10 +497,16 @@ SetupBootImage ( EntryPoint = PayloadInfo.EntryPoint; if (IsMultiboot (BootFile->Addr)) { DEBUG ((DEBUG_INFO, "and Image is Multiboot format\n")); - SetupMultibootInfo (MultiBoot); + Status = CheckAndAlignMultibootModules (MultiBoot); + if (!EFI_ERROR (Status)) { + SetupMultibootInfo (MultiBoot); + } } else if (IsMultiboot2 (BootFile->Addr)) { DEBUG ((DEBUG_INFO, "and Image is Multiboot-2 format\n")); - SetupMultiboot2Info (MultiBoot); + Status = CheckAndAlignMultiboot2Modules (MultiBoot); + if (!EFI_ERROR (Status)) { + SetupMultiboot2Info (MultiBoot); + } } MultiBoot->BootState.EntryPoint = (UINT32)(UINTN)EntryPoint; }