1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/drivers/firmware/efi/libstub/zboot-header.S
Ard Biesheuvel 29636a5ce8 efi: Put Linux specific magic number in the DOS header
GRUB currently relies on the magic number in the image header of ARM and
arm64 EFI kernel images to decide whether or not the image in question
is a bootable kernel.

However, the purpose of the magic number is to identify the image as one
that implements the bare metal boot protocol, and so GRUB, which only
does EFI boot, is limited unnecessarily to booting images that could
potentially be booted in a non-EFI manner as well.

This is problematic for the new zboot decompressor image format, as it
can only boot in EFI mode, and must therefore not use the bare metal
boot magic number in its header.

For this reason, the strict magic number was dropped from GRUB, to
permit essentially any kind of EFI executable to be booted via the
'linux' command, blurring the line between the linux loader and the
chainloader.

So let's use the same field in the DOS header that RISC-V and arm64
already use for their 'bare metal' magic numbers to store a 'generic
Linux kernel' magic number, which can be used to identify bootable
kernel images in PE format which don't necessarily implement a bare
metal boot protocol in the same binary. Note that, in the context of
EFI, the MS-DOS header is only described in terms of the fields that it
shares with the hybrid PE/COFF image format, (i.e., the MS-DOS EXE magic
number at offset #0 and the PE header offset at byte offset #0x3c).
Since we aim for compatibility with EFI only, and not with MS-DOS or
MS-Windows, we can use the remaining space in the MS-DOS header however
we want.

Let's set the generic magic number for x86 images as well: existing
bootloaders already have their own methods to identify x86 Linux images
that can be booted in a non-EFI manner, and having the magic number in
place there will ease any future transitions in loader implementations
to merge the x86 and non-x86 EFI boot paths.

Note that 32-bit ARM already uses the same location in the header for a
different purpose, but the ARM support is already widely implemented and
the EFI zboot decompressor is not available on ARM anyway, so we just
disregard it here.

Acked-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-12-05 09:31:46 +01:00

144 lines
3.2 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/pe.h>
#ifdef CONFIG_64BIT
.set .Lextra_characteristics, 0x0
.set .Lpe_opt_magic, PE_OPT_MAGIC_PE32PLUS
#else
.set .Lextra_characteristics, IMAGE_FILE_32BIT_MACHINE
.set .Lpe_opt_magic, PE_OPT_MAGIC_PE32
#endif
.section ".head", "a"
.globl __efistub_efi_zboot_header
__efistub_efi_zboot_header:
.Ldoshdr:
.long MZ_MAGIC
.ascii "zimg" // image type
.long __efistub__gzdata_start - .Ldoshdr // payload offset
.long __efistub__gzdata_size - 12 // payload size
.long 0, 0 // reserved
.asciz COMP_TYPE // compression type
.org .Ldoshdr + 0x38
.long LINUX_PE_MAGIC
.long .Lpehdr - .Ldoshdr // PE header offset
.Lpehdr:
.long PE_MAGIC
.short MACHINE_TYPE
.short .Lsection_count
.long 0
.long 0
.long 0
.short .Lsection_table - .Loptional_header
.short IMAGE_FILE_DEBUG_STRIPPED | \
IMAGE_FILE_EXECUTABLE_IMAGE | \
IMAGE_FILE_LINE_NUMS_STRIPPED |\
.Lextra_characteristics
.Loptional_header:
.short .Lpe_opt_magic
.byte 0, 0
.long _etext - .Lefi_header_end
.long __data_size
.long 0
.long __efistub_efi_zboot_entry - .Ldoshdr
.long .Lefi_header_end - .Ldoshdr
#ifdef CONFIG_64BIT
.quad 0
#else
.long _etext - .Ldoshdr, 0x0
#endif
.long 4096
.long 512
.short 0, 0
.short LINUX_EFISTUB_MAJOR_VERSION // MajorImageVersion
.short LINUX_EFISTUB_MINOR_VERSION // MinorImageVersion
.short 0, 0
.long 0
.long _end - .Ldoshdr
.long .Lefi_header_end - .Ldoshdr
.long 0
.short IMAGE_SUBSYSTEM_EFI_APPLICATION
.short 0
#ifdef CONFIG_64BIT
.quad 0, 0, 0, 0
#else
.long 0, 0, 0, 0
#endif
.long 0
.long (.Lsection_table - .) / 8
.quad 0 // ExportTable
.quad 0 // ImportTable
.quad 0 // ResourceTable
.quad 0 // ExceptionTable
.quad 0 // CertificationTable
.quad 0 // BaseRelocationTable
#ifdef CONFIG_DEBUG_EFI
.long .Lefi_debug_table - .Ldoshdr // DebugTable
.long .Lefi_debug_table_size
#endif
.Lsection_table:
.ascii ".text\0\0\0"
.long _etext - .Lefi_header_end
.long .Lefi_header_end - .Ldoshdr
.long _etext - .Lefi_header_end
.long .Lefi_header_end - .Ldoshdr
.long 0, 0
.short 0, 0
.long IMAGE_SCN_CNT_CODE | \
IMAGE_SCN_MEM_READ | \
IMAGE_SCN_MEM_EXECUTE
.ascii ".data\0\0\0"
.long __data_size
.long _etext - .Ldoshdr
.long __data_rawsize
.long _etext - .Ldoshdr
.long 0, 0
.short 0, 0
.long IMAGE_SCN_CNT_INITIALIZED_DATA | \
IMAGE_SCN_MEM_READ | \
IMAGE_SCN_MEM_WRITE
.set .Lsection_count, (. - .Lsection_table) / 40
#ifdef CONFIG_DEBUG_EFI
.section ".rodata", "a"
.align 2
.Lefi_debug_table:
// EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
.long 0 // Characteristics
.long 0 // TimeDateStamp
.short 0 // MajorVersion
.short 0 // MinorVersion
.long IMAGE_DEBUG_TYPE_CODEVIEW // Type
.long .Lefi_debug_entry_size // SizeOfData
.long 0 // RVA
.long .Lefi_debug_entry - .Ldoshdr // FileOffset
.set .Lefi_debug_table_size, . - .Lefi_debug_table
.previous
.Lefi_debug_entry:
// EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
.ascii "NB10" // Signature
.long 0 // Unknown
.long 0 // Unknown2
.long 0 // Unknown3
.asciz ZBOOT_EFI_PATH
.set .Lefi_debug_entry_size, . - .Lefi_debug_entry
#endif
.p2align 12
.Lefi_header_end: