|
|
0dc71c |
From e396fd48c78901459f39926fe28c9fbc38ffdddb Mon Sep 17 00:00:00 2001
|
|
|
0dc71c |
From: Peter Jones <pjones@redhat.com>
|
|
|
0dc71c |
Date: Thu, 18 Sep 2014 11:26:14 -0400
|
|
|
0dc71c |
Subject: [PATCH] Load arm with SB enabled.
|
|
|
0dc71c |
|
|
|
0dc71c |
Make sure we actually try to validate secure boot on this platform (even
|
|
|
0dc71c |
though we're not shipping it enabled by default.)
|
|
|
0dc71c |
|
|
|
0dc71c |
This means giving the kernel grub's loaded image as the vehicle for the
|
|
|
0dc71c |
kernel command line, because we can't call systab->bs->LoadImage() if SB
|
|
|
0dc71c |
is enabled.
|
|
|
0dc71c |
---
|
|
|
0dc71c |
grub-core/Makefile.core.def | 2 +
|
|
|
0dc71c |
grub-core/loader/arm64/linux.c | 108 ++++++++++++++++++++------------------
|
|
|
0dc71c |
grub-core/loader/efi/linux.c | 65 +++++++++++++++++++++++
|
|
|
0dc71c |
grub-core/loader/i386/efi/linux.c | 39 ++------------
|
|
|
0dc71c |
include/grub/arm64/linux.h | 8 +++
|
|
|
0dc71c |
include/grub/efi/linux.h | 31 +++++++++++
|
|
|
0dc71c |
6 files changed, 166 insertions(+), 87 deletions(-)
|
|
|
0dc71c |
create mode 100644 grub-core/loader/efi/linux.c
|
|
|
0dc71c |
create mode 100644 include/grub/efi/linux.h
|
|
|
0dc71c |
|
|
|
0dc71c |
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
|
|
0dc71c |
index 9ff9ae5..9378c73 100644
|
|
|
0dc71c |
--- a/grub-core/Makefile.core.def
|
|
|
0dc71c |
+++ b/grub-core/Makefile.core.def
|
|
|
0dc71c |
@@ -1682,6 +1682,7 @@ module = {
|
|
|
0dc71c |
ia64_efi = loader/ia64/efi/linux.c;
|
|
|
0dc71c |
arm = loader/arm/linux.c;
|
|
|
0dc71c |
arm64 = loader/arm64/linux.c;
|
|
|
0dc71c |
+ arm64 = loader/efi/linux.c;
|
|
|
0dc71c |
fdt = lib/fdt.c;
|
|
|
0dc71c |
common = loader/linux.c;
|
|
|
0dc71c |
common = lib/cmdline.c;
|
|
|
0dc71c |
@@ -1718,6 +1719,7 @@ module = {
|
|
|
0dc71c |
name = linuxefi;
|
|
|
0dc71c |
efi = loader/i386/efi/linux.c;
|
|
|
0dc71c |
efi = lib/cmdline.c;
|
|
|
0dc71c |
+ efi = loader/efi/linux.c;
|
|
|
0dc71c |
enable = i386_efi;
|
|
|
0dc71c |
enable = x86_64_efi;
|
|
|
0dc71c |
};
|
|
|
0dc71c |
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
|
|
|
0dc71c |
index 0dc144e..bdd9c9b 100644
|
|
|
0dc71c |
--- a/grub-core/loader/arm64/linux.c
|
|
|
0dc71c |
+++ b/grub-core/loader/arm64/linux.c
|
|
|
0dc71c |
@@ -27,6 +27,7 @@
|
|
|
0dc71c |
#include <grub/types.h>
|
|
|
0dc71c |
#include <grub/cpu/linux.h>
|
|
|
0dc71c |
#include <grub/efi/efi.h>
|
|
|
0dc71c |
+#include <grub/efi/linux.h>
|
|
|
0dc71c |
#include <grub/efi/pe32.h>
|
|
|
0dc71c |
#include <grub/i18n.h>
|
|
|
0dc71c |
#include <grub/lib/cmdline.h>
|
|
|
0dc71c |
@@ -44,6 +45,7 @@ static int loaded;
|
|
|
0dc71c |
|
|
|
0dc71c |
static void *kernel_addr;
|
|
|
0dc71c |
static grub_uint64_t kernel_size;
|
|
|
0dc71c |
+static grub_uint32_t handover_offset;
|
|
|
0dc71c |
|
|
|
0dc71c |
static char *linux_args;
|
|
|
0dc71c |
static grub_uint32_t cmdline_size;
|
|
|
0dc71c |
@@ -135,7 +137,9 @@ finalize_params (void)
|
|
|
0dc71c |
{
|
|
|
0dc71c |
grub_efi_boot_services_t *b;
|
|
|
0dc71c |
grub_efi_status_t status;
|
|
|
0dc71c |
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
|
|
0dc71c |
int node, retval;
|
|
|
0dc71c |
+ int len;
|
|
|
0dc71c |
|
|
|
0dc71c |
get_fdt ();
|
|
|
0dc71c |
if (!fdt)
|
|
|
0dc71c |
@@ -172,6 +176,23 @@ finalize_params (void)
|
|
|
0dc71c |
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
|
|
|
0dc71c |
fdt);
|
|
|
0dc71c |
|
|
|
0dc71c |
+ /* Convert command line to UCS-2 */
|
|
|
0dc71c |
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
|
|
0dc71c |
+ if (!loaded_image)
|
|
|
0dc71c |
+ goto failure;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ loaded_image->load_options_size = len =
|
|
|
0dc71c |
+ (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
|
|
0dc71c |
+ loaded_image->load_options =
|
|
|
0dc71c |
+ grub_efi_allocate_pages (0,
|
|
|
0dc71c |
+ BYTES_TO_PAGES (loaded_image->load_options_size));
|
|
|
0dc71c |
+ if (!loaded_image->load_options)
|
|
|
0dc71c |
+ return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ loaded_image->load_options_size =
|
|
|
0dc71c |
+ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
|
|
0dc71c |
+ (grub_uint8_t *) linux_args, len, NULL);
|
|
|
0dc71c |
+
|
|
|
0dc71c |
return GRUB_ERR_NONE;
|
|
|
0dc71c |
|
|
|
0dc71c |
failure:
|
|
|
0dc71c |
@@ -181,6 +202,23 @@ failure:
|
|
|
0dc71c |
return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
|
|
0dc71c |
}
|
|
|
0dc71c |
|
|
|
0dc71c |
+static void
|
|
|
0dc71c |
+free_params (void)
|
|
|
0dc71c |
+{
|
|
|
0dc71c |
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
|
|
0dc71c |
+ if (loaded_image)
|
|
|
0dc71c |
+ {
|
|
|
0dc71c |
+ if (loaded_image->load_options)
|
|
|
0dc71c |
+ grub_efi_free_pages ((grub_efi_physical_address_t)
|
|
|
0dc71c |
+ loaded_image->load_options,
|
|
|
0dc71c |
+ BYTES_TO_PAGES (loaded_image->load_options_size));
|
|
|
0dc71c |
+ loaded_image->load_options = NULL;
|
|
|
0dc71c |
+ loaded_image->load_options_size = 0;
|
|
|
0dc71c |
+ }
|
|
|
0dc71c |
+}
|
|
|
0dc71c |
+
|
|
|
0dc71c |
static grub_err_t
|
|
|
0dc71c |
grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
|
|
|
0dc71c |
int argc, char *argv[])
|
|
|
0dc71c |
@@ -199,6 +237,10 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
|
|
|
0dc71c |
if (argc != 1)
|
|
|
0dc71c |
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
|
|
0dc71c |
|
|
|
0dc71c |
+ if (grub_efi_secure_boot ())
|
|
|
0dc71c |
+ return grub_error (GRUB_ERR_INVALID_COMMAND,
|
|
|
0dc71c |
+ N_("Not loading devicetree - Secure Boot is enabled"));
|
|
|
0dc71c |
+
|
|
|
0dc71c |
if (loaded_fdt)
|
|
|
0dc71c |
grub_free (loaded_fdt);
|
|
|
0dc71c |
loaded_fdt = NULL;
|
|
|
0dc71c |
@@ -243,65 +285,20 @@ out:
|
|
|
0dc71c |
static grub_err_t
|
|
|
0dc71c |
grub_linux_boot (void)
|
|
|
0dc71c |
{
|
|
|
0dc71c |
- grub_efi_memory_mapped_device_path_t *mempath;
|
|
|
0dc71c |
- grub_efi_handle_t image_handle;
|
|
|
0dc71c |
- grub_efi_boot_services_t *b;
|
|
|
0dc71c |
- grub_efi_status_t status;
|
|
|
0dc71c |
grub_err_t retval;
|
|
|
0dc71c |
- grub_efi_loaded_image_t *loaded_image;
|
|
|
0dc71c |
- int len;
|
|
|
0dc71c |
|
|
|
0dc71c |
retval = finalize_params();
|
|
|
0dc71c |
if (retval != GRUB_ERR_NONE)
|
|
|
0dc71c |
return retval;
|
|
|
0dc71c |
|
|
|
0dc71c |
- mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
|
|
|
0dc71c |
- if (!mempath)
|
|
|
0dc71c |
- return grub_errno;
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
|
|
|
0dc71c |
- mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
|
|
|
0dc71c |
- mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
|
|
|
0dc71c |
- mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
|
|
|
0dc71c |
- mempath[0].start_address = (grub_addr_t) kernel_addr;
|
|
|
0dc71c |
- mempath[0].end_address = (grub_addr_t) kernel_addr + kernel_size;
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
|
|
0dc71c |
- mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
|
|
0dc71c |
- mempath[1].header.length = sizeof (grub_efi_device_path_t);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- b = grub_efi_system_table->boot_services;
|
|
|
0dc71c |
- status = b->load_image (0, grub_efi_image_handle,
|
|
|
0dc71c |
- (grub_efi_device_path_t *) mempath,
|
|
|
0dc71c |
- kernel_addr, kernel_size, &image_handle);
|
|
|
0dc71c |
- if (status != GRUB_EFI_SUCCESS)
|
|
|
0dc71c |
- return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
|
|
0dc71c |
-
|
|
|
0dc71c |
grub_dprintf ("linux", "linux command line: '%s'\n", linux_args);
|
|
|
0dc71c |
|
|
|
0dc71c |
- /* Convert command line to UCS-2 */
|
|
|
0dc71c |
- loaded_image = grub_efi_get_loaded_image (image_handle);
|
|
|
0dc71c |
- loaded_image->load_options_size = len =
|
|
|
0dc71c |
- (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
|
|
0dc71c |
- loaded_image->load_options =
|
|
|
0dc71c |
- grub_efi_allocate_pages (0,
|
|
|
0dc71c |
- BYTES_TO_PAGES (loaded_image->load_options_size));
|
|
|
0dc71c |
- if (!loaded_image->load_options)
|
|
|
0dc71c |
- return grub_errno;
|
|
|
0dc71c |
+ retval = grub_efi_linux_boot ((char *)kernel_addr, handover_offset,
|
|
|
0dc71c |
+ kernel_addr);
|
|
|
0dc71c |
|
|
|
0dc71c |
- loaded_image->load_options_size =
|
|
|
0dc71c |
- 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
|
|
0dc71c |
- (grub_uint8_t *) linux_args, len, NULL);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- grub_dprintf("linux", "starting image %p\n", image_handle);
|
|
|
0dc71c |
- status = b->start_image (image_handle, 0, NULL);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- /* When successful, not reached */
|
|
|
0dc71c |
- b->unload_image (image_handle);
|
|
|
0dc71c |
- grub_efi_free_pages ((grub_efi_physical_address_t) loaded_image->load_options,
|
|
|
0dc71c |
- BYTES_TO_PAGES (loaded_image->load_options_size));
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- return grub_errno;
|
|
|
0dc71c |
+ /* Never reached... */
|
|
|
0dc71c |
+ free_params();
|
|
|
0dc71c |
+ return retval;
|
|
|
0dc71c |
}
|
|
|
0dc71c |
|
|
|
0dc71c |
static grub_err_t
|
|
|
0dc71c |
@@ -382,6 +379,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
0dc71c |
{
|
|
|
0dc71c |
grub_file_t file = 0;
|
|
|
0dc71c |
struct grub_arm64_linux_kernel_header lh;
|
|
|
0dc71c |
+ struct grub_arm64_linux_pe_header *pe;
|
|
|
0dc71c |
|
|
|
0dc71c |
grub_dl_ref (my_mod);
|
|
|
0dc71c |
|
|
|
0dc71c |
@@ -426,6 +424,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
0dc71c |
|
|
|
0dc71c |
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
|
|
0dc71c |
|
|
|
0dc71c |
+ if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
|
|
|
0dc71c |
+ {
|
|
|
0dc71c |
+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
|
|
0dc71c |
+ goto fail;
|
|
|
0dc71c |
+ }
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
|
|
0dc71c |
+ handover_offset = pe->opt.entry_addr;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
|
|
|
0dc71c |
linux_args = grub_malloc (cmdline_size);
|
|
|
0dc71c |
if (!linux_args)
|
|
|
0dc71c |
@@ -464,7 +471,6 @@ fail:
|
|
|
0dc71c |
return grub_errno;
|
|
|
0dc71c |
}
|
|
|
0dc71c |
|
|
|
0dc71c |
-
|
|
|
0dc71c |
static grub_command_t cmd_linux, cmd_initrd, cmd_devicetree;
|
|
|
0dc71c |
|
|
|
0dc71c |
GRUB_MOD_INIT (linux)
|
|
|
0dc71c |
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
|
|
0dc71c |
new file mode 100644
|
|
|
0dc71c |
index 0000000..aea378a
|
|
|
0dc71c |
--- /dev/null
|
|
|
0dc71c |
+++ b/grub-core/loader/efi/linux.c
|
|
|
0dc71c |
@@ -0,0 +1,65 @@
|
|
|
0dc71c |
+/*
|
|
|
0dc71c |
+ * GRUB -- GRand Unified Bootloader
|
|
|
0dc71c |
+ * Copyright (C) 2014 Free Software Foundation, Inc.
|
|
|
0dc71c |
+ *
|
|
|
0dc71c |
+ * GRUB is free software: you can redistribute it and/or modify
|
|
|
0dc71c |
+ * it under the terms of the GNU General Public License as published by
|
|
|
0dc71c |
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
0dc71c |
+ * (at your option) any later version.
|
|
|
0dc71c |
+ *
|
|
|
0dc71c |
+ * GRUB is distributed in the hope that it will be useful,
|
|
|
0dc71c |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
0dc71c |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
0dc71c |
+ * GNU General Public License for more details.
|
|
|
0dc71c |
+ *
|
|
|
0dc71c |
+ * You should have received a copy of the GNU General Public License
|
|
|
0dc71c |
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
0dc71c |
+ */
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+#include <grub/err.h>
|
|
|
0dc71c |
+#include <grub/mm.h>
|
|
|
0dc71c |
+#include <grub/types.h>
|
|
|
0dc71c |
+#include <grub/cpu/linux.h>
|
|
|
0dc71c |
+#include <grub/efi/efi.h>
|
|
|
0dc71c |
+#include <grub/efi/pe32.h>
|
|
|
0dc71c |
+#include <grub/efi/linux.h>
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+#define SHIM_LOCK_GUID \
|
|
|
0dc71c |
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+struct grub_efi_shim_lock
|
|
|
0dc71c |
+{
|
|
|
0dc71c |
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
|
|
|
0dc71c |
+};
|
|
|
0dc71c |
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+grub_efi_boolean_t
|
|
|
0dc71c |
+grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
|
|
0dc71c |
+{
|
|
|
0dc71c |
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
|
|
|
0dc71c |
+ grub_efi_shim_lock_t *shim_lock;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ shim_lock = grub_efi_locate_protocol(&guid, NULL);
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ if (!shim_lock)
|
|
|
0dc71c |
+ return 1;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
|
|
|
0dc71c |
+ return 1;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ return 0;
|
|
|
0dc71c |
+}
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+grub_err_t
|
|
|
0dc71c |
+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset,
|
|
|
0dc71c |
+ void *kernel_params)
|
|
|
0dc71c |
+{
|
|
|
0dc71c |
+ handover_func hf;
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ hf = (handover_func)((char *)kernel_addr + offset);
|
|
|
0dc71c |
+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+ return GRUB_ERR_BUG;
|
|
|
0dc71c |
+}
|
|
|
0dc71c |
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
|
0dc71c |
index b79e632..e5b7785 100644
|
|
|
0dc71c |
--- a/grub-core/loader/i386/efi/linux.c
|
|
|
0dc71c |
+++ b/grub-core/loader/i386/efi/linux.c
|
|
|
0dc71c |
@@ -26,6 +26,7 @@
|
|
|
0dc71c |
#include <grub/i18n.h>
|
|
|
0dc71c |
#include <grub/lib/cmdline.h>
|
|
|
0dc71c |
#include <grub/efi/efi.h>
|
|
|
0dc71c |
+#include <grub/efi/linux.h>
|
|
|
0dc71c |
|
|
|
0dc71c |
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
0dc71c |
|
|
|
0dc71c |
@@ -40,52 +41,18 @@ static char *linux_cmdline;
|
|
|
0dc71c |
|
|
|
0dc71c |
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
|
|
0dc71c |
|
|
|
0dc71c |
-#define SHIM_LOCK_GUID \
|
|
|
0dc71c |
- { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
|
|
0dc71c |
-
|
|
|
0dc71c |
-struct grub_efi_shim_lock
|
|
|
0dc71c |
-{
|
|
|
0dc71c |
- grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
|
|
|
0dc71c |
-};
|
|
|
0dc71c |
-typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
|
|
0dc71c |
-
|
|
|
0dc71c |
-static grub_efi_boolean_t
|
|
|
0dc71c |
-grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
|
|
0dc71c |
-{
|
|
|
0dc71c |
- grub_efi_guid_t guid = SHIM_LOCK_GUID;
|
|
|
0dc71c |
- grub_efi_shim_lock_t *shim_lock;
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- shim_lock = grub_efi_locate_protocol(&guid, NULL);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- if (!shim_lock)
|
|
|
0dc71c |
- return 1;
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
|
|
|
0dc71c |
- return 1;
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- return 0;
|
|
|
0dc71c |
-}
|
|
|
0dc71c |
-
|
|
|
0dc71c |
-typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
static grub_err_t
|
|
|
0dc71c |
grub_linuxefi_boot (void)
|
|
|
0dc71c |
{
|
|
|
0dc71c |
- handover_func hf;
|
|
|
0dc71c |
int offset = 0;
|
|
|
0dc71c |
|
|
|
0dc71c |
#ifdef __x86_64__
|
|
|
0dc71c |
offset = 512;
|
|
|
0dc71c |
#endif
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
asm volatile ("cli");
|
|
|
0dc71c |
|
|
|
0dc71c |
- hf (grub_efi_image_handle, grub_efi_system_table, params);
|
|
|
0dc71c |
-
|
|
|
0dc71c |
- /* Not reached */
|
|
|
0dc71c |
- return GRUB_ERR_NONE;
|
|
|
0dc71c |
+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset,
|
|
|
0dc71c |
+ params);
|
|
|
0dc71c |
}
|
|
|
0dc71c |
|
|
|
0dc71c |
static grub_err_t
|
|
|
0dc71c |
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
|
|
|
0dc71c |
index 864e5dc..2cbd64f 100644
|
|
|
0dc71c |
--- a/include/grub/arm64/linux.h
|
|
|
0dc71c |
+++ b/include/grub/arm64/linux.h
|
|
|
0dc71c |
@@ -20,6 +20,7 @@
|
|
|
0dc71c |
#define GRUB_LINUX_CPU_HEADER 1
|
|
|
0dc71c |
|
|
|
0dc71c |
#include <grub/efi/efi.h>
|
|
|
0dc71c |
+#include <grub/efi/pe32.h>
|
|
|
0dc71c |
|
|
|
0dc71c |
#define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */
|
|
|
0dc71c |
|
|
|
0dc71c |
@@ -38,4 +39,11 @@ struct grub_arm64_linux_kernel_header
|
|
|
0dc71c |
grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
|
|
|
0dc71c |
};
|
|
|
0dc71c |
|
|
|
0dc71c |
+struct grub_arm64_linux_pe_header
|
|
|
0dc71c |
+{
|
|
|
0dc71c |
+ grub_uint32_t magic;
|
|
|
0dc71c |
+ struct grub_pe32_coff_header coff;
|
|
|
0dc71c |
+ struct grub_pe64_optional_header opt;
|
|
|
0dc71c |
+};
|
|
|
0dc71c |
+
|
|
|
0dc71c |
#endif /* ! GRUB_LINUX_CPU_HEADER */
|
|
|
0dc71c |
diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
|
|
|
0dc71c |
new file mode 100644
|
|
|
0dc71c |
index 0000000..d9ede36
|
|
|
0dc71c |
--- /dev/null
|
|
|
0dc71c |
+++ b/include/grub/efi/linux.h
|
|
|
0dc71c |
@@ -0,0 +1,31 @@
|
|
|
0dc71c |
+/*
|
|
|
0dc71c |
+ * GRUB -- GRand Unified Bootloader
|
|
|
0dc71c |
+ * Copyright (C) 2014 Free Software Foundation, Inc.
|
|
|
0dc71c |
+ *
|
|
|
0dc71c |
+ * GRUB is free software: you can redistribute it and/or modify
|
|
|
0dc71c |
+ * it under the terms of the GNU General Public License as published by
|
|
|
0dc71c |
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
0dc71c |
+ * (at your option) any later version.
|
|
|
0dc71c |
+ *
|
|
|
0dc71c |
+ * GRUB is distributed in the hope that it will be useful,
|
|
|
0dc71c |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
0dc71c |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
0dc71c |
+ * GNU General Public License for more details.
|
|
|
0dc71c |
+ *
|
|
|
0dc71c |
+ * You should have received a copy of the GNU General Public License
|
|
|
0dc71c |
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
0dc71c |
+ */
|
|
|
0dc71c |
+#ifndef GRUB_EFI_LINUX_HEADER
|
|
|
0dc71c |
+#define GRUB_EFI_LINUX_HEADER 1
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+#include <grub/efi/api.h>
|
|
|
0dc71c |
+#include <grub/err.h>
|
|
|
0dc71c |
+#include <grub/symbol.h>
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+grub_efi_boolean_t
|
|
|
0dc71c |
+EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
|
|
|
0dc71c |
+grub_err_t
|
|
|
0dc71c |
+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
|
|
|
0dc71c |
+ void *kernel_param);
|
|
|
0dc71c |
+
|
|
|
0dc71c |
+#endif /* ! GRUB_EFI_LINUX_HEADER */
|
|
|
0dc71c |
--
|
|
|
0dc71c |
1.9.3
|
|
|
0dc71c |
|