Backport required patches. Disable Secure Boot for now as it conflicts with the Xen patches. Increase Epoch.
Signed-off-by: Stefano Stabellini stefano.stabellini@eu.citrix.com --- ...rm64-Export-useful-functions-from-linux.c.patch | 280 ++++++++ ...nd-export-some-accessor-functions-for-xen.patch | 67 ++ SOURCES/0003-arm64-Add-xen_boot-module-file.patch | 733 +++++++++++++++++++++ ...-20_linux_xen.in-Add-support-of-the-XEN-b.patch | 60 ++ ...he-introduction-of-xen-boot-commands-in-d.patch | 94 +++ .../0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch | 34 + SPECS/grub2.spec | 16 +- 7 files changed, 1280 insertions(+), 4 deletions(-) create mode 100644 SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch create mode 100644 SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch create mode 100644 SOURCES/0003-arm64-Add-xen_boot-module-file.patch create mode 100644 SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch create mode 100644 SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch create mode 100644 SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch
diff --git a/SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch b/SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch new file mode 100644 index 0000000..88ccc12 --- /dev/null +++ b/SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch @@ -0,0 +1,280 @@ +From cfce76bbd91696e83bb15a180fd51a0fd1c31f83 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 7 May 2015 15:11:04 +0200 +Subject: [PATCH 1/5] arm64: Export useful functions from linux.c + +Signed-off-by: Fu Wei fu.wei@linaro.org + +Conflicts: + gentpl.py +--- + gentpl.py | 2 +- + grub-core/loader/arm64/linux.c | 59 ++++++++++++++++++++-------------------- + grub-core/loader/i386/linux.c | 11 ++++---- + grub-core/loader/linux.c | 3 +- + include/grub/arm64/linux.h | 11 ++++++++ + 5 files changed, 49 insertions(+), 37 deletions(-) + +diff --git a/gentpl.py b/gentpl.py +index bdcae1a..136b484 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -753,7 +753,7 @@ def image(defn, platform): + if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(MACHO2IMG) $< $@; \ + else \ +- $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; \ ++ $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .hash -R .dynsym -R .dynstr -R .rel.text $< $@; \ + fi + """) + +diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c +index 9d15aad..18c34c8 100644 +--- a/grub-core/loader/arm64/linux.c ++++ b/grub-core/loader/arm64/linux.c +@@ -33,12 +33,6 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-#define GRUB_EFI_PAGE_SHIFT 12 +-#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) +-#define GRUB_EFI_PE_MAGIC 0x5A4D +- +-static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; +- + static grub_dl_t my_mod; + static int loaded; + +@@ -58,6 +52,7 @@ static void * + get_firmware_fdt (void) + { + grub_efi_configuration_table_t *tables; ++ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; + void *firmware_fdt = NULL; + unsigned int i; + +@@ -75,8 +70,8 @@ get_firmware_fdt (void) + return firmware_fdt; + } + +-static void +-get_fdt (void) ++void * ++grub_linux_get_fdt (void) + { + void *raw_fdt; + grub_size_t size; +@@ -99,7 +94,7 @@ get_fdt (void) + grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size); + fdt = grub_efi_allocate_pages (0, BYTES_TO_PAGES (size)); + if (!fdt) +- return; ++ return NULL; + + if (raw_fdt) + { +@@ -110,10 +105,11 @@ get_fdt (void) + { + grub_fdt_create_empty_tree (fdt, size); + } ++ return fdt; + } + +-static grub_err_t +-check_kernel (struct grub_arm64_linux_kernel_header *lh) ++grub_err_t ++grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header * lh) + { + if (lh->magic != GRUB_ARM64_LINUX_MAGIC) + return grub_error(GRUB_ERR_BAD_OS, "invalid magic number"); +@@ -131,14 +127,14 @@ check_kernel (struct grub_arm64_linux_kernel_header *lh) + } + + static grub_err_t +-finalize_params (void) ++finalize_params_linux (void) + { + grub_efi_boot_services_t *b; ++ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; + grub_efi_status_t status; + int node, retval; + +- get_fdt (); +- if (!fdt) ++ if (!grub_linux_get_fdt ()) + goto failure; + + node = grub_fdt_find_subnode (fdt, 0, "chosen"); +@@ -240,21 +236,16 @@ out: + return grub_errno; + } + +-static grub_err_t +-grub_linux_boot (void) ++grub_err_t ++grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args) + { + grub_efi_memory_mapped_device_path_t *mempath; + grub_efi_handle_t image_handle; + grub_efi_boot_services_t *b; + grub_efi_status_t status; +- grub_err_t retval; + grub_efi_loaded_image_t *loaded_image; + int len; + +- retval = finalize_params(); +- if (retval != GRUB_ERR_NONE) +- return retval; +- + mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); + if (!mempath) + return grub_errno; +@@ -263,8 +254,8 @@ grub_linux_boot (void) + mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; + mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); + mempath[0].memory_type = GRUB_EFI_LOADER_DATA; +- mempath[0].start_address = (grub_addr_t) kernel_addr; +- mempath[0].end_address = (grub_addr_t) kernel_addr + kernel_size; ++ mempath[0].start_address = addr; ++ mempath[0].end_address = addr + size; + + mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; + mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; +@@ -273,16 +264,16 @@ grub_linux_boot (void) + b = grub_efi_system_table->boot_services; + status = b->load_image (0, grub_efi_image_handle, + (grub_efi_device_path_t *) mempath, +- kernel_addr, kernel_size, &image_handle); ++ (void *) addr, size, &image_handle); + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + +- grub_dprintf ("linux", "linux command line: '%s'\n", linux_args); ++ grub_dprintf ("linux", "linux command line: '%s'\n", args); + + /* Convert command line to UCS-2 */ + loaded_image = grub_efi_get_loaded_image (image_handle); + loaded_image->load_options_size = len = +- (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t); ++ (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); + loaded_image->load_options = + grub_efi_allocate_pages (0, + BYTES_TO_PAGES (loaded_image->load_options_size)); +@@ -291,9 +282,9 @@ grub_linux_boot (void) + + loaded_image->load_options_size = + 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, +- (grub_uint8_t *) linux_args, len, NULL); ++ (grub_uint8_t *) args, len, NULL); + +- grub_dprintf("linux", "starting image %p\n", image_handle); ++ grub_dprintf ("linux", "starting image %p\n", image_handle); + status = b->start_image (image_handle, 0, NULL); + + /* When successful, not reached */ +@@ -305,6 +296,16 @@ grub_linux_boot (void) + } + + static grub_err_t ++grub_linux_boot (void) ++{ ++ if (finalize_params_linux () != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr, ++ kernel_size, linux_args)); ++} ++ ++static grub_err_t + grub_linux_unload (void) + { + grub_dl_unref (my_mod); +@@ -400,7 +401,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) + return grub_errno; + +- if (check_kernel (&lh) != GRUB_ERR_NONE) ++ if (grub_arm64_uefi_check_image (&lh) != GRUB_ERR_NONE) + goto fail; + + grub_loader_unset(); +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 31fb91e..434ddca 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -69,7 +69,6 @@ static grub_addr_t prot_mode_target; + static void *initrd_mem; + static grub_addr_t initrd_mem_target; + static grub_size_t prot_init_space; +-static grub_uint32_t initrd_pages; + static struct grub_relocator *relocator = NULL; + static void *efi_mmap_buf; + static grub_size_t maximal_cmdline_size; +@@ -1046,7 +1045,7 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_size_t size = 0; ++ grub_size_t size = 0, aligned_size = 0; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + grub_err_t err; +@@ -1068,8 +1067,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + + size = grub_get_initrd_size (&initrd_ctx); +- +- initrd_pages = (page_align (size) >> 12); ++ aligned_size = ALIGN_UP (size, 4096); + + /* Get the highest address available for the initrd. */ + if (grub_le_to_cpu16 (linux_params.version) >= 0x0203) +@@ -1097,7 +1095,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + addr_min = (grub_addr_t) prot_mode_target + prot_init_space; + + /* Put the initrd as high as possible, 4KiB aligned. */ +- addr = (addr_max - size) & ~0xFFF; ++ addr = (addr_max - aligned_size) & ~0xFFF; + + if (addr < addr_min) + { +@@ -1108,7 +1106,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, +- addr_min, addr, size, 0x1000, ++ addr_min, addr, aligned_size, ++ 0x1000, + GRUB_RELOCATOR_PREFERENCE_HIGH, + 1); + if (err) +diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h +index 864e5dc..65796d9 100644 +--- a/include/grub/arm64/linux.h ++++ b/include/grub/arm64/linux.h +@@ -23,6 +23,10 @@ + + #define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */ + ++#define GRUB_EFI_PAGE_SHIFT 12 ++#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) ++#define GRUB_EFI_PE_MAGIC 0x5A4D ++ + /* From linux/Documentation/arm64/booting.txt */ + struct grub_arm64_linux_kernel_header + { +@@ -38,4 +42,11 @@ struct grub_arm64_linux_kernel_header + grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ + }; + ++/* Declare the functions for getting dtb and checking/booting image */ ++void *grub_linux_get_fdt (void); ++grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header ++ *lh); ++grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, ++ char *args); ++ + #endif /* ! GRUB_LINUX_CPU_HEADER */ +-- +1.7.10.4 + diff --git a/SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch b/SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch new file mode 100644 index 0000000..8caf670 --- /dev/null +++ b/SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch @@ -0,0 +1,67 @@ +From 484f6f757c6ce8419bd6037d6e67ae339d243720 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:20 +0800 +Subject: [PATCH 2/5] arm64: Add and export some accessor functions for xen + boot + +Add accessor functions of "loaded" flag in +grub-core/loader/arm64/linux.c. + +Export accessor functions of "loaded" flag and +grub_linux_get_fdt function in include/grub/arm64/linux.h. + +Purpose: Reuse the existing code of devicetree in linux module. + +Signed-off-by: Fu Wei fu.wei@linaro.org +--- + grub-core/loader/arm64/linux.c | 13 +++++++++++++ + include/grub/arm64/linux.h | 6 +++++- + 2 files changed, 18 insertions(+), 1 deletion(-) + +diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c +index 18c34c8..038300e 100644 +--- a/grub-core/loader/arm64/linux.c ++++ b/grub-core/loader/arm64/linux.c +@@ -48,6 +48,19 @@ static grub_addr_t initrd_end; + static void *loaded_fdt; + static void *fdt; + ++/* The accessor functions for "loaded" flag */ ++int ++grub_linux_get_loaded (void) ++{ ++ return loaded; ++} ++ ++void ++grub_linux_set_loaded (int loaded_flag) ++{ ++ loaded = loaded_flag; ++} ++ + static void * + get_firmware_fdt (void) + { +diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h +index 65796d9..20058f3 100644 +--- a/include/grub/arm64/linux.h ++++ b/include/grub/arm64/linux.h +@@ -43,10 +43,14 @@ struct grub_arm64_linux_kernel_header + }; + + /* Declare the functions for getting dtb and checking/booting image */ +-void *grub_linux_get_fdt (void); + grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header + *lh); + grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, + char *args); + ++/* Export the accessor functions for gettin dtb and "loaded" flag */ ++void EXPORT_FUNC (*grub_linux_get_fdt) (void); ++int EXPORT_FUNC (grub_linux_get_loaded) (void); ++void EXPORT_FUNC (grub_linux_set_loaded) (int loaded_flag); ++ + #endif /* ! GRUB_LINUX_CPU_HEADER */ +-- +1.7.10.4 + diff --git a/SOURCES/0003-arm64-Add-xen_boot-module-file.patch b/SOURCES/0003-arm64-Add-xen_boot-module-file.patch new file mode 100644 index 0000000..bbbd227 --- /dev/null +++ b/SOURCES/0003-arm64-Add-xen_boot-module-file.patch @@ -0,0 +1,733 @@ +From f319fbb1efd802c1fd62c788261ff1f6c32d9438 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:21 +0800 +Subject: [PATCH 3/5] arm64: Add xen_boot module file + +grub-core/loader/arm64/xen_boot.c + + - This adds support for the Xen boot on ARM specification for arm64. + - Introduce xen_hypervisor, xen_linux, xen_initrd and xen_xsm + to load different binaries for xen boot; + Introduce xen_module to load common or custom module for xen boot. + - This Xen boot support is a separated module for aarch64, + but reuse the existing code of devicetree in linux module. + +Signed-off-by: Fu Wei fu.wei@linaro.org +--- + grub-core/Makefile.core.def | 7 + + grub-core/loader/arm64/xen_boot.c | 685 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 692 insertions(+) + create mode 100644 grub-core/loader/arm64/xen_boot.c + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index c916246..2c92323 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1662,6 +1662,13 @@ module = { + }; + + module = { ++ name = xen_boot; ++ common = lib/cmdline.c; ++ arm64 = loader/arm64/xen_boot.c; ++ enable = arm64; ++}; ++ ++module = { + name = linux; + x86 = loader/i386/linux.c; + xen = loader/i386/xen.c; +diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c +new file mode 100644 +index 0000000..33a65dd +--- /dev/null ++++ b/grub-core/loader/arm64/xen_boot.c +@@ -0,0 +1,685 @@ ++/* ++ * 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/cache.h> ++#include <grub/charset.h> ++#include <grub/command.h> ++#include <grub/err.h> ++#include <grub/file.h> ++#include <grub/fdt.h> ++#include <grub/linux.h> ++#include <grub/list.h> ++#include <grub/loader.h> ++#include <grub/misc.h> ++#include <grub/mm.h> ++#include <grub/types.h> ++#include <grub/cpu/linux.h> ++#include <grub/efi/efi.h> ++#include <grub/efi/pe32.h> /* required by struct xen_hypervisor_header */ ++#include <grub/i18n.h> ++#include <grub/lib/cmdline.h> ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#define XEN_HYPERVISOR_NAME "xen_hypervisor" ++ ++#define MODULE_DEFAULT_ALIGN (0x0) ++#define MODULE_IMAGE_MIN_ALIGN MODULE_DEFAULT_ALIGN ++#define MODULE_INITRD_MIN_ALIGN MODULE_DEFAULT_ALIGN ++#define MODULE_XSM_MIN_ALIGN MODULE_DEFAULT_ALIGN ++#define MODULE_CUSTOM_MIN_ALIGN MODULE_DEFAULT_ALIGN ++ ++/* #define MODULE_IMAGE_COMPATIBLE "xen,linux-image\0xen,module" ++#define MODULE_INITRD_COMPATIBLE "xen,linux-image\0xen,module" ++#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0xen,module" ++#define MODULE_CUSTOM_COMPATIBLE "xen,module" */ ++#define MODULE_IMAGE_COMPATIBLE "multiboot,kernel\0multiboot,module" ++#define MODULE_INITRD_COMPATIBLE "multiboot,ramdisk\0multiboot,module" ++#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0multiboot,module" ++#define MODULE_CUSTOM_COMPATIBLE "multiboot,module" ++ ++/* This maximum size is defined in Power.org ePAPR V1.1 ++ * https://www.power.org/documentation/epapr-version-1-1/ ++ * 2.2.1.1 Node Name Requirements ++ * node-name@unit-address ++ * 31 + 1(@) + 16(64bit address in hex format) + 1(\0) = 49 ++ */ ++#define FDT_NODE_NAME_MAX_SIZE (49) ++ ++#define ARG_SHIFT(argc, argv) \ ++ do { \ ++ (argc)--; \ ++ (argv)++; \ ++ } while (0) ++ ++struct compat_string_struct ++{ ++ grub_size_t size; ++ const char *compat_string; ++}; ++typedef struct compat_string_struct compat_string_struct_t; ++#define FDT_COMPATIBLE(x) {.size = sizeof(x), .compat_string = (x)} ++ ++enum module_type ++{ ++ MODULE_IMAGE, ++ MODULE_INITRD, ++ MODULE_XSM, ++ MODULE_CUSTOM ++}; ++typedef enum module_type module_type_t; ++ ++struct fdt_node_info ++{ ++ module_type_t type; ++ ++ const char *compat_string; ++ grub_size_t compat_string_size; ++}; ++ ++struct xen_hypervisor_header ++{ ++ struct grub_arm64_linux_kernel_header efi_head; ++ ++ /* This is always PE\0\0. */ ++ grub_uint8_t signature[GRUB_PE32_SIGNATURE_SIZE]; ++ /* The COFF file header. */ ++ struct grub_pe32_coff_header coff_header; ++ /* The Optional header. */ ++ struct grub_pe64_optional_header optional_header; ++}; ++ ++struct xen_boot_binary ++{ ++ struct xen_boot_binary *next; ++ struct xen_boot_binary **prev; ++ const char *name; ++ ++ grub_addr_t start; ++ grub_size_t size; ++ grub_size_t align; ++ ++ char *cmdline; ++ int cmdline_size; ++ ++ struct fdt_node_info node_info; ++}; ++ ++static grub_dl_t my_mod; ++ ++static struct xen_boot_binary *xen_hypervisor; ++static struct xen_boot_binary *module_head; ++static const grub_size_t module_default_align[] = { ++ MODULE_IMAGE_MIN_ALIGN, ++ MODULE_INITRD_MIN_ALIGN, ++ MODULE_XSM_MIN_ALIGN, ++ MODULE_CUSTOM_MIN_ALIGN ++}; ++ ++static void *xen_boot_fdt; ++static const compat_string_struct_t default_compat_string[] = { ++ FDT_COMPATIBLE (MODULE_IMAGE_COMPATIBLE), ++ FDT_COMPATIBLE (MODULE_INITRD_COMPATIBLE), ++ FDT_COMPATIBLE (MODULE_XSM_COMPATIBLE), ++ FDT_COMPATIBLE (MODULE_CUSTOM_COMPATIBLE) ++}; ++ ++static __inline grub_addr_t ++xen_boot_address_align (grub_addr_t start, grub_size_t align) ++{ ++ return (align ? (ALIGN_UP (start, align)) : start); ++} ++ ++/* Parse the option of xen_module command. For now, we support ++ (1) --type <the compatible stream> ++ We also set up the type of module in this function. ++ If there are some "--type" options in the command line, ++ we make a custom compatible stream in this function. */ ++static grub_err_t ++set_module_type (grub_command_t cmd, struct xen_boot_binary *module, ++ int argc, char *argv[], int *file_name_index) ++{ ++ char **compat_string_temp_array; ++ grub_size_t total_size = 0; ++ int num_types = 0, i; ++ char *temp = NULL; ++ ++ *file_name_index = 0; ++ ++ if (!grub_strcmp (cmd->name, "xen_linux")) ++ module->node_info.type = MODULE_IMAGE; ++ else if (!grub_strcmp (cmd->name, "xen_initrd")) ++ module->node_info.type = MODULE_INITRD; ++ else if (!grub_strcmp (cmd->name, "xen_xsm")) ++ module->node_info.type = MODULE_XSM; ++ else if (!grub_strcmp (cmd->name, "xen_module")) ++ module->node_info.type = MODULE_CUSTOM; ++ ++ /* if there are some options we need to process. */ ++ if (module->node_info.type == MODULE_CUSTOM) ++ { ++ compat_string_temp_array = ++ (char **) grub_zalloc (sizeof (char *) * argc); ++ if (!compat_string_temp_array) ++ return grub_errno; ++ /* the module type is set by "--type"(MODULE_CUSTOM) */ ++ while (argc > 2 && !grub_strcmp (argv[0], "--type")) ++ { ++ module->node_info.type = MODULE_CUSTOM; ++ ARG_SHIFT (argc, argv); ++ total_size += grub_strlen (argv[0]) + 1; ++ compat_string_temp_array[num_types++] = argv[0]; ++ ARG_SHIFT (argc, argv); ++ (*file_name_index) += 2; ++ } ++ ++ if (total_size) ++ { ++ module->node_info.compat_string = temp = ++ (char *) grub_zalloc (total_size); ++ if (!temp) ++ { ++ grub_free (compat_string_temp_array); ++ return grub_errno; ++ } ++ ++ module->node_info.compat_string_size = total_size; ++ for (i = 0; num_types > 0; num_types--, i++, temp++) ++ { ++ grub_strcpy (temp, compat_string_temp_array[i]); ++ temp += grub_strlen (compat_string_temp_array[i]); ++ } ++ } ++ else ++ { ++ module->node_info.compat_string = ++ default_compat_string[MODULE_CUSTOM].compat_string; ++ module->node_info.compat_string_size = ++ default_compat_string[MODULE_CUSTOM].size; ++ } ++ ++ grub_free (compat_string_temp_array); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++prepare_xen_hypervisor_params (void) ++{ ++ int chosen_node = 0; ++ int retval; ++ ++ xen_boot_fdt = grub_linux_get_fdt (); ++ if (!xen_boot_fdt) ++ return grub_error (GRUB_ERR_IO, "failed to get FDT"); ++ ++ chosen_node = grub_fdt_find_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 0) ++ chosen_node = grub_fdt_add_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 1) ++ return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); ++ ++ grub_dprintf ("xen_loader", ++ "Xen Hypervisor cmdline : %s @ %p size:%d\n", ++ xen_hypervisor->cmdline, xen_hypervisor->cmdline, ++ xen_hypervisor->cmdline_size); ++ ++ retval = grub_fdt_set_prop (xen_boot_fdt, chosen_node, "bootargs", ++ xen_hypervisor->cmdline, ++ xen_hypervisor->cmdline_size); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, "failed to install/update FDT"); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++prepare_xen_module_params (struct xen_boot_binary *module) ++{ ++ int retval, chosen_node = 0, module_node = 0; ++ char module_name[FDT_NODE_NAME_MAX_SIZE]; ++ ++ retval = grub_snprintf (module_name, FDT_NODE_NAME_MAX_SIZE, "module@%lx", ++ xen_boot_address_align (module->start, ++ module->align)); ++ grub_dprintf ("xen_loader", "Module node name %s \n", module_name); ++ ++ if (retval < (int) sizeof ("module@")) ++ return grub_error (GRUB_ERR_IO, N_("failed to get FDT")); ++ ++ chosen_node = grub_fdt_find_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 0) ++ chosen_node = grub_fdt_add_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 1) ++ return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); ++ ++ module_node = ++ grub_fdt_find_subnode (xen_boot_fdt, chosen_node, module_name); ++ if (module_node < 0) ++ module_node = ++ grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name); ++ ++ retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible", ++ module->node_info.compat_string, ++ (grub_uint32_t) module-> ++ node_info.compat_string_size); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, N_("failed to update FDT")); ++ ++ grub_dprintf ("xen_loader", "Module %s compatible = %s size = 0x%lx\n", ++ module->name, module->node_info.compat_string, ++ module->node_info.compat_string_size); ++ ++ retval = grub_fdt_set_reg64 (xen_boot_fdt, module_node, ++ xen_boot_address_align (module->start, ++ module->align), ++ module->size); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, N_("failed to update FDT")); ++ ++ if (module->cmdline && module->cmdline_size > 0) ++ { ++ grub_dprintf ("xen_loader", ++ "Module %s cmdline : %s @ %p size:%d\n", module->name, ++ module->cmdline, module->cmdline, module->cmdline_size); ++ ++ retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "bootargs", ++ module->cmdline, module->cmdline_size + 1); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, "failed to update FDT"); ++ } ++ else ++ { ++ grub_dprintf ("xen_loader", "Module %s has not bootargs!\n", ++ module->name); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++install_all_params (void) ++{ ++ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; ++ grub_efi_boot_services_t *b; ++ grub_efi_status_t status; ++ ++ b = grub_efi_system_table->boot_services; ++ status = b->install_configuration_table (&fdt_guid, xen_boot_fdt); ++ if (status != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_IO, "failed to install FDT"); ++ ++ grub_dprintf ("xen_loader", ++ "Installed/updated FDT configuration table @ %p\n", ++ xen_boot_fdt); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++clean_all_params (void) ++{ ++ if (xen_boot_fdt) ++ { ++ grub_efi_free_pages ((grub_efi_physical_address_t) xen_boot_fdt, ++ BYTES_TO_PAGES (grub_fdt_get_totalsize ++ (xen_boot_fdt))); ++ xen_boot_fdt = NULL; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++finalize_params_xen_boot (void) ++{ ++ struct xen_boot_binary *module; ++ ++ if (xen_hypervisor) ++ { ++ if (prepare_xen_hypervisor_params () != GRUB_ERR_NONE) ++ goto fail; ++ } ++ else ++ { ++ grub_dprintf ("xen_loader", "Failed to get Xen Hypervisor info!\n"); ++ goto fail; ++ } ++ ++ /* Set module params info */ ++ FOR_LIST_ELEMENTS (module, module_head) ++ { ++ if (module->start && module->size > 0) ++ { ++ grub_dprintf ("xen_loader", "Module %s @ 0x%lx size:0x%lx\n", ++ module->name, ++ xen_boot_address_align (module->start, module->align), ++ module->size); ++ if (prepare_xen_module_params (module) != GRUB_ERR_NONE) ++ goto fail; ++ } ++ else ++ { ++ grub_dprintf ("xen_loader", "Module info error: %s!\n", module->name); ++ goto fail; ++ } ++ } ++ ++ if (install_all_params () == GRUB_ERR_NONE) ++ return GRUB_ERR_NONE; ++ ++fail: ++ clean_all_params (); ++ ++ return grub_error (GRUB_ERR_IO, "failed to install/update FDT"); ++} ++ ++ ++static grub_err_t ++xen_boot (void) ++{ ++ grub_err_t err = finalize_params_xen_boot (); ++ if (err) ++ return err; ++ ++ return grub_arm64_uefi_boot_image (xen_hypervisor->start, ++ xen_hypervisor->size, ++ xen_hypervisor->cmdline); ++} ++ ++static void ++single_binary_unload (struct xen_boot_binary *binary) ++{ ++ if (!binary) ++ return; ++ ++ if (binary->start && binary->size > 0) ++ { ++ grub_efi_free_pages ((grub_efi_physical_address_t) binary->start, ++ BYTES_TO_PAGES (binary->size + binary->align)); ++ } ++ ++ if (binary->cmdline && binary->cmdline_size > 0) ++ { ++ grub_free (binary->cmdline); ++ grub_dprintf ("xen_loader", ++ "Module %s cmdline memory free @ %p size: %d\n", ++ binary->name, binary->cmdline, binary->cmdline_size); ++ } ++ ++ if (binary->node_info.type == MODULE_CUSTOM) ++ grub_free ((void *) binary->node_info.compat_string); ++ ++ if (grub_strcmp (binary->name, XEN_HYPERVISOR_NAME)) ++ grub_list_remove (GRUB_AS_LIST (binary)); ++ ++ grub_dprintf ("xen_loader", ++ "Module %s struct memory free @ %p size: 0x%lx\n", ++ binary->name, binary, sizeof (binary)); ++ grub_free (binary); ++ ++ return; ++} ++ ++static void ++all_binaries_unload (void) ++{ ++ struct xen_boot_binary *binary; ++ ++ FOR_LIST_ELEMENTS (binary, module_head) ++ { ++ single_binary_unload (binary); ++ } ++ ++ if (xen_hypervisor) ++ single_binary_unload (xen_hypervisor); ++ ++ return; ++} ++ ++static grub_err_t ++xen_unload (void) ++{ ++ grub_linux_set_loaded (0); ++ all_binaries_unload (); ++ clean_all_params (); ++ grub_dl_unref (my_mod); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static void ++xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file, ++ int argc, char *argv[]) ++{ ++ binary->size = grub_file_size (file); ++ grub_dprintf ("xen_loader", "Xen_boot %s file size: 0x%lx\n", ++ binary->name, binary->size); ++ ++ binary->start = (grub_addr_t) grub_efi_allocate_pages (0, ++ (BYTES_TO_PAGES ++ (binary->size + ++ binary->align))); ++ if (!binary->start) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ return; ++ } ++ ++ grub_dprintf ("xen_loader", "Xen_boot %s numpages: 0x%lx\n", ++ binary->name, BYTES_TO_PAGES (binary->size + binary->align)); ++ ++ if (grub_file_read (file, (void *) xen_boot_address_align (binary->start, ++ binary->align), ++ binary->size) != (grub_ssize_t) binary->size) ++ { ++ single_binary_unload (binary); ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); ++ return; ++ } ++ ++ if (argc > 1) ++ { ++ binary->cmdline_size = grub_loader_cmdline_size (argc - 1, argv + 1); ++ binary->cmdline = grub_zalloc (binary->cmdline_size); ++ if (!binary->cmdline) ++ { ++ single_binary_unload (binary); ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ return; ++ } ++ grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline, ++ binary->cmdline_size); ++ grub_dprintf ("xen_loader", ++ "Xen_boot %s cmdline @ %p %s, size: %d\n", binary->name, ++ binary->cmdline, binary->cmdline, binary->cmdline_size); ++ } ++ else ++ { ++ binary->cmdline_size = 0; ++ binary->cmdline = NULL; ++ } ++ ++ grub_errno = GRUB_ERR_NONE; ++ return; ++} ++ ++static grub_err_t ++grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[]) ++{ ++ ++ struct xen_boot_binary *module = NULL; ++ int file_name_index = 0; ++ grub_file_t file = 0; ++ ++ if (!argc) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ if (!grub_linux_get_loaded ()) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("you need to load the Xen Hypervisor first")); ++ goto fail; ++ } ++ ++ module = ++ (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary)); ++ if (!module) ++ return grub_errno; ++ ++ /* process all the options and get module type */ ++ if (set_module_type (cmd, module, argc, argv, &file_name_index) != ++ GRUB_ERR_NONE) ++ goto fail; ++ switch (module->node_info.type) ++ { ++ case MODULE_IMAGE: ++ case MODULE_INITRD: ++ case MODULE_XSM: ++ module->node_info.compat_string = ++ default_compat_string[module->node_info.type].compat_string; ++ module->node_info.compat_string_size = ++ default_compat_string[module->node_info.type].size; ++ break; ++ ++ case MODULE_CUSTOM: ++ /* we have set the node_info in set_module_type */ ++ break; ++ ++ default: ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); ++ } ++ module->name = module->node_info.compat_string; ++ module->align = module_default_align[module->node_info.type]; ++ ++ grub_dprintf ("xen_loader", "Init %s module and node info:\n" ++ "compatible %s\ncompat_string_size 0x%lx\n", ++ module->name, module->node_info.compat_string, ++ module->node_info.compat_string_size); ++ ++ file = grub_file_open (argv[file_name_index]); ++ if (!file) ++ goto fail; ++ ++ xen_boot_binary_load (module, file, argc - file_name_index, ++ argv + file_name_index); ++ if (grub_errno == GRUB_ERR_NONE) ++ grub_list_push (GRUB_AS_LIST_P (&module_head), GRUB_AS_LIST (module)); ++ ++fail: ++ if (file) ++ grub_file_close (file); ++ if (grub_errno != GRUB_ERR_NONE) ++ single_binary_unload (module); ++ ++ return grub_errno; ++} ++ ++static grub_err_t ++grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ struct xen_hypervisor_header sh; ++ grub_file_t file = NULL; ++ ++ grub_dl_ref (my_mod); ++ ++ if (!argc) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ file = grub_file_open (argv[0]); ++ if (!file) ++ goto fail; ++ ++ if (grub_file_read (file, &sh, sizeof (sh)) != (long) sizeof (sh)) ++ goto fail; ++ if (grub_arm64_uefi_check_image ++ ((struct grub_arm64_linux_kernel_header *) &sh) != GRUB_ERR_NONE) ++ goto fail; ++ grub_file_seek (file, 0); ++ ++ /* if another module has called grub_loader_set, ++ we need to make sure that another module is unloaded properly */ ++ grub_loader_unset (); ++ ++ xen_hypervisor = ++ (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary)); ++ if (!xen_hypervisor) ++ return grub_errno; ++ ++ xen_hypervisor->name = XEN_HYPERVISOR_NAME; ++ xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment; ++ ++ xen_boot_binary_load (xen_hypervisor, file, argc, argv); ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (xen_boot, xen_unload, 0); ++ grub_linux_set_loaded (1); ++ } ++ ++fail: ++ if (file) ++ grub_file_close (file); ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_linux_set_loaded (0); ++ all_binaries_unload (); ++ grub_dl_unref (my_mod); ++ } ++ ++ return grub_errno; ++} ++ ++static grub_command_t cmd_xen_hypervisor, cmd_xen_module; ++static grub_command_t cmd_xen_linux, cmd_xen_initrd, cmd_xen_xsm; ++ ++GRUB_MOD_INIT (xen_boot) ++{ ++ cmd_xen_hypervisor = ++ grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0, ++ N_("Load a xen hypervisor.")); ++ cmd_xen_linux = ++ grub_register_command ("xen_linux", grub_cmd_xen_module, 0, ++ N_("Load a xen linux kernel for dom0.")); ++ cmd_xen_initrd = ++ grub_register_command ("xen_initrd", grub_cmd_xen_module, 0, ++ N_("Load a xen initrd for dom0.")); ++ cmd_xen_xsm = ++ grub_register_command ("xen_xsm", grub_cmd_xen_module, 0, ++ N_("Load a xen security module.")); ++ cmd_xen_module = ++ grub_register_command ("xen_module", grub_cmd_xen_module, 0, ++ N_("Load a xen module.")); ++ my_mod = mod; ++} ++ ++GRUB_MOD_FINI (xen_boot) ++{ ++ grub_unregister_command (cmd_xen_hypervisor); ++ grub_unregister_command (cmd_xen_linux); ++ grub_unregister_command (cmd_xen_initrd); ++ grub_unregister_command (cmd_xen_xsm); ++ grub_unregister_command (cmd_xen_module); ++} +-- +1.7.10.4 + diff --git a/SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch b/SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch new file mode 100644 index 0000000..bd3a0e6 --- /dev/null +++ b/SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch @@ -0,0 +1,60 @@ +From 05b8c5b34eb6d30131b381145040a4eecb10cba4 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:22 +0800 +Subject: [PATCH 4/5] * util/grub.d/20_linux_xen.in: Add support of the XEN + boot on aarch64 + +This patch adds the support of boot command on aarch64 for XEN: + xen_hypervisor + xen_linux + xen_initrd + +Signed-off-by: Fu Wei fu.wei@linaro.org +--- + util/grub.d/20_linux_xen.in | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index a608435..b8bfc6c 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -120,16 +120,16 @@ linux_entry () + else + xen_rm_opts="no-real-mode edd=off" + fi +- multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} ${xen_rm_opts} ++ ${multiboot_cmd} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} ${xen_rm_opts} + echo '$(echo "$lmessage" | grub_quote)' +- module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} ++ ${module_linux_cmd} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. + message="$(gettext_printf "Loading initial ramdisk ...")" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' +- module --nounzip ${rel_dirname}/${initrd} ++ ${module_initrd_cmd} ${rel_dirname}/${initrd} + EOF + fi + sed "s/^/$submenu_indentation/" << EOF +@@ -183,6 +183,16 @@ case "$machine" in + *) GENKERNEL_ARCH="$machine" ;; + esac + ++if [ "x$machine" != xaarch64 ]; then ++ multiboot_cmd="multiboot" ++ module_linux_cmd="module" ++ module_initrd_cmd="module --nounzip" ++else ++ multiboot_cmd="xen_hypervisor" ++ module_linux_cmd="xen_linux" ++ module_initrd_cmd="xen_initrd" ++fi ++ + # Extra indentation to add to menu entries in a submenu. We're not in a submenu + # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). + submenu_indentation="" +-- +1.7.10.4 + diff --git a/SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch b/SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch new file mode 100644 index 0000000..9baf400 --- /dev/null +++ b/SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch @@ -0,0 +1,94 @@ +From 3aeb819fa8dde62b62e29c157fd1171ff4c5a3c9 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:23 +0800 +Subject: [PATCH 5/5] arm64: Add the introduction of xen boot commands in + docs/grub.texi + + xen_hypervisor + xen_linux + xen_initrd + xen_xsm + xen_module + +Signed-off-by: Fu Wei fu.wei@linaro.org +--- + docs/grub.texi | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/docs/grub.texi b/docs/grub.texi +index 46b9e7f..9c62a1b 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3839,6 +3839,12 @@ you forget a command, you can run the command @command{help} + @comment * vbeinfo:: List available video modes + * verify_detached:: Verify detached digital signature + * videoinfo:: List available video modes ++@comment * xen_*:: Xen boot commands, for arm64 only ++* xen_hypervisor:: Load xen hypervisor binary on arm64 ++* xen_linux:: Load dom0 kernel for xen hypervisor on arm64 ++* xen_initrd:: Load dom0 initrd for xen hypervisor on arm64 ++* xen_xsm:: Load xen security module for xen hypervisor on arm64 ++* xen_module:: Load custom module for xen hypervisor on arm64 + @end menu + + +@@ -5102,6 +5108,56 @@ successfully. If validation fails, it is set to a non-zero value. + List available video modes. If resolution is given, show only matching modes. + @end deffn + ++@node xen_hypervisor ++@subsection xen_hypervisor ++ ++@deffn Command xen_hypervisor file [arguments] @dots{} ++Load a Xen hypervisor binary from @var{file}. The rest of the ++line is passed verbatim as the @dfn{kernel command-line}. Any Xen module must ++be reloaded after using this command (@pxref{xen_module}). ++This command is only available on ARM64 systems. ++@end deffn ++ ++@node xen_linux ++@subsection xen_linux ++ ++@deffn Command xen_linux file [arguments] ++Load a dom0 kernel image for xen hypervisor binary. The rest of the ++line is passed verbatim as the module command line. ++This command is only available on ARM64 systems. ++@end deffn ++ ++@node xen_initrd ++@subsection xen_initrd ++ ++@deffn Command xen_initrd file ++Load a dom0 initrd image for xen hypervisor binary. ++This command is only available on ARM64 systems. ++@end deffn ++ ++@node xen_xsm ++@subsection xen_xsm ++ ++@deffn Command xen_xsm file ++Load a xen security module for xen hypervisor binary. ++This command is only available on ARM64 systems. ++@end deffn ++ ++ ++@node xen_module ++@subsection xen_module ++ ++@deffn Command xen_module [--type <compatible stream>] file [arguments] ++Load a custom module for xen hypervisor binary. The rest of the ++line is passed verbatim as the module command line. ++This command is only available on ARM64 systems. ++ ++--type is an option which allow the module command to take "compatible" string. ++This would override default compatible string:"xen,module". The rest of the ++line is passed verbatim as the module command line. ++This command is only available on ARM64 systems. ++@end deffn ++ + @node Networking commands + @section The list of networking commands + +-- +1.7.10.4 + diff --git a/SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch b/SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch new file mode 100644 index 0000000..c1a899e --- /dev/null +++ b/SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch @@ -0,0 +1,34 @@ +From 1c7ca193728bf99f1a0b8b9ac267fa7f51fc9ec5 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 7 May 2015 15:13:25 +0200 +Subject: [PATCH] fdt.h: Add grub_fdt_set_reg64 macro + +Signed-off-by: Fu Wei fu.wei@linaro.org +--- + include/grub/fdt.h | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/include/grub/fdt.h b/include/grub/fdt.h +index 3016998..fdfca75 100644 +--- a/include/grub/fdt.h ++++ b/include/grub/fdt.h +@@ -117,4 +117,16 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, + grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 8); \ + }) + ++/* Setup "reg" property for ++ * #address-cells = <0x2> ++ * #size-cells = <0x2> ++ */ ++#define grub_fdt_set_reg64(fdt, nodeoffset, addr, size) \ ++({ \ ++ grub_uint64_t reg_64[2]; \ ++ reg_64[0] = grub_cpu_to_be64(addr); \ ++ reg_64[1] = grub_cpu_to_be64(size); \ ++ grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \ ++}) ++ + #endif /* ! GRUB_FDT_HEADER */ +-- +1.7.10.4 + diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec index a7077a1..a0d7f22 100644 --- a/SPECS/grub2.spec +++ b/SPECS/grub2.spec @@ -43,7 +43,7 @@ %undefine _missing_build_ids_terminate_build
Name: grub2 -Epoch: 1 +Epoch: 2 Version: 2.02 Release: 0.16.1%{?dist} Summary: Bootloader with support for Linux, Multiboot and more @@ -54,7 +54,7 @@ URL: http://www.gnu.org/software/grub/ Obsoletes: grub < 1:0.98 Source0: ftp://alpha.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz #Source0: ftp://ftp.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz -Source1: centos.cer +#Source1: centos.cer #(source removed) Source4: http://unifoundry.com/unifont-5.1.20080820.pcf.gz Source5: theme.tar.bz2 @@ -211,7 +211,7 @@ Patch0148: 0001-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch Patch0149: 0001-Add-GRUB_DISABLE_UUID.patch Patch0150: 0001-Allow-fallback-to-include-entries-by-title-not-just-.patch Patch0151: 0001-Initialized-initrd_ctx-so-we-don-t-free-a-random-poi.patch -Patch0152: 0002-Load-arm-with-SB-enabled.patch +#Patch0152: 0002-Load-arm-with-SB-enabled.patch Patch0153: 0001-Fix-up-some-man-pages-rpmdiff-noticed.patch Patch0154: 0001-Try-prefix-if-fw_path-doesn-t-work.patch
@@ -220,6 +220,14 @@ Patch0201: 0001-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch Patch0202: 0002-efinet-open-Simple-Network-Protocol-exclusively.patch Patch0203: 0001-efinet-save-and-restore-SNP-rx-filters.patch
+Patch204: 0001-arm64-Export-useful-functions-from-linux.c.patch +Patch205: 0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch +Patch206: 0003-arm64-Add-xen_boot-module-file.patch +Patch207: 0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch +Patch208: 0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch +Patch209: 0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch + + BuildRequires: flex bison binutils python BuildRequires: ncurses-devel xz-devel bzip2-devel BuildRequires: freetype-devel libusb-devel @@ -352,7 +360,7 @@ GRUB_MODULES=" all_video boot btrfs cat chain configfile echo efifwsetup \ jpeg loadenv lvm mdraid09 mdraid1x minicmd normal part_apple \ part_msdos part_gpt password_pbkdf2 png reboot search \ search_fs_uuid search_fs_file search_label sleep syslinuxcfg \ - test tftp regexp video xfs" + test tftp regexp video xfs xen_boot" %ifarch aarch64 GRUB_MODULES="${GRUB_MODULES} linux" %else
I'm fine with carrying this patch for a little while. At some point this will need to work with Secure Boot. For now we're not signing the shims on aarch64, so it won't impact anything currently...
+1
On 10/01/2015 11:47 AM, Stefano Stabellini wrote:
Backport required patches. Disable Secure Boot for now as it conflicts with the Xen patches. Increase Epoch.
Signed-off-by: Stefano Stabellini stefano.stabellini@eu.citrix.com
...rm64-Export-useful-functions-from-linux.c.patch | 280 ++++++++ ...nd-export-some-accessor-functions-for-xen.patch | 67 ++ SOURCES/0003-arm64-Add-xen_boot-module-file.patch | 733 +++++++++++++++++++++ ...-20_linux_xen.in-Add-support-of-the-XEN-b.patch | 60 ++ ...he-introduction-of-xen-boot-commands-in-d.patch | 94 +++ .../0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch | 34 + SPECS/grub2.spec | 16 +- 7 files changed, 1280 insertions(+), 4 deletions(-) create mode 100644 SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch create mode 100644 SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch create mode 100644 SOURCES/0003-arm64-Add-xen_boot-module-file.patch create mode 100644 SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch create mode 100644 SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch create mode 100644 SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch
diff --git a/SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch b/SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch new file mode 100644 index 0000000..88ccc12 --- /dev/null +++ b/SOURCES/0001-arm64-Export-useful-functions-from-linux.c.patch @@ -0,0 +1,280 @@ +From cfce76bbd91696e83bb15a180fd51a0fd1c31f83 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 7 May 2015 15:11:04 +0200 +Subject: [PATCH 1/5] arm64: Export useful functions from linux.c
+Signed-off-by: Fu Wei fu.wei@linaro.org
+Conflicts:
- gentpl.py
+---
- gentpl.py | 2 +-
- grub-core/loader/arm64/linux.c | 59 ++++++++++++++++++++--------------------
- grub-core/loader/i386/linux.c | 11 ++++----
- grub-core/loader/linux.c | 3 +-
- include/grub/arm64/linux.h | 11 ++++++++
- 5 files changed, 49 insertions(+), 37 deletions(-)
+diff --git a/gentpl.py b/gentpl.py +index bdcae1a..136b484 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -753,7 +753,7 @@ def image(defn, platform):
- if test x$(TARGET_APPLE_LINKER) = x1; then \
- $(MACHO2IMG) $< $@; \
- else \
+- $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; \ ++ $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .hash -R .dynsym -R .dynstr -R .rel.text $< $@; \
- fi
- """)
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c +index 9d15aad..18c34c8 100644 +--- a/grub-core/loader/arm64/linux.c ++++ b/grub-core/loader/arm64/linux.c +@@ -33,12 +33,6 @@
- GRUB_MOD_LICENSE ("GPLv3+");
+-#define GRUB_EFI_PAGE_SHIFT 12 +-#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) +-#define GRUB_EFI_PE_MAGIC 0x5A4D +- +-static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; +-
- static grub_dl_t my_mod;
- static int loaded;
+@@ -58,6 +52,7 @@ static void *
- get_firmware_fdt (void)
- {
- grub_efi_configuration_table_t *tables;
++ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
- void *firmware_fdt = NULL;
- unsigned int i;
+@@ -75,8 +70,8 @@ get_firmware_fdt (void)
- return firmware_fdt;
- }
+-static void +-get_fdt (void) ++void * ++grub_linux_get_fdt (void)
- {
- void *raw_fdt;
- grub_size_t size;
+@@ -99,7 +94,7 @@ get_fdt (void)
- grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size);
- fdt = grub_efi_allocate_pages (0, BYTES_TO_PAGES (size));
- if (!fdt)
+- return; ++ return NULL;
- if (raw_fdt)
{
+@@ -110,10 +105,11 @@ get_fdt (void)
{
grub_fdt_create_empty_tree (fdt, size);
}
++ return fdt;
- }
+-static grub_err_t +-check_kernel (struct grub_arm64_linux_kernel_header *lh) ++grub_err_t ++grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header * lh)
- {
- if (lh->magic != GRUB_ARM64_LINUX_MAGIC)
return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
+@@ -131,14 +127,14 @@ check_kernel (struct grub_arm64_linux_kernel_header *lh)
- }
- static grub_err_t
+-finalize_params (void) ++finalize_params_linux (void)
- {
- grub_efi_boot_services_t *b;
++ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
- grub_efi_status_t status;
- int node, retval;
+- get_fdt (); +- if (!fdt) ++ if (!grub_linux_get_fdt ())
goto failure;
- node = grub_fdt_find_subnode (fdt, 0, "chosen");
+@@ -240,21 +236,16 @@ out:
- return grub_errno;
- }
+-static grub_err_t +-grub_linux_boot (void) ++grub_err_t ++grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args)
- {
- grub_efi_memory_mapped_device_path_t *mempath;
- grub_efi_handle_t image_handle;
- grub_efi_boot_services_t *b;
- grub_efi_status_t status;
+- grub_err_t retval;
- grub_efi_loaded_image_t *loaded_image;
- int len;
+- retval = finalize_params(); +- if (retval != GRUB_ERR_NONE) +- return retval; +-
- mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
- if (!mempath)
return grub_errno;
+@@ -263,8 +254,8 @@ grub_linux_boot (void)
- mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
- mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
- mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
+- mempath[0].start_address = (grub_addr_t) kernel_addr; +- mempath[0].end_address = (grub_addr_t) kernel_addr + kernel_size; ++ mempath[0].start_address = addr; ++ mempath[0].end_address = addr + size;
- mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
- mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+@@ -273,16 +264,16 @@ grub_linux_boot (void)
- b = grub_efi_system_table->boot_services;
- status = b->load_image (0, grub_efi_image_handle,
(grub_efi_device_path_t *) mempath,
+- kernel_addr, kernel_size, &image_handle); ++ (void *) addr, size, &image_handle);
- if (status != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
+- grub_dprintf ("linux", "linux command line: '%s'\n", linux_args); ++ grub_dprintf ("linux", "linux command line: '%s'\n", args);
- /* Convert command line to UCS-2 */
- loaded_image = grub_efi_get_loaded_image (image_handle);
- loaded_image->load_options_size = len =
+- (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t); ++ (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
- loaded_image->load_options =
grub_efi_allocate_pages (0,
BYTES_TO_PAGES (loaded_image->load_options_size));
+@@ -291,9 +282,9 @@ grub_linux_boot (void)
- loaded_image->load_options_size =
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
+- (grub_uint8_t *) linux_args, len, NULL); ++ (grub_uint8_t *) args, len, NULL);
+- grub_dprintf("linux", "starting image %p\n", image_handle); ++ grub_dprintf ("linux", "starting image %p\n", image_handle);
- status = b->start_image (image_handle, 0, NULL);
- /* When successful, not reached */
+@@ -305,6 +296,16 @@ grub_linux_boot (void)
- }
- static grub_err_t
++grub_linux_boot (void) ++{ ++ if (finalize_params_linux () != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr, ++ kernel_size, linux_args)); ++} ++ ++static grub_err_t
- grub_linux_unload (void)
- {
- grub_dl_unref (my_mod);
+@@ -400,7 +401,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
return grub_errno;
+- if (check_kernel (&lh) != GRUB_ERR_NONE) ++ if (grub_arm64_uefi_check_image (&lh) != GRUB_ERR_NONE)
goto fail;
- grub_loader_unset();
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 31fb91e..434ddca 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -69,7 +69,6 @@ static grub_addr_t prot_mode_target;
- static void *initrd_mem;
- static grub_addr_t initrd_mem_target;
- static grub_size_t prot_init_space;
+-static grub_uint32_t initrd_pages;
- static struct grub_relocator *relocator = NULL;
- static void *efi_mmap_buf;
- static grub_size_t maximal_cmdline_size;
+@@ -1046,7 +1045,7 @@ static grub_err_t
- grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
- {
+- grub_size_t size = 0; ++ grub_size_t size = 0, aligned_size = 0;
- grub_addr_t addr_min, addr_max;
- grub_addr_t addr;
- grub_err_t err;
+@@ -1068,8 +1067,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail;
- size = grub_get_initrd_size (&initrd_ctx);
+- +- initrd_pages = (page_align (size) >> 12); ++ aligned_size = ALIGN_UP (size, 4096);
- /* Get the highest address available for the initrd. */
- if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
+@@ -1097,7 +1095,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
- addr_min = (grub_addr_t) prot_mode_target + prot_init_space;
- /* Put the initrd as high as possible, 4KiB aligned. */
+- addr = (addr_max - size) & ~0xFFF; ++ addr = (addr_max - aligned_size) & ~0xFFF;
- if (addr < addr_min)
{
+@@ -1108,7 +1106,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
- {
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (relocator, &ch,
+- addr_min, addr, size, 0x1000, ++ addr_min, addr, aligned_size, ++ 0x1000,
GRUB_RELOCATOR_PREFERENCE_HIGH,
1);
if (err)
+diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h +index 864e5dc..65796d9 100644 +--- a/include/grub/arm64/linux.h ++++ b/include/grub/arm64/linux.h +@@ -23,6 +23,10 @@
- #define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */
++#define GRUB_EFI_PAGE_SHIFT 12 ++#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) ++#define GRUB_EFI_PE_MAGIC 0x5A4D ++
- /* From linux/Documentation/arm64/booting.txt */
- struct grub_arm64_linux_kernel_header
- {
+@@ -38,4 +42,11 @@ struct grub_arm64_linux_kernel_header
- grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
- };
++/* Declare the functions for getting dtb and checking/booting image */ ++void *grub_linux_get_fdt (void); ++grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header ++ *lh); ++grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, ++ char *args); ++
- #endif /* ! GRUB_LINUX_CPU_HEADER */
+-- +1.7.10.4
diff --git a/SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch b/SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch new file mode 100644 index 0000000..8caf670 --- /dev/null +++ b/SOURCES/0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch @@ -0,0 +1,67 @@ +From 484f6f757c6ce8419bd6037d6e67ae339d243720 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:20 +0800 +Subject: [PATCH 2/5] arm64: Add and export some accessor functions for xen
- boot
+Add accessor functions of "loaded" flag in +grub-core/loader/arm64/linux.c.
+Export accessor functions of "loaded" flag and +grub_linux_get_fdt function in include/grub/arm64/linux.h.
+Purpose: Reuse the existing code of devicetree in linux module.
+Signed-off-by: Fu Wei fu.wei@linaro.org +---
- grub-core/loader/arm64/linux.c | 13 +++++++++++++
- include/grub/arm64/linux.h | 6 +++++-
- 2 files changed, 18 insertions(+), 1 deletion(-)
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c +index 18c34c8..038300e 100644 +--- a/grub-core/loader/arm64/linux.c ++++ b/grub-core/loader/arm64/linux.c +@@ -48,6 +48,19 @@ static grub_addr_t initrd_end;
- static void *loaded_fdt;
- static void *fdt;
++/* The accessor functions for "loaded" flag */ ++int ++grub_linux_get_loaded (void) ++{ ++ return loaded; ++} ++ ++void ++grub_linux_set_loaded (int loaded_flag) ++{ ++ loaded = loaded_flag; ++} ++
- static void *
- get_firmware_fdt (void)
- {
+diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h +index 65796d9..20058f3 100644 +--- a/include/grub/arm64/linux.h ++++ b/include/grub/arm64/linux.h +@@ -43,10 +43,14 @@ struct grub_arm64_linux_kernel_header
- };
- /* Declare the functions for getting dtb and checking/booting image */
+-void *grub_linux_get_fdt (void);
- grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header
*lh);
- grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size,
char *args);
++/* Export the accessor functions for gettin dtb and "loaded" flag */ ++void EXPORT_FUNC (*grub_linux_get_fdt) (void); ++int EXPORT_FUNC (grub_linux_get_loaded) (void); ++void EXPORT_FUNC (grub_linux_set_loaded) (int loaded_flag); ++
- #endif /* ! GRUB_LINUX_CPU_HEADER */
+-- +1.7.10.4
diff --git a/SOURCES/0003-arm64-Add-xen_boot-module-file.patch b/SOURCES/0003-arm64-Add-xen_boot-module-file.patch new file mode 100644 index 0000000..bbbd227 --- /dev/null +++ b/SOURCES/0003-arm64-Add-xen_boot-module-file.patch @@ -0,0 +1,733 @@ +From f319fbb1efd802c1fd62c788261ff1f6c32d9438 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:21 +0800 +Subject: [PATCH 3/5] arm64: Add xen_boot module file
+grub-core/loader/arm64/xen_boot.c
- This adds support for the Xen boot on ARM specification for arm64.
- Introduce xen_hypervisor, xen_linux, xen_initrd and xen_xsm
- to load different binaries for xen boot;
- Introduce xen_module to load common or custom module for xen boot.
- This Xen boot support is a separated module for aarch64,
- but reuse the existing code of devicetree in linux module.
+Signed-off-by: Fu Wei fu.wei@linaro.org +---
- grub-core/Makefile.core.def | 7 +
- grub-core/loader/arm64/xen_boot.c | 685 +++++++++++++++++++++++++++++++++++++
- 2 files changed, 692 insertions(+)
- create mode 100644 grub-core/loader/arm64/xen_boot.c
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index c916246..2c92323 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1662,6 +1662,13 @@ module = {
- };
- module = {
++ name = xen_boot; ++ common = lib/cmdline.c; ++ arm64 = loader/arm64/xen_boot.c; ++ enable = arm64; ++}; ++ ++module = {
- name = linux;
- x86 = loader/i386/linux.c;
- xen = loader/i386/xen.c;
+diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c +new file mode 100644 +index 0000000..33a65dd +--- /dev/null ++++ b/grub-core/loader/arm64/xen_boot.c +@@ -0,0 +1,685 @@ ++/* ++ * 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/cache.h> ++#include <grub/charset.h> ++#include <grub/command.h> ++#include <grub/err.h> ++#include <grub/file.h> ++#include <grub/fdt.h> ++#include <grub/linux.h> ++#include <grub/list.h> ++#include <grub/loader.h> ++#include <grub/misc.h> ++#include <grub/mm.h> ++#include <grub/types.h> ++#include <grub/cpu/linux.h> ++#include <grub/efi/efi.h> ++#include <grub/efi/pe32.h> /* required by struct xen_hypervisor_header */ ++#include <grub/i18n.h> ++#include <grub/lib/cmdline.h> ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#define XEN_HYPERVISOR_NAME "xen_hypervisor" ++ ++#define MODULE_DEFAULT_ALIGN (0x0) ++#define MODULE_IMAGE_MIN_ALIGN MODULE_DEFAULT_ALIGN ++#define MODULE_INITRD_MIN_ALIGN MODULE_DEFAULT_ALIGN ++#define MODULE_XSM_MIN_ALIGN MODULE_DEFAULT_ALIGN ++#define MODULE_CUSTOM_MIN_ALIGN MODULE_DEFAULT_ALIGN ++ ++/* #define MODULE_IMAGE_COMPATIBLE "xen,linux-image\0xen,module" ++#define MODULE_INITRD_COMPATIBLE "xen,linux-image\0xen,module" ++#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0xen,module" ++#define MODULE_CUSTOM_COMPATIBLE "xen,module" */ ++#define MODULE_IMAGE_COMPATIBLE "multiboot,kernel\0multiboot,module" ++#define MODULE_INITRD_COMPATIBLE "multiboot,ramdisk\0multiboot,module" ++#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0multiboot,module" ++#define MODULE_CUSTOM_COMPATIBLE "multiboot,module" ++ ++/* This maximum size is defined in Power.org ePAPR V1.1 ++ * https://www.power.org/documentation/epapr-version-1-1/ ++ * 2.2.1.1 Node Name Requirements ++ * node-name@unit-address ++ * 31 + 1(@) + 16(64bit address in hex format) + 1(\0) = 49 ++ */ ++#define FDT_NODE_NAME_MAX_SIZE (49) ++ ++#define ARG_SHIFT(argc, argv) \ ++ do { \ ++ (argc)--; \ ++ (argv)++; \ ++ } while (0) ++ ++struct compat_string_struct ++{ ++ grub_size_t size; ++ const char *compat_string; ++}; ++typedef struct compat_string_struct compat_string_struct_t; ++#define FDT_COMPATIBLE(x) {.size = sizeof(x), .compat_string = (x)} ++ ++enum module_type ++{ ++ MODULE_IMAGE, ++ MODULE_INITRD, ++ MODULE_XSM, ++ MODULE_CUSTOM ++}; ++typedef enum module_type module_type_t; ++ ++struct fdt_node_info ++{ ++ module_type_t type; ++ ++ const char *compat_string; ++ grub_size_t compat_string_size; ++}; ++ ++struct xen_hypervisor_header ++{ ++ struct grub_arm64_linux_kernel_header efi_head; ++ ++ /* This is always PE\0\0. */ ++ grub_uint8_t signature[GRUB_PE32_SIGNATURE_SIZE]; ++ /* The COFF file header. */ ++ struct grub_pe32_coff_header coff_header; ++ /* The Optional header. */ ++ struct grub_pe64_optional_header optional_header; ++}; ++ ++struct xen_boot_binary ++{ ++ struct xen_boot_binary *next; ++ struct xen_boot_binary **prev; ++ const char *name; ++ ++ grub_addr_t start; ++ grub_size_t size; ++ grub_size_t align; ++ ++ char *cmdline; ++ int cmdline_size; ++ ++ struct fdt_node_info node_info; ++}; ++ ++static grub_dl_t my_mod; ++ ++static struct xen_boot_binary *xen_hypervisor; ++static struct xen_boot_binary *module_head; ++static const grub_size_t module_default_align[] = { ++ MODULE_IMAGE_MIN_ALIGN, ++ MODULE_INITRD_MIN_ALIGN, ++ MODULE_XSM_MIN_ALIGN, ++ MODULE_CUSTOM_MIN_ALIGN ++}; ++ ++static void *xen_boot_fdt; ++static const compat_string_struct_t default_compat_string[] = { ++ FDT_COMPATIBLE (MODULE_IMAGE_COMPATIBLE), ++ FDT_COMPATIBLE (MODULE_INITRD_COMPATIBLE), ++ FDT_COMPATIBLE (MODULE_XSM_COMPATIBLE), ++ FDT_COMPATIBLE (MODULE_CUSTOM_COMPATIBLE) ++}; ++ ++static __inline grub_addr_t ++xen_boot_address_align (grub_addr_t start, grub_size_t align) ++{ ++ return (align ? (ALIGN_UP (start, align)) : start); ++} ++ ++/* Parse the option of xen_module command. For now, we support ++ (1) --type <the compatible stream> ++ We also set up the type of module in this function. ++ If there are some "--type" options in the command line, ++ we make a custom compatible stream in this function. */ ++static grub_err_t ++set_module_type (grub_command_t cmd, struct xen_boot_binary *module, ++ int argc, char *argv[], int *file_name_index) ++{ ++ char **compat_string_temp_array; ++ grub_size_t total_size = 0; ++ int num_types = 0, i; ++ char *temp = NULL; ++ ++ *file_name_index = 0; ++ ++ if (!grub_strcmp (cmd->name, "xen_linux")) ++ module->node_info.type = MODULE_IMAGE; ++ else if (!grub_strcmp (cmd->name, "xen_initrd")) ++ module->node_info.type = MODULE_INITRD; ++ else if (!grub_strcmp (cmd->name, "xen_xsm")) ++ module->node_info.type = MODULE_XSM; ++ else if (!grub_strcmp (cmd->name, "xen_module")) ++ module->node_info.type = MODULE_CUSTOM; ++ ++ /* if there are some options we need to process. */ ++ if (module->node_info.type == MODULE_CUSTOM) ++ { ++ compat_string_temp_array = ++ (char **) grub_zalloc (sizeof (char *) * argc); ++ if (!compat_string_temp_array) ++ return grub_errno; ++ /* the module type is set by "--type"(MODULE_CUSTOM) */ ++ while (argc > 2 && !grub_strcmp (argv[0], "--type")) ++ { ++ module->node_info.type = MODULE_CUSTOM; ++ ARG_SHIFT (argc, argv); ++ total_size += grub_strlen (argv[0]) + 1; ++ compat_string_temp_array[num_types++] = argv[0]; ++ ARG_SHIFT (argc, argv); ++ (*file_name_index) += 2; ++ } ++ ++ if (total_size) ++ { ++ module->node_info.compat_string = temp = ++ (char *) grub_zalloc (total_size); ++ if (!temp) ++ { ++ grub_free (compat_string_temp_array); ++ return grub_errno; ++ } ++ ++ module->node_info.compat_string_size = total_size; ++ for (i = 0; num_types > 0; num_types--, i++, temp++) ++ { ++ grub_strcpy (temp, compat_string_temp_array[i]); ++ temp += grub_strlen (compat_string_temp_array[i]); ++ } ++ } ++ else ++ { ++ module->node_info.compat_string = ++ default_compat_string[MODULE_CUSTOM].compat_string; ++ module->node_info.compat_string_size = ++ default_compat_string[MODULE_CUSTOM].size; ++ } ++ ++ grub_free (compat_string_temp_array); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++prepare_xen_hypervisor_params (void) ++{ ++ int chosen_node = 0; ++ int retval; ++ ++ xen_boot_fdt = grub_linux_get_fdt (); ++ if (!xen_boot_fdt) ++ return grub_error (GRUB_ERR_IO, "failed to get FDT"); ++ ++ chosen_node = grub_fdt_find_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 0) ++ chosen_node = grub_fdt_add_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 1) ++ return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); ++ ++ grub_dprintf ("xen_loader", ++ "Xen Hypervisor cmdline : %s @ %p size:%d\n", ++ xen_hypervisor->cmdline, xen_hypervisor->cmdline, ++ xen_hypervisor->cmdline_size); ++ ++ retval = grub_fdt_set_prop (xen_boot_fdt, chosen_node, "bootargs", ++ xen_hypervisor->cmdline, ++ xen_hypervisor->cmdline_size); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, "failed to install/update FDT"); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++prepare_xen_module_params (struct xen_boot_binary *module) ++{ ++ int retval, chosen_node = 0, module_node = 0; ++ char module_name[FDT_NODE_NAME_MAX_SIZE]; ++ ++ retval = grub_snprintf (module_name, FDT_NODE_NAME_MAX_SIZE, "module@%lx", ++ xen_boot_address_align (module->start, ++ module->align)); ++ grub_dprintf ("xen_loader", "Module node name %s \n", module_name); ++ ++ if (retval < (int) sizeof ("module@")) ++ return grub_error (GRUB_ERR_IO, N_("failed to get FDT")); ++ ++ chosen_node = grub_fdt_find_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 0) ++ chosen_node = grub_fdt_add_subnode (xen_boot_fdt, 0, "chosen"); ++ if (chosen_node < 1) ++ return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); ++ ++ module_node = ++ grub_fdt_find_subnode (xen_boot_fdt, chosen_node, module_name); ++ if (module_node < 0) ++ module_node = ++ grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name); ++ ++ retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible", ++ module->node_info.compat_string, ++ (grub_uint32_t) module-> ++ node_info.compat_string_size); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, N_("failed to update FDT")); ++ ++ grub_dprintf ("xen_loader", "Module %s compatible = %s size = 0x%lx\n", ++ module->name, module->node_info.compat_string, ++ module->node_info.compat_string_size); ++ ++ retval = grub_fdt_set_reg64 (xen_boot_fdt, module_node, ++ xen_boot_address_align (module->start, ++ module->align), ++ module->size); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, N_("failed to update FDT")); ++ ++ if (module->cmdline && module->cmdline_size > 0) ++ { ++ grub_dprintf ("xen_loader", ++ "Module %s cmdline : %s @ %p size:%d\n", module->name, ++ module->cmdline, module->cmdline, module->cmdline_size); ++ ++ retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "bootargs", ++ module->cmdline, module->cmdline_size + 1); ++ if (retval) ++ return grub_error (GRUB_ERR_IO, "failed to update FDT"); ++ } ++ else ++ { ++ grub_dprintf ("xen_loader", "Module %s has not bootargs!\n", ++ module->name); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++install_all_params (void) ++{ ++ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; ++ grub_efi_boot_services_t *b; ++ grub_efi_status_t status; ++ ++ b = grub_efi_system_table->boot_services; ++ status = b->install_configuration_table (&fdt_guid, xen_boot_fdt); ++ if (status != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_IO, "failed to install FDT"); ++ ++ grub_dprintf ("xen_loader", ++ "Installed/updated FDT configuration table @ %p\n", ++ xen_boot_fdt); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++clean_all_params (void) ++{ ++ if (xen_boot_fdt) ++ { ++ grub_efi_free_pages ((grub_efi_physical_address_t) xen_boot_fdt, ++ BYTES_TO_PAGES (grub_fdt_get_totalsize ++ (xen_boot_fdt))); ++ xen_boot_fdt = NULL; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++finalize_params_xen_boot (void) ++{ ++ struct xen_boot_binary *module; ++ ++ if (xen_hypervisor) ++ { ++ if (prepare_xen_hypervisor_params () != GRUB_ERR_NONE) ++ goto fail; ++ } ++ else ++ { ++ grub_dprintf ("xen_loader", "Failed to get Xen Hypervisor info!\n"); ++ goto fail; ++ } ++ ++ /* Set module params info */ ++ FOR_LIST_ELEMENTS (module, module_head) ++ { ++ if (module->start && module->size > 0) ++ { ++ grub_dprintf ("xen_loader", "Module %s @ 0x%lx size:0x%lx\n", ++ module->name, ++ xen_boot_address_align (module->start, module->align), ++ module->size); ++ if (prepare_xen_module_params (module) != GRUB_ERR_NONE) ++ goto fail; ++ } ++ else ++ { ++ grub_dprintf ("xen_loader", "Module info error: %s!\n", module->name); ++ goto fail; ++ } ++ } ++ ++ if (install_all_params () == GRUB_ERR_NONE) ++ return GRUB_ERR_NONE; ++ ++fail: ++ clean_all_params (); ++ ++ return grub_error (GRUB_ERR_IO, "failed to install/update FDT"); ++} ++ ++ ++static grub_err_t ++xen_boot (void) ++{ ++ grub_err_t err = finalize_params_xen_boot (); ++ if (err) ++ return err; ++ ++ return grub_arm64_uefi_boot_image (xen_hypervisor->start, ++ xen_hypervisor->size, ++ xen_hypervisor->cmdline); ++} ++ ++static void ++single_binary_unload (struct xen_boot_binary *binary) ++{ ++ if (!binary) ++ return; ++ ++ if (binary->start && binary->size > 0) ++ { ++ grub_efi_free_pages ((grub_efi_physical_address_t) binary->start, ++ BYTES_TO_PAGES (binary->size + binary->align)); ++ } ++ ++ if (binary->cmdline && binary->cmdline_size > 0) ++ { ++ grub_free (binary->cmdline); ++ grub_dprintf ("xen_loader", ++ "Module %s cmdline memory free @ %p size: %d\n", ++ binary->name, binary->cmdline, binary->cmdline_size); ++ } ++ ++ if (binary->node_info.type == MODULE_CUSTOM) ++ grub_free ((void *) binary->node_info.compat_string); ++ ++ if (grub_strcmp (binary->name, XEN_HYPERVISOR_NAME)) ++ grub_list_remove (GRUB_AS_LIST (binary)); ++ ++ grub_dprintf ("xen_loader", ++ "Module %s struct memory free @ %p size: 0x%lx\n", ++ binary->name, binary, sizeof (binary)); ++ grub_free (binary); ++ ++ return; ++} ++ ++static void ++all_binaries_unload (void) ++{ ++ struct xen_boot_binary *binary; ++ ++ FOR_LIST_ELEMENTS (binary, module_head) ++ { ++ single_binary_unload (binary); ++ } ++ ++ if (xen_hypervisor) ++ single_binary_unload (xen_hypervisor); ++ ++ return; ++} ++ ++static grub_err_t ++xen_unload (void) ++{ ++ grub_linux_set_loaded (0); ++ all_binaries_unload (); ++ clean_all_params (); ++ grub_dl_unref (my_mod); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static void ++xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file, ++ int argc, char *argv[]) ++{ ++ binary->size = grub_file_size (file); ++ grub_dprintf ("xen_loader", "Xen_boot %s file size: 0x%lx\n", ++ binary->name, binary->size); ++ ++ binary->start = (grub_addr_t) grub_efi_allocate_pages (0, ++ (BYTES_TO_PAGES ++ (binary->size + ++ binary->align))); ++ if (!binary->start) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ return; ++ } ++ ++ grub_dprintf ("xen_loader", "Xen_boot %s numpages: 0x%lx\n", ++ binary->name, BYTES_TO_PAGES (binary->size + binary->align)); ++ ++ if (grub_file_read (file, (void *) xen_boot_address_align (binary->start, ++ binary->align), ++ binary->size) != (grub_ssize_t) binary->size) ++ { ++ single_binary_unload (binary); ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); ++ return; ++ } ++ ++ if (argc > 1) ++ { ++ binary->cmdline_size = grub_loader_cmdline_size (argc - 1, argv + 1); ++ binary->cmdline = grub_zalloc (binary->cmdline_size); ++ if (!binary->cmdline) ++ { ++ single_binary_unload (binary); ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ return; ++ } ++ grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline, ++ binary->cmdline_size); ++ grub_dprintf ("xen_loader", ++ "Xen_boot %s cmdline @ %p %s, size: %d\n", binary->name, ++ binary->cmdline, binary->cmdline, binary->cmdline_size); ++ } ++ else ++ { ++ binary->cmdline_size = 0; ++ binary->cmdline = NULL; ++ } ++ ++ grub_errno = GRUB_ERR_NONE; ++ return; ++} ++ ++static grub_err_t ++grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[]) ++{ ++ ++ struct xen_boot_binary *module = NULL; ++ int file_name_index = 0; ++ grub_file_t file = 0; ++ ++ if (!argc) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ if (!grub_linux_get_loaded ()) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("you need to load the Xen Hypervisor first")); ++ goto fail; ++ } ++ ++ module = ++ (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary)); ++ if (!module) ++ return grub_errno; ++ ++ /* process all the options and get module type */ ++ if (set_module_type (cmd, module, argc, argv, &file_name_index) != ++ GRUB_ERR_NONE) ++ goto fail; ++ switch (module->node_info.type) ++ { ++ case MODULE_IMAGE: ++ case MODULE_INITRD: ++ case MODULE_XSM: ++ module->node_info.compat_string = ++ default_compat_string[module->node_info.type].compat_string; ++ module->node_info.compat_string_size = ++ default_compat_string[module->node_info.type].size; ++ break; ++ ++ case MODULE_CUSTOM: ++ /* we have set the node_info in set_module_type */ ++ break; ++ ++ default: ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); ++ } ++ module->name = module->node_info.compat_string; ++ module->align = module_default_align[module->node_info.type]; ++ ++ grub_dprintf ("xen_loader", "Init %s module and node info:\n" ++ "compatible %s\ncompat_string_size 0x%lx\n", ++ module->name, module->node_info.compat_string, ++ module->node_info.compat_string_size); ++ ++ file = grub_file_open (argv[file_name_index]); ++ if (!file) ++ goto fail; ++ ++ xen_boot_binary_load (module, file, argc - file_name_index, ++ argv + file_name_index); ++ if (grub_errno == GRUB_ERR_NONE) ++ grub_list_push (GRUB_AS_LIST_P (&module_head), GRUB_AS_LIST (module)); ++ ++fail: ++ if (file) ++ grub_file_close (file); ++ if (grub_errno != GRUB_ERR_NONE) ++ single_binary_unload (module); ++ ++ return grub_errno; ++} ++ ++static grub_err_t ++grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ struct xen_hypervisor_header sh; ++ grub_file_t file = NULL; ++ ++ grub_dl_ref (my_mod); ++ ++ if (!argc) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ file = grub_file_open (argv[0]); ++ if (!file) ++ goto fail; ++ ++ if (grub_file_read (file, &sh, sizeof (sh)) != (long) sizeof (sh)) ++ goto fail; ++ if (grub_arm64_uefi_check_image ++ ((struct grub_arm64_linux_kernel_header *) &sh) != GRUB_ERR_NONE) ++ goto fail; ++ grub_file_seek (file, 0); ++ ++ /* if another module has called grub_loader_set, ++ we need to make sure that another module is unloaded properly */ ++ grub_loader_unset (); ++ ++ xen_hypervisor = ++ (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary)); ++ if (!xen_hypervisor) ++ return grub_errno; ++ ++ xen_hypervisor->name = XEN_HYPERVISOR_NAME; ++ xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment; ++ ++ xen_boot_binary_load (xen_hypervisor, file, argc, argv); ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (xen_boot, xen_unload, 0); ++ grub_linux_set_loaded (1); ++ } ++ ++fail: ++ if (file) ++ grub_file_close (file); ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_linux_set_loaded (0); ++ all_binaries_unload (); ++ grub_dl_unref (my_mod); ++ } ++ ++ return grub_errno; ++} ++ ++static grub_command_t cmd_xen_hypervisor, cmd_xen_module; ++static grub_command_t cmd_xen_linux, cmd_xen_initrd, cmd_xen_xsm; ++ ++GRUB_MOD_INIT (xen_boot) ++{ ++ cmd_xen_hypervisor = ++ grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0, ++ N_("Load a xen hypervisor.")); ++ cmd_xen_linux = ++ grub_register_command ("xen_linux", grub_cmd_xen_module, 0, ++ N_("Load a xen linux kernel for dom0.")); ++ cmd_xen_initrd = ++ grub_register_command ("xen_initrd", grub_cmd_xen_module, 0, ++ N_("Load a xen initrd for dom0.")); ++ cmd_xen_xsm = ++ grub_register_command ("xen_xsm", grub_cmd_xen_module, 0, ++ N_("Load a xen security module.")); ++ cmd_xen_module = ++ grub_register_command ("xen_module", grub_cmd_xen_module, 0, ++ N_("Load a xen module.")); ++ my_mod = mod; ++} ++ ++GRUB_MOD_FINI (xen_boot) ++{ ++ grub_unregister_command (cmd_xen_hypervisor); ++ grub_unregister_command (cmd_xen_linux); ++ grub_unregister_command (cmd_xen_initrd); ++ grub_unregister_command (cmd_xen_xsm); ++ grub_unregister_command (cmd_xen_module); ++} +-- +1.7.10.4
diff --git a/SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch b/SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch new file mode 100644 index 0000000..bd3a0e6 --- /dev/null +++ b/SOURCES/0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch @@ -0,0 +1,60 @@ +From 05b8c5b34eb6d30131b381145040a4eecb10cba4 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:22 +0800 +Subject: [PATCH 4/5] * util/grub.d/20_linux_xen.in: Add support of the XEN
- boot on aarch64
+This patch adds the support of boot command on aarch64 for XEN:
- xen_hypervisor
- xen_linux
- xen_initrd
+Signed-off-by: Fu Wei fu.wei@linaro.org +---
- util/grub.d/20_linux_xen.in | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
+diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index a608435..b8bfc6c 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -120,16 +120,16 @@ linux_entry ()
else
xen_rm_opts="no-real-mode edd=off"
fi
+- multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} ${xen_rm_opts} ++ ${multiboot_cmd} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} ${xen_rm_opts}
- echo '$(echo "$lmessage" | grub_quote)'
+- module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} ++ ${module_linux_cmd} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
- EOF
- if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
sed "s/^/$submenu_indentation/" << EOF
- echo '$(echo "$message" | grub_quote)'
+- module --nounzip ${rel_dirname}/${initrd} ++ ${module_initrd_cmd} ${rel_dirname}/${initrd}
- EOF
- fi
- sed "s/^/$submenu_indentation/" << EOF
+@@ -183,6 +183,16 @@ case "$machine" in
*) GENKERNEL_ARCH="$machine" ;;
- esac
++if [ "x$machine" != xaarch64 ]; then ++ multiboot_cmd="multiboot" ++ module_linux_cmd="module" ++ module_initrd_cmd="module --nounzip" ++else ++ multiboot_cmd="xen_hypervisor" ++ module_linux_cmd="xen_linux" ++ module_initrd_cmd="xen_initrd" ++fi ++
- # Extra indentation to add to menu entries in a submenu. We're not in a submenu
- # yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
- submenu_indentation=""
+-- +1.7.10.4
diff --git a/SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch b/SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch new file mode 100644 index 0000000..9baf400 --- /dev/null +++ b/SOURCES/0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch @@ -0,0 +1,94 @@ +From 3aeb819fa8dde62b62e29c157fd1171ff4c5a3c9 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 23 Jul 2015 13:16:23 +0800 +Subject: [PATCH 5/5] arm64: Add the introduction of xen boot commands in
- docs/grub.texi
- xen_hypervisor
- xen_linux
- xen_initrd
- xen_xsm
- xen_module
+Signed-off-by: Fu Wei fu.wei@linaro.org +---
- docs/grub.texi | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 56 insertions(+)
+diff --git a/docs/grub.texi b/docs/grub.texi +index 46b9e7f..9c62a1b 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3839,6 +3839,12 @@ you forget a command, you can run the command @command{help}
- @comment * vbeinfo:: List available video modes
- verify_detached:: Verify detached digital signature
- videoinfo:: List available video modes
++@comment * xen_*:: Xen boot commands, for arm64 only ++* xen_hypervisor:: Load xen hypervisor binary on arm64 ++* xen_linux:: Load dom0 kernel for xen hypervisor on arm64 ++* xen_initrd:: Load dom0 initrd for xen hypervisor on arm64 ++* xen_xsm:: Load xen security module for xen hypervisor on arm64 ++* xen_module:: Load custom module for xen hypervisor on arm64
- @end menu
+@@ -5102,6 +5108,56 @@ successfully. If validation fails, it is set to a non-zero value.
- List available video modes. If resolution is given, show only matching modes.
- @end deffn
++@node xen_hypervisor ++@subsection xen_hypervisor ++ ++@deffn Command xen_hypervisor file [arguments] @dots{} ++Load a Xen hypervisor binary from @var{file}. The rest of the ++line is passed verbatim as the @dfn{kernel command-line}. Any Xen module must ++be reloaded after using this command (@pxref{xen_module}). ++This command is only available on ARM64 systems. ++@end deffn ++ ++@node xen_linux ++@subsection xen_linux ++ ++@deffn Command xen_linux file [arguments] ++Load a dom0 kernel image for xen hypervisor binary. The rest of the ++line is passed verbatim as the module command line. ++This command is only available on ARM64 systems. ++@end deffn ++ ++@node xen_initrd ++@subsection xen_initrd ++ ++@deffn Command xen_initrd file ++Load a dom0 initrd image for xen hypervisor binary. ++This command is only available on ARM64 systems. ++@end deffn ++ ++@node xen_xsm ++@subsection xen_xsm ++ ++@deffn Command xen_xsm file ++Load a xen security module for xen hypervisor binary. ++This command is only available on ARM64 systems. ++@end deffn ++ ++ ++@node xen_module ++@subsection xen_module ++ ++@deffn Command xen_module [--type <compatible stream>] file [arguments] ++Load a custom module for xen hypervisor binary. The rest of the ++line is passed verbatim as the module command line. ++This command is only available on ARM64 systems. ++ ++--type is an option which allow the module command to take "compatible" string. ++This would override default compatible string:"xen,module". The rest of the ++line is passed verbatim as the module command line. ++This command is only available on ARM64 systems. ++@end deffn ++
- @node Networking commands
- @section The list of networking commands
+-- +1.7.10.4
diff --git a/SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch b/SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch new file mode 100644 index 0000000..c1a899e --- /dev/null +++ b/SOURCES/0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch @@ -0,0 +1,34 @@ +From 1c7ca193728bf99f1a0b8b9ac267fa7f51fc9ec5 Mon Sep 17 00:00:00 2001 +From: Fu Wei fu.wei@linaro.org +Date: Thu, 7 May 2015 15:13:25 +0200 +Subject: [PATCH] fdt.h: Add grub_fdt_set_reg64 macro
+Signed-off-by: Fu Wei fu.wei@linaro.org +---
- include/grub/fdt.h | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
+diff --git a/include/grub/fdt.h b/include/grub/fdt.h +index 3016998..fdfca75 100644 +--- a/include/grub/fdt.h ++++ b/include/grub/fdt.h +@@ -117,4 +117,16 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name,
- grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 8); \
- })
++/* Setup "reg" property for ++ * #address-cells = <0x2> ++ * #size-cells = <0x2> ++ */ ++#define grub_fdt_set_reg64(fdt, nodeoffset, addr, size) \ ++({ \ ++ grub_uint64_t reg_64[2]; \ ++ reg_64[0] = grub_cpu_to_be64(addr); \ ++ reg_64[1] = grub_cpu_to_be64(size); \ ++ grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \ ++}) ++
- #endif /* ! GRUB_FDT_HEADER */
+-- +1.7.10.4
diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec index a7077a1..a0d7f22 100644 --- a/SPECS/grub2.spec +++ b/SPECS/grub2.spec @@ -43,7 +43,7 @@ %undefine _missing_build_ids_terminate_build
Name: grub2 -Epoch: 1 +Epoch: 2 Version: 2.02 Release: 0.16.1%{?dist} Summary: Bootloader with support for Linux, Multiboot and more @@ -54,7 +54,7 @@ URL: http://www.gnu.org/software/grub/ Obsoletes: grub < 1:0.98 Source0: ftp://alpha.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz #Source0: ftp://ftp.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz -Source1: centos.cer +#Source1: centos.cer #(source removed) Source4: http://unifoundry.com/unifont-5.1.20080820.pcf.gz Source5: theme.tar.bz2 @@ -211,7 +211,7 @@ Patch0148: 0001-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch Patch0149: 0001-Add-GRUB_DISABLE_UUID.patch Patch0150: 0001-Allow-fallback-to-include-entries-by-title-not-just-.patch Patch0151: 0001-Initialized-initrd_ctx-so-we-don-t-free-a-random-poi.patch -Patch0152: 0002-Load-arm-with-SB-enabled.patch +#Patch0152: 0002-Load-arm-with-SB-enabled.patch Patch0153: 0001-Fix-up-some-man-pages-rpmdiff-noticed.patch Patch0154: 0001-Try-prefix-if-fw_path-doesn-t-work.patch
@@ -220,6 +220,14 @@ Patch0201: 0001-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch Patch0202: 0002-efinet-open-Simple-Network-Protocol-exclusively.patch Patch0203: 0001-efinet-save-and-restore-SNP-rx-filters.patch
+Patch204: 0001-arm64-Export-useful-functions-from-linux.c.patch +Patch205: 0002-arm64-Add-and-export-some-accessor-functions-for-xen.patch +Patch206: 0003-arm64-Add-xen_boot-module-file.patch +Patch207: 0004-util-grub.d-20_linux_xen.in-Add-support-of-the-XEN-b.patch +Patch208: 0005-arm64-Add-the-introduction-of-xen-boot-commands-in-d.patch +Patch209: 0006-fdt.h-Add-grub_fdt_set_reg64-macro.patch
BuildRequires: flex bison binutils python BuildRequires: ncurses-devel xz-devel bzip2-devel BuildRequires: freetype-devel libusb-devel @@ -352,7 +360,7 @@ GRUB_MODULES=" all_video boot btrfs cat chain configfile echo efifwsetup \ jpeg loadenv lvm mdraid09 mdraid1x minicmd normal part_apple \ part_msdos part_gpt password_pbkdf2 png reboot search \ search_fs_uuid search_fs_file search_label sleep syslinuxcfg \
test tftp regexp video xfs"
test tftp regexp video xfs xen_boot"
%ifarch aarch64 GRUB_MODULES="${GRUB_MODULES} linux" %else