diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 997647a33..977757f2c 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -624,6 +624,18 @@ grub_linux_boot (void) } #endif +#if defined (__x86_64__) && defined (GRUB_MACHINE_EFI) + if (grub_le_to_cpu16 (ctx.params->version) >= 0x020c && + (linux_params.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0) + { + struct grub_relocator64_efi_state state64; + + state64.rsi = ctx.real_mode_target; + state64.rip = ctx.params->code32_start + LINUX_X86_STARTUP64_OFFSET; + return grub_relocator64_efi_boot (relocator, state64); + } +#endif + /* FIXME. */ /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ state.ebp = state.edi = state.ebx = 0; diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index 0fd6e1212..d4b550869 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -69,6 +69,16 @@ #define GRUB_LINUX_OFW_SIGNATURE \ (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O') +#define LINUX_X86_XLF_KERNEL_64 (1<<0) +#define LINUX_X86_XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) +#define LINUX_X86_XLF_EFI_HANDOVER_32 (1<<2) +#define LINUX_X86_XLF_EFI_HANDOVER_64 (1<<3) +#define LINUX_X86_XLF_EFI_KEXEC (1<<4) +#define LINUX_X86_XLF_5LEVEL (1<<5) +#define LINUX_X86_XLF_5LEVEL_ENABLED (1<<6) + +#define LINUX_X86_STARTUP64_OFFSET 0x200 + #ifndef ASM_FILE #define GRUB_E820_RAM 1 @@ -138,7 +148,7 @@ struct linux_i386_kernel_header grub_uint32_t kernel_alignment; grub_uint8_t relocatable; grub_uint8_t min_alignment; - grub_uint8_t pad[2]; + grub_uint16_t xloadflags; grub_uint32_t cmdline_size; grub_uint32_t hardware_subarch; grub_uint64_t hardware_subarch_data; @@ -315,7 +325,8 @@ struct linux_kernel_params grub_uint32_t initrd_addr_max; /* Maximum initrd address */ grub_uint32_t kernel_alignment; /* Alignment of the kernel */ grub_uint8_t relocatable_kernel; /* Is the kernel relocatable */ - grub_uint8_t pad1[3]; + grub_uint8_t min_alignment; + grub_uint16_t xloadflags; grub_uint32_t cmdline_size; /* Size of the kernel command line */ grub_uint32_t hardware_subarch; grub_uint64_t hardware_subarch_data;