216 lines
6.7 KiB
Diff
216 lines
6.7 KiB
Diff
From 82d95254ca0496c8843113665bb9a99876101025 Mon Sep 17 00:00:00 2001
|
|
From: Michael Chang <mchang@suse.com>
|
|
Date: Fri, 8 Oct 2021 13:36:45 +0800
|
|
Subject: [PATCH 01/11] Factor out grub_efi_linux_boot
|
|
|
|
Both x86 and arm64 on efi are using handover protocol to boot linux
|
|
kernel. To enable better code reuse, factor out grub_efi_linux_boot from
|
|
arm64 so that it can be shared with x86 platform for the common fixes.
|
|
|
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
|
---
|
|
grub-core/Makefile.core.def | 1 +
|
|
grub-core/loader/arm64/efi/linux.c | 35 +-----------------
|
|
grub-core/loader/efi/linux.c | 58 ++++++++++++++++++++++++++++++
|
|
grub-core/loader/i386/efi/linux.c | 13 ++-----
|
|
include/grub/efi/linux.h | 29 +++++++++++++++
|
|
5 files changed, 92 insertions(+), 44 deletions(-)
|
|
create mode 100644 grub-core/loader/efi/linux.c
|
|
create mode 100644 include/grub/efi/linux.h
|
|
|
|
--- a/grub-core/Makefile.core.def
|
|
+++ b/grub-core/Makefile.core.def
|
|
@@ -1860,6 +1860,9 @@
|
|
riscv64 = loader/efi/linux.c;
|
|
emu = loader/emu/linux.c;
|
|
common = loader/linux.c;
|
|
+ i386_efi = loader/efi/linux_boot.c;
|
|
+ x86_64_efi = loader/efi/linux_boot.c;
|
|
+ arm64 = loader/efi/linux_boot.c;
|
|
};
|
|
|
|
module = {
|
|
--- a/grub-core/loader/arm64/efi/linux.c
|
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
|
@@ -33,6 +33,7 @@
|
|
#include <grub/i18n.h>
|
|
#include <grub/lib/cmdline.h>
|
|
#include <grub/verify.h>
|
|
+#include <grub/efi/linux.h>
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
@@ -51,40 +52,6 @@
|
|
static grub_addr_t initrd_start;
|
|
static grub_addr_t initrd_end;
|
|
|
|
-#pragma GCC diagnostic push
|
|
-#pragma GCC diagnostic ignored "-Wcast-align"
|
|
-
|
|
-typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
|
-
|
|
-static grub_err_t
|
|
-grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
|
- void *kernel_params)
|
|
-{
|
|
- grub_efi_loaded_image_t *loaded_image = NULL;
|
|
- handover_func hf;
|
|
-
|
|
- /*
|
|
- * Since the EFI loader is not calling the LoadImage() and StartImage()
|
|
- * services for loading the kernel and booting respectively, it has to
|
|
- * set the Loaded Image base address.
|
|
- */
|
|
- loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
|
- if (loaded_image)
|
|
- loaded_image->image_base = kernel_addr;
|
|
- else
|
|
- grub_dprintf ("linux", "Loaded Image base address could not be set\n");
|
|
-
|
|
- grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
|
|
- kernel_address, (void *)(grub_efi_uintn_t)offset, kernel_params);
|
|
- hf = (handover_func)((char *)kernel_address + offset);
|
|
- grub_dprintf ("linux", "handover_func() = %p\n", hf);
|
|
- hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
|
-
|
|
- return GRUB_ERR_BUG;
|
|
-}
|
|
-
|
|
-#pragma GCC diagnostic pop
|
|
-
|
|
static grub_err_t
|
|
grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
|
|
{
|
|
--- a/grub-core/loader/i386/efi/linux.c
|
|
+++ b/grub-core/loader/i386/efi/linux.c
|
|
@@ -26,6 +26,7 @@
|
|
#include <grub/i18n.h>
|
|
#include <grub/lib/cmdline.h>
|
|
#include <grub/efi/efi.h>
|
|
+#include <grub/efi/linux.h>
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
@@ -40,26 +41,18 @@
|
|
|
|
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
|
|
|
-typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
|
|
-
|
|
static grub_err_t
|
|
grub_linuxefi_boot (void)
|
|
{
|
|
- handover_func hf;
|
|
int offset = 0;
|
|
|
|
#ifdef __x86_64__
|
|
offset = 512;
|
|
#endif
|
|
-
|
|
- hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
|
|
-
|
|
asm volatile ("cli");
|
|
|
|
- hf (grub_efi_image_handle, grub_efi_system_table, params);
|
|
-
|
|
- /* Not reached */
|
|
- return GRUB_ERR_NONE;
|
|
+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset,
|
|
+ params);
|
|
}
|
|
|
|
static grub_err_t
|
|
--- /dev/null
|
|
+++ b/include/grub/efi/linux.h
|
|
@@ -0,0 +1,29 @@
|
|
+/*
|
|
+ * GRUB -- GRand Unified Bootloader
|
|
+ * Copyright (C) 2014 Free Software Foundation, Inc.
|
|
+ *
|
|
+ * GRUB is free software: you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * GRUB is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
+ */
|
|
+#ifndef GRUB_EFI_LINUX_HEADER
|
|
+#define GRUB_EFI_LINUX_HEADER 1
|
|
+
|
|
+#include <grub/efi/api.h>
|
|
+#include <grub/err.h>
|
|
+#include <grub/symbol.h>
|
|
+
|
|
+grub_err_t
|
|
+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
|
|
+ void *kernel_param);
|
|
+
|
|
+#endif /* ! GRUB_EFI_LINUX_HEADER */
|
|
--- /dev/null
|
|
+++ b/grub-core/loader/efi/linux_boot.c
|
|
@@ -0,0 +1,58 @@
|
|
+/*
|
|
+ * GRUB -- GRand Unified Bootloader
|
|
+ * Copyright (C) 2014 Free Software Foundation, Inc.
|
|
+ *
|
|
+ * GRUB is free software: you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * GRUB is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
+ */
|
|
+
|
|
+#include <grub/err.h>
|
|
+#include <grub/mm.h>
|
|
+#include <grub/types.h>
|
|
+#include <grub/cpu/linux.h>
|
|
+#include <grub/efi/efi.h>
|
|
+#include <grub/efi/pe32.h>
|
|
+#include <grub/efi/linux.h>
|
|
+
|
|
+#pragma GCC diagnostic push
|
|
+#pragma GCC diagnostic ignored "-Wcast-align"
|
|
+
|
|
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
|
+
|
|
+grub_err_t
|
|
+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset,
|
|
+ void *kernel_params)
|
|
+{
|
|
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
|
+ handover_func hf;
|
|
+
|
|
+ /*
|
|
+ * Since the EFI loader is not calling the LoadImage() and StartImage()
|
|
+ * services for loading the kernel and booting respectively, it has to
|
|
+ * set the Loaded Image base address.
|
|
+ */
|
|
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
|
+ if (loaded_image)
|
|
+ loaded_image->image_base = kernel_addr;
|
|
+ else
|
|
+ grub_dprintf ("linux", "Loaded Image base address could not be set\n");
|
|
+
|
|
+ grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
|
|
+ kernel_addr, (void *)(grub_efi_uintn_t)offset, kernel_params);
|
|
+ hf = (handover_func)((char *)kernel_addr + offset);
|
|
+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
|
+
|
|
+ return GRUB_ERR_BUG;
|
|
+}
|
|
+
|
|
+#pragma GCC diagnostic pop
|