[Arm-dev] [PATCH] Add Xen multiboot support to grub2 for aarch64

Thu Oct 1 16:56:49 UTC 2015
Jim Perrin <jperrin at centos.org>

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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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
> ++ at 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
> + 
> ++ at node xen_hypervisor
> ++ at subsection xen_hypervisor
> ++
> ++ at 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.
> ++ at end deffn
> ++
> ++ at node xen_linux
> ++ at subsection xen_linux
> ++
> ++ at 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.
> ++ at end deffn
> ++
> ++ at node xen_initrd
> ++ at subsection xen_initrd
> ++
> ++ at deffn Command xen_initrd file
> ++Load a dom0 initrd image for xen hypervisor binary.
> ++This command is only available on ARM64 systems.
> ++ at end deffn
> ++
> ++ at node xen_xsm
> ++ at subsection xen_xsm
> ++
> ++ at deffn Command xen_xsm file
> ++Load a xen security module for xen hypervisor binary.
> ++This command is only available on ARM64 systems.
> ++ at end deffn
> ++
> ++
> ++ at node xen_module
> ++ at subsection xen_module
> ++
> ++ at 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.
> ++ at 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 at 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 at 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
> 

-- 
Jim Perrin
The CentOS Project | http://www.centos.org
twitter: @BitIntegrity | GPG Key: FA09AD77