xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot
       [not found] <=fu.wei@linaro.org>
@ 2015-07-13  8:53 ` fu.wei
  2015-07-13  8:53   ` [PATCH v2 1/3] arm64: Add Xen boot support file fu.wei
                     ` (4 more replies)
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
  2016-02-25  6:50 ` [PATCH v2 0/4] arm64,xen: add xen_boot support into grup-mkconfig fu.wei
  2 siblings, 5 replies; 40+ messages in thread
From: fu.wei @ 2015-07-13  8:53 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

  - This adds support for the Xen boot on ARM specification for arm64.

  - The implementation for Xen is following  <Multiboot on ARM Specification>:
    http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
    and xen/docs/misc/arm/device-tree/booting.txt in Xen source code.

  - The multiboot/module commands have existed, so we use 
    xen_hypervisor/xen_module instead.

  - This Xen boot support is built into linux module for aarch64,
    and can not be used alone.

  - Adding this functionality to the existing "linux" module is for
    reusing the existing code of devicetree.

  - Add the support of xen_hypervisor/xen_module commands in util/grub.d/20_linux_xen.in

  - Add the introduction of xen_hypervisor/xen_module commands in docs/grub.texi

  - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
    https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB

Changelog:
v2: remove the patches which have been accepted.
    according to Vladimir's suggestion, change the command manes
    and relevant code:
        multiboot-->xen_hypervisor
        module-->xen_module
    improve the option parsing support for xen_hypervisor/xen_module commands.
    add a patch for adding xen_hypervisor/xen_module support
    in util/grub.d/20_linux_xen.in.
    update docs/grub.texi patch for the new command names.

v1: The first version upstream patchset to grub-devel mailing list


Fu Wei (3):
  arm64: Add Xen boot support file
  * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  arm64: Add the introduction of xen_hypervisor/xen_module command in
    docs/grub.texi

 docs/grub.texi                    |  27 ++
 grub-core/Makefile.core.def       |   1 +
 grub-core/loader/arm64/linux.c    |   6 +
 grub-core/loader/arm64/xen_boot.c | 615 ++++++++++++++++++++++++++++++++++++++
 include/grub/arm64/xen_boot.h     | 115 +++++++
 util/grub.d/20_linux_xen.in       |  14 +-
 6 files changed, 775 insertions(+), 3 deletions(-)
 create mode 100644 grub-core/loader/arm64/xen_boot.c
 create mode 100644 include/grub/arm64/xen_boot.h

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v2 1/3] arm64: Add Xen boot support file
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
@ 2015-07-13  8:53   ` fu.wei
  2015-07-15 16:18     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-07-13  8:53   ` [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support fu.wei
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: fu.wei @ 2015-07-13  8:53 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

This patch adds Xen boot support file:
grub-core/loader/arm64/xen_boot.c
include/grub/arm64/xen_boot.h

This patch also adds commands register code and hearder file into
grub-core/loader/arm64/linux.c

  - This adds support for the Xen boot on ARM specification for arm64.
  - The implementation for Xen is following  <Multiboot on ARM Specification>:
      http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
    and xen/docs/misc/arm/device-tree/booting.txt in Xen source code.
  - The multiboot/module commands have existed,
    so we use xen_hypervisor/xen_module instead.
  - This Xen boot support is built into linux module for aarch64.
  - Adding this functionality to the existing "linux" module is for
    reusing the existing code of devicetree.

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 grub-core/Makefile.core.def       |   1 +
 grub-core/loader/arm64/linux.c    |   6 +
 grub-core/loader/arm64/xen_boot.c | 615 ++++++++++++++++++++++++++++++++++++++
 include/grub/arm64/xen_boot.h     | 115 +++++++
 4 files changed, 737 insertions(+)
 create mode 100644 grub-core/loader/arm64/xen_boot.c
 create mode 100644 include/grub/arm64/xen_boot.h

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index a6101de..01f8261 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1659,6 +1659,7 @@ module = {
   ia64_efi = loader/ia64/efi/linux.c;
   arm = loader/arm/linux.c;
   arm64 = loader/arm64/linux.c;
+  arm64 = loader/arm64/xen_boot.c;
   fdt = lib/fdt.c;
   common = loader/linux.c;
   common = lib/cmdline.c;
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 987f5b9..7ae9bde 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -26,6 +26,7 @@
 #include <grub/mm.h>
 #include <grub/types.h>
 #include <grub/cpu/linux.h>
+#include <grub/cpu/xen_boot.h>
 #include <grub/efi/efi.h>
 #include <grub/efi/pe32.h>
 #include <grub/i18n.h>
@@ -477,6 +478,9 @@ GRUB_MOD_INIT (linux)
   cmd_devicetree =
     grub_register_command ("devicetree", grub_cmd_devicetree, 0,
 			   N_("Load DTB file."));
+
+  grub_arm64_linux_register_xen_boot_command (mod, &loaded);
+
   my_mod = mod;
 }
 
@@ -485,4 +489,6 @@ GRUB_MOD_FINI (linux)
   grub_unregister_command (cmd_linux);
   grub_unregister_command (cmd_initrd);
   grub_unregister_command (cmd_devicetree);
+
+  grub_arm64_linux_unregister_xen_boot_command ();
 }
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
new file mode 100644
index 0000000..23bd00e
--- /dev/null
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -0,0 +1,615 @@
+/*
+ *  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/cpu/xen_boot.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/pe32.h>
+#include <grub/i18n.h>
+#include <grub/lib/cmdline.h>
+
+static grub_dl_t linux_mod;
+static int *loaded;
+
+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_OTHER_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_OTHER_COMPATIBLE)
+};
+
+
+/* Parse all the options of xen_module command. For now, we support
+   (1) --type <the compatible stream>
+   (2) --nounzip
+   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 (struct xen_boot_binary *module, int argc, char *argv[],
+		 int *file_name_index)
+{
+  char **compat_string_temp_array =
+    (char **) grub_zalloc (sizeof (char *) * argc);
+  static module_type_t default_type = MODULE_IMAGE;
+  grub_size_t total_size = 0;
+  int num_types = 0, i;
+  char *temp = NULL;
+
+  *file_name_index = 0;
+
+  /* if there are some options we need to process. */
+  while (argc > 1 && !grub_strncmp (argv[0], "--", 2))
+    {
+      if (!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;
+	}
+      else if (!grub_strcmp (argv[0], "--nounzip"))
+	{
+	  grub_file_filter_disable_compression ();
+	  ARG_SHIFT (argc, argv);
+	  (*file_name_index) += 1;
+	}
+      else			/* we can add more options process code here. */
+	{
+	  grub_dprintf ("xen_boot_loader",
+			"Unknown option %s, skip.\n", argv[0]);
+	  ARG_SHIFT (argc, argv);
+	  (*file_name_index) += 1;
+	}
+    }
+
+  /* To prevent some wrong command lines using "--type" option */
+  if (!argc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+
+  /* For the default module type :
+     The implementation is following <Multiboot on ARM Specification>:
+     Each module will be given a default compatibility property
+     based on the order in which the modules are added.
+     The 1st module: compatible = "multiboot,kernel", "multiboot,module"
+     The 2nd module: compatible = "multiboot,ramdisk", "multiboot,module"
+     All subsequent modules: compatible = "multiboot,module"
+     But this order will NOT be interfered with "--type"(MODULE_CUSTOM)
+     For more detail, please refer to:
+     http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot */
+  if (module->node_info.type != MODULE_CUSTOM)
+    {
+      /* the module type is set by the load order */
+      module->node_info.type = default_type;
+      switch (default_type)
+	{
+	case MODULE_IMAGE:
+	  default_type = MODULE_INITRD;
+	  break;
+
+	case MODULE_INITRD:
+	  default_type = MODULE_OTHER;
+	  break;
+
+	case MODULE_OTHER:
+	  break;
+
+	default:
+	  default_type = MODULE_IMAGE;	/* error, reset the type */
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
+	}
+    }
+  else
+    {
+      /* the module type is set by "--type"(MODULE_CUSTOM) */
+      module->node_info.compat_string = temp =
+	(char *) grub_zalloc (total_size);
+      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]);
+	}
+    }
+
+  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_BAD_OS, "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_BAD_OS, "failed to get chosen node in FDT");
+
+  grub_dprintf ("xen_boot_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_BAD_OS, "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_boot_loader", "Module node name %s \n", module_name);
+
+  if (retval < (int) sizeof ("module@"))
+    return grub_error (GRUB_ERR_BAD_OS, 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_BAD_OS, "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_BAD_OS, N_("failed to update FDT"));
+
+  grub_dprintf ("xen_boot_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_BAD_OS, N_("failed to update FDT"));
+
+  if (module->cmdline && module->cmdline_size > 0)
+    {
+      grub_dprintf ("xen_boot_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_BAD_OS, "failed to update FDT");
+    }
+  else
+    {
+      grub_dprintf ("xen_boot_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_BAD_OS, "failed to install FDT");
+
+  grub_dprintf ("xen_boot_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_boot_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_boot_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_boot_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_BAD_OS, "failed to install/update FDT");
+}
+
+
+static grub_err_t
+xen_boot (void)
+{
+  if (finalize_params_xen_boot () != GRUB_ERR_NONE)
+    return grub_errno;
+
+  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 && 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 && binary->cmdline && binary->cmdline_size > 0)
+    {
+      grub_free (binary->cmdline);
+      grub_dprintf ("xen_boot_loader",
+		    "Module %s cmdline memory free @ %p size: %d\n",
+		    binary->name, binary->cmdline, binary->cmdline_size);
+    }
+
+  if (binary)
+    {
+      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_boot_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)
+{
+  *loaded = 0;
+  all_binaries_unload ();
+  clean_all_params ();
+  grub_dl_unref (linux_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+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_boot_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)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+
+  grub_dprintf ("xen_boot_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);
+      return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+			 argv[0]);
+    }
+
+  /* Skip the xen_boot binary file name */
+  ARG_SHIFT (argc, argv);
+
+  if (argc > 0)
+    {
+      binary->cmdline_size = grub_loader_cmdline_size (argc, argv);
+      binary->cmdline = grub_zalloc (binary->cmdline_size);
+      if (!binary->cmdline)
+	{
+	  single_binary_unload (binary);
+	  return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+	}
+      grub_create_loader_cmdline (argc, argv, binary->cmdline,
+				  binary->cmdline_size);
+      grub_dprintf ("xen_boot_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;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_xen_module (grub_command_t cmd __attribute__ ((unused)),
+		     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 (!*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_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+
+  /* process all the options and get module type */
+  if (set_module_type (module, argc, argv, &file_name_index) != GRUB_ERR_NONE)
+    goto fail;
+  switch (module->node_info.type)
+    {
+    case MODULE_IMAGE:
+    case MODULE_INITRD:
+    case MODULE_OTHER:
+      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_boot_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;
+
+  grub_errno = 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 (linux_mod);
+
+  if (!argc)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+      goto fail;
+    }
+
+  /* For now, we don't support any option in xen_hypervisor command.
+     If there are some options, we skip them. */
+  while (argc > 1 && !grub_strncmp (argv[0], "--", 2))
+    {
+      grub_dprintf ("xen_boot_loader", "Unknown option %s, skip.\n", argv[0]);
+      ARG_SHIFT (argc, argv);
+    }
+
+  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);
+
+  grub_loader_unset ();
+
+  xen_hypervisor =
+    (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary));
+  if (!xen_hypervisor)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+
+  xen_hypervisor->name = XEN_HYPERVISOR_NAME;
+  xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
+
+  grub_errno = xen_boot_binary_load (xen_hypervisor, file, argc, argv);
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (xen_boot, xen_unload, 0);
+      *loaded = 1;
+    }
+
+fail:
+  if (file)
+    grub_file_close (file);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      *loaded = 0;
+      all_binaries_unload ();
+      grub_dl_unref (linux_mod);
+    }
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_xen_hypervisor, cmd_xen_module;
+
+void
+grub_arm64_linux_register_xen_boot_command (grub_dl_t mod, int *linux_loaded)
+{
+  cmd_xen_hypervisor =
+    grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0,
+			   N_("Load a xen hypervisor."));
+  cmd_xen_module =
+    grub_register_command ("xen_module", grub_cmd_xen_module, 0,
+			   N_("Load a xen module."));
+  linux_mod = mod;
+  loaded = linux_loaded;
+}
+
+void
+grub_arm64_linux_unregister_xen_boot_command (void)
+{
+  grub_unregister_command (cmd_xen_hypervisor);
+  grub_unregister_command (cmd_xen_module);
+}
diff --git a/include/grub/arm64/xen_boot.h b/include/grub/arm64/xen_boot.h
new file mode 100644
index 0000000..8e8f6cb
--- /dev/null
+++ b/include/grub/arm64/xen_boot.h
@@ -0,0 +1,115 @@
+/*
+ *  xen_boot.h - Xen boot header file for Xen boot via FDT
+ *  on AArch64 architecture.
+ *  Copyright (C) 2014  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef XEN_BOOT_HEADER
+#define XEN_BOOT_HEADER 1
+
+#include <grub/list.h>
+#include <grub/types.h>
+#include <grub/efi/pe32.h>	/* required by struct xen_hypervisor_header */
+
+#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_OTHER_MIN_ALIGN  MODULE_DEFAULT_ALIGN
+#define MODULE_CUSTOM_MIN_ALIGN  MODULE_DEFAULT_ALIGN
+
+#define MODULE_IMAGE_COMPATIBLE  "multiboot,kernel\0multiboot,module"
+#define MODULE_INITRD_COMPATIBLE  "multiboot,ramdisk\0multiboot,module"
+#define MODULE_OTHER_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_OTHER,
+  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;
+};
+
+void grub_arm64_linux_register_xen_boot_command (grub_dl_t mod, int *loaded);
+void grub_arm64_linux_unregister_xen_boot_command (void);
+
+static __inline grub_addr_t
+xen_boot_address_align (grub_addr_t start, grub_size_t align)
+{
+  return (align ? (ALIGN_UP (start, align)) : start);
+}
+
+#endif /* ! XEN_BOOT_HEADER */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
  2015-07-13  8:53   ` [PATCH v2 1/3] arm64: Add Xen boot support file fu.wei
@ 2015-07-13  8:53   ` fu.wei
  2015-07-14  3:53     ` Andrei Borzenkov
  2015-07-13  8:54   ` [PATCH v2 3/3] arm64: Add the introduction of Xen boot command fu.wei
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: fu.wei @ 2015-07-13  8:53 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

This patch adds the support of boot command on arm64 for XEN:
    xen_hypervisor
    xen_module

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 util/grub.d/20_linux_xen.in | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
index f532fb9..b52c50d 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_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_cmd}	--nounzip   ${rel_dirname}/${initrd}
 EOF
   fi
   sed "s/^/$submenu_indentation/" << EOF
@@ -185,6 +185,14 @@ case "$machine" in
     *) GENKERNEL_ARCH="$machine" ;;
 esac
 
+if [ "x$machine" != xaarch64 ]; then
+	multiboot_cmd="multiboot"
+	module_cmd="module"
+else
+	multiboot_cmd="xen_hypervisor"
+	module_cmd="xen_module"
+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.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 3/3] arm64: Add the introduction of Xen boot command
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
  2015-07-13  8:53   ` [PATCH v2 1/3] arm64: Add Xen boot support file fu.wei
  2015-07-13  8:53   ` [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support fu.wei
@ 2015-07-13  8:54   ` fu.wei
  2015-07-14  9:29   ` [Xen-devel] [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot Ian Campbell
  2015-07-15 15:56   ` Vladimir 'φ-coder/phcoder' Serbinenko
  4 siblings, 0 replies; 40+ messages in thread
From: fu.wei @ 2015-07-13  8:54 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

This patch adds the introduction of xen_hypervisor/xen_module commands
in docs/grub.texi

Signed-off-by: Fu Wei <fu.wei@linaro.org>
---
 docs/grub.texi | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/docs/grub.texi b/docs/grub.texi
index b9f41a7..3bd2fc3 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -3839,6 +3839,9 @@ 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_hypervisor/xen_module::   Xen boot command, for arm64 only
+* xen_hypervisor::              Load xen hypervisor binary on arm64
+* xen_module::                  Load module for xen hypervisor on arm64
 @end menu
 
 
@@ -5102,6 +5105,30 @@ 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_module
+@subsection xen_module
+
+@deffn Command xen_module [--type <compatible stream>] file [arguments]
+Load a 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 for this module.
+See @uref{http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot},
+to obtain more information.
+@end deffn
+
 @node Networking commands
 @section The list of networking commands
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support
  2015-07-13  8:53   ` [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support fu.wei
@ 2015-07-14  3:53     ` Andrei Borzenkov
  2015-07-14  9:41       ` Ian Campbell
  2015-07-14 13:09       ` Fu Wei
  0 siblings, 2 replies; 40+ messages in thread
From: Andrei Borzenkov @ 2015-07-14  3:53 UTC (permalink / raw)
  To: fu.wei
  Cc: grub-devel, xen-devel, Ian.Campbell, stefano.stabellini, phcoder,
	leif.lindholm, ryan.harkin, linaro-uefi, jcm

В Mon, 13 Jul 2015 16:53:59 +0800
fu.wei@linaro.org пишет:

> From: Fu Wei <fu.wei@linaro.org>
> 
> This patch adds the support of boot command on arm64 for XEN:
>     xen_hypervisor
>     xen_module
> 
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
>  util/grub.d/20_linux_xen.in | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
> index f532fb9..b52c50d 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_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_cmd}	--nounzip   ${rel_dirname}/${initrd}
>  EOF
>    fi
>    sed "s/^/$submenu_indentation/" << EOF
> @@ -185,6 +185,14 @@ case "$machine" in
>      *) GENKERNEL_ARCH="$machine" ;;
>  esac
>  
> +if [ "x$machine" != xaarch64 ]; then
> +	multiboot_cmd="multiboot"
> +	module_cmd="module"
> +else
> +	multiboot_cmd="xen_hypervisor"
> +	module_cmd="xen_module"
> +fi
> +

Strictly speaking, this is boot-time decision. As mentioned by
Vladimir, better would be to provide alias xen_hypervisor and
xen_module in multiboot for platforms supporting Xen (is MIPS really
supported?) and use it consistently.

>  # 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=""


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Xen-devel] [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
                     ` (2 preceding siblings ...)
  2015-07-13  8:54   ` [PATCH v2 3/3] arm64: Add the introduction of Xen boot command fu.wei
@ 2015-07-14  9:29   ` Ian Campbell
  2015-07-14 11:56     ` Fu Wei
  2015-07-15 15:56   ` Vladimir 'φ-coder/phcoder' Serbinenko
  4 siblings, 1 reply; 40+ messages in thread
From: Ian Campbell @ 2015-07-14  9:29 UTC (permalink / raw)
  To: fu.wei
  Cc: grub-devel, xen-devel, stefano.stabellini, arvidjaar, jcm,
	linaro-uefi, leif.lindholm, ryan.harkin, phcoder

On Mon, 2015-07-13 at 16:53 +0800, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
>   - This adds support for the Xen boot on ARM specification for arm64.

I have used this to PXE boot Xen on a mustang board. My (handcrafted)
grub.cfg was:

        set default=0
        set timeout=5
        menuentry 'pxe multiboot xen' {
          echo "xen_hypervisor /trap/xen.efi"
          xen_hypervisor /trap/xen.efi conswitch=x watchdog console=dtuart dtuart=/soc/serial@1c020000 dom0_mem=512M,max:512M
          echo "xen_module /trap/vmlinuz"
          xen_module /trap/vmlinuz root=/dev/mapper/trap--vg-root ro  console=hvc0
          echo "xen_module /trap/initrd.gz"
          xen_module /trap/initrd.gz
          boot
        }
        
Tested-by: Ian Campbell <ian.campbell@citrix.com>

I didn't yet try a local boot from hdd since I'm sure it would work
equivalently and there still seems to be some discussion around how the
update-grub side should fit together.

Thanks!

Ian.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support
  2015-07-14  3:53     ` Andrei Borzenkov
@ 2015-07-14  9:41       ` Ian Campbell
  2015-07-14 15:23         ` [Xen-devel] " Konrad Rzeszutek Wilk
  2015-07-14 13:09       ` Fu Wei
  1 sibling, 1 reply; 40+ messages in thread
From: Ian Campbell @ 2015-07-14  9:41 UTC (permalink / raw)
  To: Andrei Borzenkov
  Cc: grub-devel, xen-devel, jcm, stefano.stabellini, phcoder,
	leif.lindholm, ryan.harkin, linaro-uefi, fu.wei

On Tue, 2015-07-14 at 06:53 +0300, Andrei Borzenkov wrote:
> > +if [ "x$machine" != xaarch64 ]; then
> > +	multiboot_cmd="multiboot"
> > +	module_cmd="module"
> > +else
> > +	multiboot_cmd="xen_hypervisor"
> > +	module_cmd="xen_module"
> > +fi
> > +
> 
> Strictly speaking, this is boot-time decision. As mentioned by
> Vladimir, better would be to provide alias xen_hypervisor and
> xen_module in multiboot for platforms supporting Xen (is MIPS really
> supported?) and use it consistently.

I had been thinking of this the other way around, e.g. on platforms
which support Xen but not multiboot1 "multiboot" would be added as an
alias for xen_hypervisor.

However so long as grub-mkconfig (via 20_linux_xen) work for everyone
and that peoples existing hand-crafted x86/multiboot/Xen grub.cfg's
continue to work then I think having the alias go either way would be
fine.

BTW I had been going to suggest a function at the grub.cfg level which
dispatched to the correct command, but I suppose an actual alias is
better.

Ian.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Xen-devel] [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot
  2015-07-14  9:29   ` [Xen-devel] [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot Ian Campbell
@ 2015-07-14 11:56     ` Fu Wei
  0 siblings, 0 replies; 40+ messages in thread
From: Fu Wei @ 2015-07-14 11:56 UTC (permalink / raw)
  To: Ian Campbell
  Cc: The development of GNU GRUB, xen-devel, Stefano Stabellini,
	Andrei Borzenkov, Jon Masters, Linaro UEFI Mailman List,
	Leif Lindholm, Ryan Harkin, Vladimir Serbinenko

Hi Ian,
Great thanks for your testing, will add your tested-by in my next patchset :-)

On 14 July 2015 at 17:29, Ian Campbell <ian.campbell@citrix.com> wrote:
> On Mon, 2015-07-13 at 16:53 +0800, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>>   - This adds support for the Xen boot on ARM specification for arm64.
>
> I have used this to PXE boot Xen on a mustang board. My (handcrafted)
> grub.cfg was:
>
>         set default=0
>         set timeout=5
>         menuentry 'pxe multiboot xen' {
>           echo "xen_hypervisor /trap/xen.efi"
>           xen_hypervisor /trap/xen.efi conswitch=x watchdog console=dtuart dtuart=/soc/serial@1c020000 dom0_mem=512M,max:512M
>           echo "xen_module /trap/vmlinuz"
>           xen_module /trap/vmlinuz root=/dev/mapper/trap--vg-root ro  console=hvc0
>           echo "xen_module /trap/initrd.gz"
>           xen_module /trap/initrd.gz
>           boot
>         }
>
> Tested-by: Ian Campbell <ian.campbell@citrix.com>
>
> I didn't yet try a local boot from hdd since I'm sure it would work
> equivalently and there still seems to be some discussion around how the
> update-grub side should fit together.
>
> Thanks!
>
> Ian.
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support
  2015-07-14  3:53     ` Andrei Borzenkov
  2015-07-14  9:41       ` Ian Campbell
@ 2015-07-14 13:09       ` Fu Wei
  2015-07-15 16:24         ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-07-14 13:09 UTC (permalink / raw)
  To: Andrei Borzenkov
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Vladimir Serbinenko, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List, Jon Masters

Hi Andrei,

Great thanks for your review.

So Are you suggesting this:
(1) in util/grub.d/20_linux_xen.in, we only use xen_hypervisor/xen_module.
(2) in xen_boot.c, we only register command xen_hypervisor/xen_module.
(3) in grub-core/loader/i386/xen.c, we *add*
---------------
  cmd_xen_hypervisort = grub_register_command ("xen_hypervisor", grub_cmd_xen,
0, N_("Load Linux."));
  cmd_xen_module = grub_register_command ("xen_module", grub_cmd_module,
     0, N_("Load module."));
---------------
(4)in grub-core/loader/multiboot.c, we *add*
---------------
#if defined (__i386__) || defined (__aarch64__)
  cmd_xen_hypervisort =
    grub_register_command ("xen_hypervisor", grub_cmd_multiboot,
  0, N_("Load a multiboot kernel."));
  cmd_xen_module =
    grub_register_command ("xen_module", grub_cmd_module,
  0, N_("Load a multiboot module."));
#endif
---------------

BTW, from the source code, MIPS isn't supported by multiboot,  IS
supported by multiboot2.

Please correct me. If I misunderstand your suggestion. :-)

Thanks again!


On 14 July 2015 at 11:53, Andrei Borzenkov <arvidjaar@gmail.com> wrote:
> В Mon, 13 Jul 2015 16:53:59 +0800
> fu.wei@linaro.org пишет:
>
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patch adds the support of boot command on arm64 for XEN:
>>     xen_hypervisor
>>     xen_module
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>>  util/grub.d/20_linux_xen.in | 14 +++++++++++---
>>  1 file changed, 11 insertions(+), 3 deletions(-)
>>
>> diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
>> index f532fb9..b52c50d 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_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_cmd}   --nounzip   ${rel_dirname}/${initrd}
>>  EOF
>>    fi
>>    sed "s/^/$submenu_indentation/" << EOF
>> @@ -185,6 +185,14 @@ case "$machine" in
>>      *) GENKERNEL_ARCH="$machine" ;;
>>  esac
>>
>> +if [ "x$machine" != xaarch64 ]; then
>> +     multiboot_cmd="multiboot"
>> +     module_cmd="module"
>> +else
>> +     multiboot_cmd="xen_hypervisor"
>> +     module_cmd="xen_module"
>> +fi
>> +
>
> Strictly speaking, this is boot-time decision. As mentioned by
> Vladimir, better would be to provide alias xen_hypervisor and
> xen_module in multiboot for platforms supporting Xen (is MIPS really
> supported?) and use it consistently.
>
>>  # 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=""
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [Xen-devel] [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support
  2015-07-14  9:41       ` Ian Campbell
@ 2015-07-14 15:23         ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 40+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-07-14 15:23 UTC (permalink / raw)
  To: Ian Campbell
  Cc: grub-devel, xen-devel, stefano.stabellini, Andrei Borzenkov,
	phcoder, linaro-uefi, leif.lindholm, ryan.harkin, jcm, fu.wei

On Tue, Jul 14, 2015 at 10:41:28AM +0100, Ian Campbell wrote:
> On Tue, 2015-07-14 at 06:53 +0300, Andrei Borzenkov wrote:
> > > +if [ "x$machine" != xaarch64 ]; then
> > > +	multiboot_cmd="multiboot"
> > > +	module_cmd="module"

And we should use the grub-file --is-multiboot2 to figure out if the
Xen binary can also do that - and use multiboot2 protocol.

But that patch I can cobble after this one is done.

> > > +else
> > > +	multiboot_cmd="xen_hypervisor"
> > > +	module_cmd="xen_module"
> > > +fi
> > > +
> > 
> > Strictly speaking, this is boot-time decision. As mentioned by
> > Vladimir, better would be to provide alias xen_hypervisor and
> > xen_module in multiboot for platforms supporting Xen (is MIPS really
> > supported?) and use it consistently.
> 
> I had been thinking of this the other way around, e.g. on platforms
> which support Xen but not multiboot1 "multiboot" would be added as an
> alias for xen_hypervisor.
> 
> However so long as grub-mkconfig (via 20_linux_xen) work for everyone
> and that peoples existing hand-crafted x86/multiboot/Xen grub.cfg's
> continue to work then I think having the alias go either way would be
> fine.
> 
> BTW I had been going to suggest a function at the grub.cfg level which
> dispatched to the correct command, but I suppose an actual alias is
> better.
> 
> Ian.
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
                     ` (3 preceding siblings ...)
  2015-07-14  9:29   ` [Xen-devel] [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot Ian Campbell
@ 2015-07-15 15:56   ` Vladimir 'φ-coder/phcoder' Serbinenko
  4 siblings, 0 replies; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-07-15 15:56 UTC (permalink / raw)
  To: fu.wei, grub-devel, arvidjaar
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi


[-- Attachment #1.1: Type: text/plain, Size: 2639 bytes --]

On 13.07.2015 10:53, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
>   - This adds support for the Xen boot on ARM specification for arm64.
> 
>   - The implementation for Xen is following  <Multiboot on ARM Specification>:
>     http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
>     and xen/docs/misc/arm/device-tree/booting.txt in Xen source code.
> 
>   - The multiboot/module commands have existed, so we use 
>     xen_hypervisor/xen_module instead.
> 
>   - This Xen boot support is built into linux module for aarch64,
>     and can not be used alone.
> 
>   - Adding this functionality to the existing "linux" module is for
>     reusing the existing code of devicetree.
> 
This is a misguided decision. Modules can depend on other modules.
Ideally shared functionality should be in a separate module but having
xen depend on linux is an OK stopgap solution. Putting everything in one
module is bad.
>   - Add the support of xen_hypervisor/xen_module commands in util/grub.d/20_linux_xen.in
> 
>   - Add the introduction of xen_hypervisor/xen_module commands in docs/grub.texi
> 
>   - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
>     https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB
> 
> Changelog:
> v2: remove the patches which have been accepted.
>     according to Vladimir's suggestion, change the command manes
>     and relevant code:
>         multiboot-->xen_hypervisor
>         module-->xen_module
>     improve the option parsing support for xen_hypervisor/xen_module commands.
>     add a patch for adding xen_hypervisor/xen_module support
>     in util/grub.d/20_linux_xen.in.
>     update docs/grub.texi patch for the new command names.
> 
> v1: The first version upstream patchset to grub-devel mailing list
> 
> 
> Fu Wei (3):
>   arm64: Add Xen boot support file
>   * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
>   arm64: Add the introduction of xen_hypervisor/xen_module command in
>     docs/grub.texi
> 
>  docs/grub.texi                    |  27 ++
>  grub-core/Makefile.core.def       |   1 +
>  grub-core/loader/arm64/linux.c    |   6 +
>  grub-core/loader/arm64/xen_boot.c | 615 ++++++++++++++++++++++++++++++++++++++
>  include/grub/arm64/xen_boot.h     | 115 +++++++
>  util/grub.d/20_linux_xen.in       |  14 +-
>  6 files changed, 775 insertions(+), 3 deletions(-)
>  create mode 100644 grub-core/loader/arm64/xen_boot.c
>  create mode 100644 include/grub/arm64/xen_boot.h
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 1/3] arm64: Add Xen boot support file
  2015-07-13  8:53   ` [PATCH v2 1/3] arm64: Add Xen boot support file fu.wei
@ 2015-07-15 16:18     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-07-16 16:46       ` Ian Campbell
  2015-07-23 10:16       ` Fu Wei
  0 siblings, 2 replies; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-07-15 16:18 UTC (permalink / raw)
  To: fu.wei, grub-devel, arvidjaar
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi


[-- Attachment #1.1: Type: text/plain, Size: 27720 bytes --]

On 13.07.2015 10:53, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> This patch adds Xen boot support file:
> grub-core/loader/arm64/xen_boot.c
> include/grub/arm64/xen_boot.h
> 
> This patch also adds commands register code and hearder file into
> grub-core/loader/arm64/linux.c
> 
>   - This adds support for the Xen boot on ARM specification for arm64.
>   - The implementation for Xen is following  <Multiboot on ARM Specification>:
>       http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
Please don't refer to this protocol as multiboot anywhere in grub or
around because it's NOT multiboot and we don't want to confuse those 2
protocols.
>     and xen/docs/misc/arm/device-tree/booting.txt in Xen source code.
>   - The multiboot/module commands have existed,
>     so we use xen_hypervisor/xen_module instead.
>   - This Xen boot support is built into linux module for aarch64.
>   - Adding this functionality to the existing "linux" module is for
>     reusing the existing code of devicetree.
> 
Please create separate module. Modules are dynamically linked.
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
>  grub-core/Makefile.core.def       |   1 +
>  grub-core/loader/arm64/linux.c    |   6 +
>  grub-core/loader/arm64/xen_boot.c | 615 ++++++++++++++++++++++++++++++++++++++
>  include/grub/arm64/xen_boot.h     | 115 +++++++
>  4 files changed, 737 insertions(+)
>  create mode 100644 grub-core/loader/arm64/xen_boot.c
>  create mode 100644 include/grub/arm64/xen_boot.h
> 
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index a6101de..01f8261 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -1659,6 +1659,7 @@ module = {
>    ia64_efi = loader/ia64/efi/linux.c;
>    arm = loader/arm/linux.c;
>    arm64 = loader/arm64/linux.c;
> +  arm64 = loader/arm64/xen_boot.c;
>    fdt = lib/fdt.c;
>    common = loader/linux.c;
>    common = lib/cmdline.c;
> diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
> index 987f5b9..7ae9bde 100644
> --- a/grub-core/loader/arm64/linux.c
> +++ b/grub-core/loader/arm64/linux.c
> @@ -26,6 +26,7 @@
>  #include <grub/mm.h>
>  #include <grub/types.h>
>  #include <grub/cpu/linux.h>
> +#include <grub/cpu/xen_boot.h>
>  #include <grub/efi/efi.h>
>  #include <grub/efi/pe32.h>
>  #include <grub/i18n.h>
> @@ -477,6 +478,9 @@ GRUB_MOD_INIT (linux)
>    cmd_devicetree =
>      grub_register_command ("devicetree", grub_cmd_devicetree, 0,
>  			   N_("Load DTB file."));
> +
> +  grub_arm64_linux_register_xen_boot_command (mod, &loaded);
> +
>    my_mod = mod;
>  }
>  
> @@ -485,4 +489,6 @@ GRUB_MOD_FINI (linux)
>    grub_unregister_command (cmd_linux);
>    grub_unregister_command (cmd_initrd);
>    grub_unregister_command (cmd_devicetree);
> +
> +  grub_arm64_linux_unregister_xen_boot_command ();
>  }
Not needed with separate module.
> diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
> new file mode 100644
> index 0000000..23bd00e
> --- /dev/null
> +++ b/grub-core/loader/arm64/xen_boot.c
> @@ -0,0 +1,615 @@
> +/*
> + *  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/cpu/xen_boot.h>
> +#include <grub/efi/efi.h>
> +#include <grub/efi/pe32.h>
> +#include <grub/i18n.h>
> +#include <grub/lib/cmdline.h>
> +
> +static grub_dl_t linux_mod;
> +static int *loaded;
> +
> +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_OTHER_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_OTHER_COMPATIBLE)
> +};
> +
> +
> +/* Parse all the options of xen_module command. For now, we support
> +   (1) --type <the compatible stream>
> +   (2) --nounzip
> +   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 (struct xen_boot_binary *module, int argc, char *argv[],
> +		 int *file_name_index)
> +{
> +  char **compat_string_temp_array =
> +    (char **) grub_zalloc (sizeof (char *) * argc);
> +  static module_type_t default_type = MODULE_IMAGE;
> +  grub_size_t total_size = 0;
> +  int num_types = 0, i;
> +  char *temp = NULL;
> +
> +  *file_name_index = 0;
> +
> +  /* if there are some options we need to process. */
> +  while (argc > 1 && !grub_strncmp (argv[0], "--", 2))
> +    {
> +      if (!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;
This (and subsequent) parsing is unecessarily complicated. Please create
separate commands for different types
> +	}
> +      else if (!grub_strcmp (argv[0], "--nounzip"))
> +	{
> +	  grub_file_filter_disable_compression ();
> +	  ARG_SHIFT (argc, argv);
> +	  (*file_name_index) += 1;
> +	}
> +      else			/* we can add more options process code here. */
> +	{
> +	  grub_dprintf ("xen_boot_loader",
> +			"Unknown option %s, skip.\n", argv[0]);
> +	  ARG_SHIFT (argc, argv);
> +	  (*file_name_index) += 1;
> +	}
> +    }
> +
> +  /* To prevent some wrong command lines using "--type" option */
> +  if (!argc)
> +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> +
> +  /* For the default module type :
> +     The implementation is following <Multiboot on ARM Specification>:
> +     Each module will be given a default compatibility property
> +     based on the order in which the modules are added.
> +     The 1st module: compatible = "multiboot,kernel", "multiboot,module"
> +     The 2nd module: compatible = "multiboot,ramdisk", "multiboot,module"
> +     All subsequent modules: compatible = "multiboot,module"
> +     But this order will NOT be interfered with "--type"(MODULE_CUSTOM)
> +     For more detail, please refer to:
> +     http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot */
> +  if (module->node_info.type != MODULE_CUSTOM)
> +    {
> +      /* the module type is set by the load order */
> +      module->node_info.type = default_type;
Please don't make it order-dependent more than necessarry.
> +      switch (default_type)
> +	{
> +	case MODULE_IMAGE:
> +	  default_type = MODULE_INITRD;
> +	  break;
> +
> +	case MODULE_INITRD:
> +	  default_type = MODULE_OTHER;
> +	  break;
> +
> +	case MODULE_OTHER:
> +	  break;
> +
> +	default:
> +	  default_type = MODULE_IMAGE;	/* error, reset the type */
> +	  return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
> +	}
> +    }
> +  else
> +    {
> +      /* the module type is set by "--type"(MODULE_CUSTOM) */
> +      module->node_info.compat_string = temp =
> +	(char *) grub_zalloc (total_size);
> +      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]);
> +	}
> +    }
> +
> +  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_BAD_OS, "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_BAD_OS, "failed to get chosen node in FDT");
> +
BAD_OS means that OS images are invalid. ERR_IO is a generic error for
such cases.
> +  grub_dprintf ("xen_boot_loader",
> +		"Xen Hypervisor cmdline : %s @ %p size:%d\n",
> +		xen_hypervisor->cmdline, xen_hypervisor->cmdline,
> +		xen_hypervisor->cmdline_size);
> +
No need for "boot_". xen_loader is fine and mre consistent.
> +  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_BAD_OS, "failed to install/update FDT");
> +
ditto
> +  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_boot_loader", "Module node name %s \n", module_name);
> +
> +  if (retval < (int) sizeof ("module@"))
> +    return grub_error (GRUB_ERR_BAD_OS, 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_BAD_OS, "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_BAD_OS, N_("failed to update FDT"));
> +
> +  grub_dprintf ("xen_boot_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_BAD_OS, N_("failed to update FDT"));
> +
> +  if (module->cmdline && module->cmdline_size > 0)
> +    {
> +      grub_dprintf ("xen_boot_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_BAD_OS, "failed to update FDT");
> +    }
> +  else
> +    {
> +      grub_dprintf ("xen_boot_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_BAD_OS, "failed to install FDT");
> +
> +  grub_dprintf ("xen_boot_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_boot_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_boot_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_boot_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_BAD_OS, "failed to install/update FDT");
> +}
> +
> +
> +static grub_err_t
> +xen_boot (void)
> +{
> +  if (finalize_params_xen_boot () != GRUB_ERR_NONE)
> +    return grub_errno;
> +
Better use 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)
> +{
Just put if (!binary) return; It will save a lot of if's.
> +  if (binary && 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 && binary->cmdline && binary->cmdline_size > 0)
> +    {
> +      grub_free (binary->cmdline);
> +      grub_dprintf ("xen_boot_loader",
> +		    "Module %s cmdline memory free @ %p size: %d\n",
> +		    binary->name, binary->cmdline, binary->cmdline_size);
> +    }
> +
> +  if (binary)
> +    {
> +      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_boot_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)
> +{
> +  *loaded = 0;
> +  all_binaries_unload ();
> +  clean_all_params ();
> +  grub_dl_unref (linux_mod);
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +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_boot_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)
> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +
> +  grub_dprintf ("xen_boot_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)
> +    {
We use != throughout. It's safer.
> +      single_binary_unload (binary);
> +      return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
> +			 argv[0]);
> +    }
> +
> +  /* Skip the xen_boot binary file name */
> +  ARG_SHIFT (argc, argv);
> +
There shouldn't be any need for shifting. Just use argc - 1 and argv + 1
> +  if (argc > 0)
> +    {
> +      binary->cmdline_size = grub_loader_cmdline_size (argc, argv);
> +      binary->cmdline = grub_zalloc (binary->cmdline_size);
> +      if (!binary->cmdline)
> +	{
> +	  single_binary_unload (binary);
> +	  return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +	}
> +      grub_create_loader_cmdline (argc, argv, binary->cmdline,
> +				  binary->cmdline_size);
> +      grub_dprintf ("xen_boot_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;
> +    }
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_cmd_xen_module (grub_command_t cmd __attribute__ ((unused)),
> +		     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 (!*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_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +
Just return grub_errno; zalloc already calls grub_error
> +  /* process all the options and get module type */
> +  if (set_module_type (module, argc, argv, &file_name_index) != GRUB_ERR_NONE)
> +    goto fail;
> +  switch (module->node_info.type)
> +    {
> +    case MODULE_IMAGE:
> +    case MODULE_INITRD:
> +    case MODULE_OTHER:
> +      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_boot_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;
> +
> +  grub_errno = xen_boot_binary_load (module, file, argc - file_name_index,
> +				     argv + file_name_index);
> +
When you call grub_error. grub_errno is already set
> +  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 (linux_mod);
> +
> +  if (!argc)
> +    {
> +      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> +      goto fail;
> +    }
> +
> +  /* For now, we don't support any option in xen_hypervisor command.
> +     If there are some options, we skip them. */
> +  while (argc > 1 && !grub_strncmp (argv[0], "--", 2))
> +    {
> +      grub_dprintf ("xen_boot_loader", "Unknown option %s, skip.\n", argv[0]);
> +      ARG_SHIFT (argc, argv);
> +    }
> +
Why do you need this? Just delete it.
> +  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);
> +
> +  grub_loader_unset ();
> +
This is implicit in loader_set. Please add a comment why it needs to be
explicit. I suppose it's to avoid unloading oneself.
> +  xen_hypervisor =
> +    (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary));
> +  if (!xen_hypervisor)
> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +
Ditto
> +  xen_hypervisor->name = XEN_HYPERVISOR_NAME;
> +  xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
> +
> +  grub_errno = xen_boot_binary_load (xen_hypervisor, file, argc, argv);
> +  if (grub_errno == GRUB_ERR_NONE)
> +    {
> +      grub_loader_set (xen_boot, xen_unload, 0);
> +      *loaded = 1;
> +    }
> +
> +fail:
> +  if (file)
> +    grub_file_close (file);
> +  if (grub_errno != GRUB_ERR_NONE)
> +    {
> +      *loaded = 0;
> +      all_binaries_unload ();
> +      grub_dl_unref (linux_mod);
> +    }
> +
> +  return grub_errno;
> +}
> +
> +static grub_command_t cmd_xen_hypervisor, cmd_xen_module;
> +
> +void
> +grub_arm64_linux_register_xen_boot_command (grub_dl_t mod, int *linux_loaded)
> +{
> +  cmd_xen_hypervisor =
> +    grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0,
> +			   N_("Load a xen hypervisor."));
> +  cmd_xen_module =
> +    grub_register_command ("xen_module", grub_cmd_xen_module, 0,
> +			   N_("Load a xen module."));
> +  linux_mod = mod;
> +  loaded = linux_loaded;
> +}
> +
> +void
> +grub_arm64_linux_unregister_xen_boot_command (void)
> +{
> +  grub_unregister_command (cmd_xen_hypervisor);
> +  grub_unregister_command (cmd_xen_module);
> +}
> diff --git a/include/grub/arm64/xen_boot.h b/include/grub/arm64/xen_boot.h
> new file mode 100644
> index 0000000..8e8f6cb
> --- /dev/null
> +++ b/include/grub/arm64/xen_boot.h
> @@ -0,0 +1,115 @@
> +/*
> + *  xen_boot.h - Xen boot header file for Xen boot via FDT
> + *  on AArch64 architecture.
> + *  Copyright (C) 2014  Free Software Foundation, Inc.
> + *
> + *  GRUB is free software: you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation, either version 3 of the License, or
> + *  (at your option) any later version.
> + *
> + *  GRUB is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef XEN_BOOT_HEADER
> +#define XEN_BOOT_HEADER 1
> +
> +#include <grub/list.h>
> +#include <grub/types.h>
> +#include <grub/efi/pe32.h>	/* required by struct xen_hypervisor_header */
> +
This file doesn't really look like having anything reusable. Please put
it directly into .c
> +#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_OTHER_MIN_ALIGN  MODULE_DEFAULT_ALIGN
> +#define MODULE_CUSTOM_MIN_ALIGN  MODULE_DEFAULT_ALIGN
> +
> +#define MODULE_IMAGE_COMPATIBLE  "multiboot,kernel\0multiboot,module"
> +#define MODULE_INITRD_COMPATIBLE  "multiboot,ramdisk\0multiboot,module"
> +#define MODULE_OTHER_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_OTHER,
> +  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;
> +};
> +
> +void grub_arm64_linux_register_xen_boot_command (grub_dl_t mod, int *loaded);
> +void grub_arm64_linux_unregister_xen_boot_command (void);
> +
> +static __inline grub_addr_t
> +xen_boot_address_align (grub_addr_t start, grub_size_t align)
> +{
> +  return (align ? (ALIGN_UP (start, align)) : start);
> +}
> +
> +#endif /* ! XEN_BOOT_HEADER */
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support
  2015-07-14 13:09       ` Fu Wei
@ 2015-07-15 16:24         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-07-15 16:24 UTC (permalink / raw)
  To: Fu Wei, Andrei Borzenkov
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Jon Masters, Leif Lindholm, Ryan Harkin,
	Linaro UEFI Mailman List


[-- Attachment #1.1: Type: text/plain, Size: 3850 bytes --]

On 14.07.2015 15:09, Fu Wei wrote:
> Hi Andrei,
> 
> Great thanks for your review.
> 
> So Are you suggesting this:
> (1) in util/grub.d/20_linux_xen.in, we only use xen_hypervisor/xen_module.
> (2) in xen_boot.c, we only register command xen_hypervisor/xen_module.
> (3) in grub-core/loader/i386/xen.c, we *add*
> ---------------
>   cmd_xen_hypervisort = grub_register_command ("xen_hypervisor", grub_cmd_xen,
> 0, N_("Load Linux."));
>   cmd_xen_module = grub_register_command ("xen_module", grub_cmd_module,
>      0, N_("Load module."));
No. This is for pvgrub2.
> ---------------
> (4)in grub-core/loader/multiboot.c, we *add*
> ---------------
> #if defined (__i386__) || defined (__aarch64__)
>   cmd_xen_hypervisort =
>     grub_register_command ("xen_hypervisor", grub_cmd_multiboot,
>   0, N_("Load a multiboot kernel."));
>   cmd_xen_module =
>     grub_register_command ("xen_module", grub_cmd_module,
>   0, N_("Load a multiboot module."));
> #endif
No. Don't mix arm64 xen with multiboot. Neither in command names nor in
the descriptions.
> ---------------
> 
> BTW, from the source code, MIPS isn't supported by multiboot,  IS
> supported by multiboot2.
> 
> Please correct me. If I misunderstand your suggestion. :-)
> 
> Thanks again!
> 
> 
> On 14 July 2015 at 11:53, Andrei Borzenkov <arvidjaar@gmail.com> wrote:
>> В Mon, 13 Jul 2015 16:53:59 +0800
>> fu.wei@linaro.org пишет:
>>
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> This patch adds the support of boot command on arm64 for XEN:
>>>     xen_hypervisor
>>>     xen_module
>>>
>>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>>> ---
>>>  util/grub.d/20_linux_xen.in | 14 +++++++++++---
>>>  1 file changed, 11 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
>>> index f532fb9..b52c50d 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_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_cmd}   --nounzip   ${rel_dirname}/${initrd}
>>>  EOF
>>>    fi
>>>    sed "s/^/$submenu_indentation/" << EOF
>>> @@ -185,6 +185,14 @@ case "$machine" in
>>>      *) GENKERNEL_ARCH="$machine" ;;
>>>  esac
>>>
>>> +if [ "x$machine" != xaarch64 ]; then
>>> +     multiboot_cmd="multiboot"
>>> +     module_cmd="module"
>>> +else
>>> +     multiboot_cmd="xen_hypervisor"
>>> +     module_cmd="xen_module"
>>> +fi
>>> +
>>
>> Strictly speaking, this is boot-time decision. As mentioned by
>> Vladimir, better would be to provide alias xen_hypervisor and
>> xen_module in multiboot for platforms supporting Xen (is MIPS really
>> supported?) and use it consistently.
>>
>>>  # 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=""
>>
> 
> 
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 1/3] arm64: Add Xen boot support file
  2015-07-15 16:18     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2015-07-16 16:46       ` Ian Campbell
  2015-07-23 10:16       ` Fu Wei
  1 sibling, 0 replies; 40+ messages in thread
From: Ian Campbell @ 2015-07-16 16:46 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: grub-devel, xen-devel, stefano.stabellini, arvidjaar, jcm,
	leif.lindholm, ryan.harkin, linaro-uefi, fu.wei

On Wed, 2015-07-15 at 18:18 +0200, Vladimir 'φ-coder/phcoder' Serbinenko
wrote:
> On 13.07.2015 10:53, fu.wei@linaro.org wrote:
> > From: Fu Wei <fu.wei@linaro.org>
> > 
> > This patch adds Xen boot support file:
> > grub-core/loader/arm64/xen_boot.c
> > include/grub/arm64/xen_boot.h
> > 
> > This patch also adds commands register code and hearder file into
> > grub-core/loader/arm64/linux.c
> > 
> >   - This adds support for the Xen boot on ARM specification for arm64.
> >   - The implementation for Xen is following  <Multiboot on ARM Specification>:
> >       http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
> Please don't refer to this protocol as multiboot anywhere in grub or
> around because it's NOT multiboot and we don't want to confuse those 2
> protocols.

That's fair enough, my hope was that the docs and communal knowledge
about how to write a grub.cfg for Xen x86/multiboot could remain
unchanged for Xen on arm (e.g. by using the same multiboot1 command
names, which surely won't be reused on arm), but I can see why you would
object to that and updating 20_linux_xen to DTRT on both arches solves
the majority of that concern.

WRT to what to call it instead: I did try and design it[0] to not be Xen
specific, so it would be nice to avoid making it so in the command names
if possible. I suspect this may lead to a certain amount of
bikeshedding, if so we should just call it something Xen specific and
move on I think.

For a non-Xen specific name how about "fbm -- fdt boot module" protocol
and associated commands fbm_kernel + fbm_module?

Ian.

[0]
http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
       [not found] <=fu.wei@linaro.org>
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
@ 2015-07-23  5:16 ` fu.wei
  2015-07-23  5:16   ` [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot fu.wei
                     ` (4 more replies)
  2016-02-25  6:50 ` [PATCH v2 0/4] arm64,xen: add xen_boot support into grup-mkconfig fu.wei
  2 siblings, 5 replies; 40+ messages in thread
From: fu.wei @ 2015-07-23  5:16 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

  - This adds support for the Xen boot on ARM specification for arm64.

  - Add and export some accessor functions of "loaded" flag and
    grub_linux_get_fdt function in include/grub/arm64/linux.h for xen boot.

  - 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.

  - Add the support of xen_hypervisor, xen_linux and xen_initrd
    in util/grub.d/20_linux_xen.in

  - Add the introduction of all xen boot commands in docs/grub.texi

  - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
    https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB

Changelog:
v3: create separate module for xen boot: xen_boot
    create separate commands for different types of module
    delete order-dependent for commands of xen module
    simplify the code

v2: remove the patches which have been accepted.
    according to Vladimir's suggestion, change the command manes
    and relevant code:
        multiboot-->xen_hypervisor
        module-->xen_module
    improve the option parsing support for xen_hypervisor/xen_module commands.
    add a patch for adding xen_hypervisor/xen_module support
    in util/grub.d/20_linux_xen.in.
    update docs/grub.texi patch for the new command names.

v1: The first version upstream patchset to grub-devel mailing list


Fu Wei (4):
  arm64: Add and export some accessor functions for xen boot
  arm64: Add xen_boot module file
  * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  arm64: Add the introduction of xen boot commands in docs/grub.texi

 docs/grub.texi                    |  56 ++++
 grub-core/Makefile.core.def       |   7 +
 grub-core/loader/arm64/linux.c    |  13 +
 grub-core/loader/arm64/xen_boot.c | 685 ++++++++++++++++++++++++++++++++++++++
 include/grub/arm64/linux.h        |   6 +-
 util/grub.d/20_linux_xen.in       |  16 +-
 6 files changed, 779 insertions(+), 4 deletions(-)
 create mode 100644 grub-core/loader/arm64/xen_boot.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
@ 2015-07-23  5:16   ` fu.wei
  2015-10-29 12:03     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-07-23  5:16   ` [PATCH v3 2/4] arm64: Add xen_boot module file fu.wei
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: fu.wei @ 2015-07-23  5:16 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 987f5b9..cf6026e 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.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 2/4] arm64: Add xen_boot module file
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
  2015-07-23  5:16   ` [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot fu.wei
@ 2015-07-23  5:16   ` fu.wei
  2015-10-29 14:27     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-07-23  5:16   ` [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64 fu.wei
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: fu.wei @ 2015-07-23  5:16 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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(+)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index a6101de..796f7e9 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1648,6 +1648,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.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
  2015-07-23  5:16   ` [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot fu.wei
  2015-07-23  5:16   ` [PATCH v3 2/4] arm64: Add xen_boot module file fu.wei
@ 2015-07-23  5:16   ` fu.wei
  2015-10-29 15:25     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-07-23  5:16   ` [PATCH v3 4/4] arm64: Add the introduction of xen boot commands in docs/grub.texi fu.wei
  2015-08-04  8:34   ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) Fu Wei
  4 siblings, 1 reply; 40+ messages in thread
From: fu.wei @ 2015-07-23  5:16 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

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 f532fb9..49aa709 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
@@ -185,6 +185,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.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 4/4] arm64: Add the introduction of xen boot commands in docs/grub.texi
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
                     ` (2 preceding siblings ...)
  2015-07-23  5:16   ` [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64 fu.wei
@ 2015-07-23  5:16   ` fu.wei
  2015-08-04  8:34   ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) Fu Wei
  4 siblings, 0 replies; 40+ messages in thread
From: fu.wei @ 2015-07-23  5:16 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

    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 b9f41a7..e94b03c 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.8.3.1

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 1/3] arm64: Add Xen boot support file
  2015-07-15 16:18     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-07-16 16:46       ` Ian Campbell
@ 2015-07-23 10:16       ` Fu Wei
  1 sibling, 0 replies; 40+ messages in thread
From: Fu Wei @ 2015-07-23 10:16 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Jon Masters, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List

Hi Vladimir,

I have submitted a new patchset (v3) for xen boot.
this patchset follows all your comment here.

please help me again on this, Great thanks for your help.

On 16 July 2015 at 00:18, Vladimir 'φ-coder/phcoder' Serbinenko
<phcoder@gmail.com> wrote:
> On 13.07.2015 10:53, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patch adds Xen boot support file:
>> grub-core/loader/arm64/xen_boot.c
>> include/grub/arm64/xen_boot.h
>>
>> This patch also adds commands register code and hearder file into
>> grub-core/loader/arm64/linux.c
>>
>>   - This adds support for the Xen boot on ARM specification for arm64.
>>   - The implementation for Xen is following  <Multiboot on ARM Specification>:
>>       http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
> Please don't refer to this protocol as multiboot anywhere in grub or
> around because it's NOT multiboot and we don't want to confuse those 2
> protocols.
>>     and xen/docs/misc/arm/device-tree/booting.txt in Xen source code.
>>   - The multiboot/module commands have existed,
>>     so we use xen_hypervisor/xen_module instead.
>>   - This Xen boot support is built into linux module for aarch64.
>>   - Adding this functionality to the existing "linux" module is for
>>     reusing the existing code of devicetree.
>>
> Please create separate module. Modules are dynamically linked.
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>>  grub-core/Makefile.core.def       |   1 +
>>  grub-core/loader/arm64/linux.c    |   6 +
>>  grub-core/loader/arm64/xen_boot.c | 615 ++++++++++++++++++++++++++++++++++++++
>>  include/grub/arm64/xen_boot.h     | 115 +++++++
>>  4 files changed, 737 insertions(+)
>>  create mode 100644 grub-core/loader/arm64/xen_boot.c
>>  create mode 100644 include/grub/arm64/xen_boot.h
>>
>> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
>> index a6101de..01f8261 100644
>> --- a/grub-core/Makefile.core.def
>> +++ b/grub-core/Makefile.core.def
>> @@ -1659,6 +1659,7 @@ module = {
>>    ia64_efi = loader/ia64/efi/linux.c;
>>    arm = loader/arm/linux.c;
>>    arm64 = loader/arm64/linux.c;
>> +  arm64 = loader/arm64/xen_boot.c;
>>    fdt = lib/fdt.c;
>>    common = loader/linux.c;
>>    common = lib/cmdline.c;
>> diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
>> index 987f5b9..7ae9bde 100644
>> --- a/grub-core/loader/arm64/linux.c
>> +++ b/grub-core/loader/arm64/linux.c
>> @@ -26,6 +26,7 @@
>>  #include <grub/mm.h>
>>  #include <grub/types.h>
>>  #include <grub/cpu/linux.h>
>> +#include <grub/cpu/xen_boot.h>
>>  #include <grub/efi/efi.h>
>>  #include <grub/efi/pe32.h>
>>  #include <grub/i18n.h>
>> @@ -477,6 +478,9 @@ GRUB_MOD_INIT (linux)
>>    cmd_devicetree =
>>      grub_register_command ("devicetree", grub_cmd_devicetree, 0,
>>                          N_("Load DTB file."));
>> +
>> +  grub_arm64_linux_register_xen_boot_command (mod, &loaded);
>> +
>>    my_mod = mod;
>>  }
>>
>> @@ -485,4 +489,6 @@ GRUB_MOD_FINI (linux)
>>    grub_unregister_command (cmd_linux);
>>    grub_unregister_command (cmd_initrd);
>>    grub_unregister_command (cmd_devicetree);
>> +
>> +  grub_arm64_linux_unregister_xen_boot_command ();
>>  }
> Not needed with separate module.
>> diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
>> new file mode 100644
>> index 0000000..23bd00e
>> --- /dev/null
>> +++ b/grub-core/loader/arm64/xen_boot.c
>> @@ -0,0 +1,615 @@
>> +/*
>> + *  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/cpu/xen_boot.h>
>> +#include <grub/efi/efi.h>
>> +#include <grub/efi/pe32.h>
>> +#include <grub/i18n.h>
>> +#include <grub/lib/cmdline.h>
>> +
>> +static grub_dl_t linux_mod;
>> +static int *loaded;
>> +
>> +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_OTHER_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_OTHER_COMPATIBLE)
>> +};
>> +
>> +
>> +/* Parse all the options of xen_module command. For now, we support
>> +   (1) --type <the compatible stream>
>> +   (2) --nounzip
>> +   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 (struct xen_boot_binary *module, int argc, char *argv[],
>> +              int *file_name_index)
>> +{
>> +  char **compat_string_temp_array =
>> +    (char **) grub_zalloc (sizeof (char *) * argc);
>> +  static module_type_t default_type = MODULE_IMAGE;
>> +  grub_size_t total_size = 0;
>> +  int num_types = 0, i;
>> +  char *temp = NULL;
>> +
>> +  *file_name_index = 0;
>> +
>> +  /* if there are some options we need to process. */
>> +  while (argc > 1 && !grub_strncmp (argv[0], "--", 2))
>> +    {
>> +      if (!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;
> This (and subsequent) parsing is unecessarily complicated. Please create
> separate commands for different types
>> +     }
>> +      else if (!grub_strcmp (argv[0], "--nounzip"))
>> +     {
>> +       grub_file_filter_disable_compression ();
>> +       ARG_SHIFT (argc, argv);
>> +       (*file_name_index) += 1;
>> +     }
>> +      else                   /* we can add more options process code here. */
>> +     {
>> +       grub_dprintf ("xen_boot_loader",
>> +                     "Unknown option %s, skip.\n", argv[0]);
>> +       ARG_SHIFT (argc, argv);
>> +       (*file_name_index) += 1;
>> +     }
>> +    }
>> +
>> +  /* To prevent some wrong command lines using "--type" option */
>> +  if (!argc)
>> +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
>> +
>> +  /* For the default module type :
>> +     The implementation is following <Multiboot on ARM Specification>:
>> +     Each module will be given a default compatibility property
>> +     based on the order in which the modules are added.
>> +     The 1st module: compatible = "multiboot,kernel", "multiboot,module"
>> +     The 2nd module: compatible = "multiboot,ramdisk", "multiboot,module"
>> +     All subsequent modules: compatible = "multiboot,module"
>> +     But this order will NOT be interfered with "--type"(MODULE_CUSTOM)
>> +     For more detail, please refer to:
>> +     http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot */
>> +  if (module->node_info.type != MODULE_CUSTOM)
>> +    {
>> +      /* the module type is set by the load order */
>> +      module->node_info.type = default_type;
> Please don't make it order-dependent more than necessarry.
>> +      switch (default_type)
>> +     {
>> +     case MODULE_IMAGE:
>> +       default_type = MODULE_INITRD;
>> +       break;
>> +
>> +     case MODULE_INITRD:
>> +       default_type = MODULE_OTHER;
>> +       break;
>> +
>> +     case MODULE_OTHER:
>> +       break;
>> +
>> +     default:
>> +       default_type = MODULE_IMAGE;  /* error, reset the type */
>> +       return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
>> +     }
>> +    }
>> +  else
>> +    {
>> +      /* the module type is set by "--type"(MODULE_CUSTOM) */
>> +      module->node_info.compat_string = temp =
>> +     (char *) grub_zalloc (total_size);
>> +      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]);
>> +     }
>> +    }
>> +
>> +  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_BAD_OS, "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_BAD_OS, "failed to get chosen node in FDT");
>> +
> BAD_OS means that OS images are invalid. ERR_IO is a generic error for
> such cases.
>> +  grub_dprintf ("xen_boot_loader",
>> +             "Xen Hypervisor cmdline : %s @ %p size:%d\n",
>> +             xen_hypervisor->cmdline, xen_hypervisor->cmdline,
>> +             xen_hypervisor->cmdline_size);
>> +
> No need for "boot_". xen_loader is fine and mre consistent.
>> +  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_BAD_OS, "failed to install/update FDT");
>> +
> ditto
>> +  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_boot_loader", "Module node name %s \n", module_name);
>> +
>> +  if (retval < (int) sizeof ("module@"))
>> +    return grub_error (GRUB_ERR_BAD_OS, 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_BAD_OS, "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_BAD_OS, N_("failed to update FDT"));
>> +
>> +  grub_dprintf ("xen_boot_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_BAD_OS, N_("failed to update FDT"));
>> +
>> +  if (module->cmdline && module->cmdline_size > 0)
>> +    {
>> +      grub_dprintf ("xen_boot_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_BAD_OS, "failed to update FDT");
>> +    }
>> +  else
>> +    {
>> +      grub_dprintf ("xen_boot_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_BAD_OS, "failed to install FDT");
>> +
>> +  grub_dprintf ("xen_boot_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_boot_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_boot_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_boot_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_BAD_OS, "failed to install/update FDT");
>> +}
>> +
>> +
>> +static grub_err_t
>> +xen_boot (void)
>> +{
>> +  if (finalize_params_xen_boot () != GRUB_ERR_NONE)
>> +    return grub_errno;
>> +
> Better use 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)
>> +{
> Just put if (!binary) return; It will save a lot of if's.
>> +  if (binary && 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 && binary->cmdline && binary->cmdline_size > 0)
>> +    {
>> +      grub_free (binary->cmdline);
>> +      grub_dprintf ("xen_boot_loader",
>> +                 "Module %s cmdline memory free @ %p size: %d\n",
>> +                 binary->name, binary->cmdline, binary->cmdline_size);
>> +    }
>> +
>> +  if (binary)
>> +    {
>> +      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_boot_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)
>> +{
>> +  *loaded = 0;
>> +  all_binaries_unload ();
>> +  clean_all_params ();
>> +  grub_dl_unref (linux_mod);
>> +
>> +  return GRUB_ERR_NONE;
>> +}
>> +
>> +static grub_err_t
>> +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_boot_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)
>> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
>> +
>> +  grub_dprintf ("xen_boot_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)
>> +    {
> We use != throughout. It's safer.
>> +      single_binary_unload (binary);
>> +      return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
>> +                      argv[0]);
>> +    }
>> +
>> +  /* Skip the xen_boot binary file name */
>> +  ARG_SHIFT (argc, argv);
>> +
> There shouldn't be any need for shifting. Just use argc - 1 and argv + 1
>> +  if (argc > 0)
>> +    {
>> +      binary->cmdline_size = grub_loader_cmdline_size (argc, argv);
>> +      binary->cmdline = grub_zalloc (binary->cmdline_size);
>> +      if (!binary->cmdline)
>> +     {
>> +       single_binary_unload (binary);
>> +       return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
>> +     }
>> +      grub_create_loader_cmdline (argc, argv, binary->cmdline,
>> +                               binary->cmdline_size);
>> +      grub_dprintf ("xen_boot_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;
>> +    }
>> +
>> +  return GRUB_ERR_NONE;
>> +}
>> +
>> +static grub_err_t
>> +grub_cmd_xen_module (grub_command_t cmd __attribute__ ((unused)),
>> +                  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 (!*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_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
>> +
> Just return grub_errno; zalloc already calls grub_error
>> +  /* process all the options and get module type */
>> +  if (set_module_type (module, argc, argv, &file_name_index) != GRUB_ERR_NONE)
>> +    goto fail;
>> +  switch (module->node_info.type)
>> +    {
>> +    case MODULE_IMAGE:
>> +    case MODULE_INITRD:
>> +    case MODULE_OTHER:
>> +      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_boot_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;
>> +
>> +  grub_errno = xen_boot_binary_load (module, file, argc - file_name_index,
>> +                                  argv + file_name_index);
>> +
> When you call grub_error. grub_errno is already set
>> +  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 (linux_mod);
>> +
>> +  if (!argc)
>> +    {
>> +      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
>> +      goto fail;
>> +    }
>> +
>> +  /* For now, we don't support any option in xen_hypervisor command.
>> +     If there are some options, we skip them. */
>> +  while (argc > 1 && !grub_strncmp (argv[0], "--", 2))
>> +    {
>> +      grub_dprintf ("xen_boot_loader", "Unknown option %s, skip.\n", argv[0]);
>> +      ARG_SHIFT (argc, argv);
>> +    }
>> +
> Why do you need this? Just delete it.
>> +  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);
>> +
>> +  grub_loader_unset ();
>> +
> This is implicit in loader_set. Please add a comment why it needs to be
> explicit. I suppose it's to avoid unloading oneself.
>> +  xen_hypervisor =
>> +    (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary));
>> +  if (!xen_hypervisor)
>> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
>> +
> Ditto
>> +  xen_hypervisor->name = XEN_HYPERVISOR_NAME;
>> +  xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
>> +
>> +  grub_errno = xen_boot_binary_load (xen_hypervisor, file, argc, argv);
>> +  if (grub_errno == GRUB_ERR_NONE)
>> +    {
>> +      grub_loader_set (xen_boot, xen_unload, 0);
>> +      *loaded = 1;
>> +    }
>> +
>> +fail:
>> +  if (file)
>> +    grub_file_close (file);
>> +  if (grub_errno != GRUB_ERR_NONE)
>> +    {
>> +      *loaded = 0;
>> +      all_binaries_unload ();
>> +      grub_dl_unref (linux_mod);
>> +    }
>> +
>> +  return grub_errno;
>> +}
>> +
>> +static grub_command_t cmd_xen_hypervisor, cmd_xen_module;
>> +
>> +void
>> +grub_arm64_linux_register_xen_boot_command (grub_dl_t mod, int *linux_loaded)
>> +{
>> +  cmd_xen_hypervisor =
>> +    grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0,
>> +                        N_("Load a xen hypervisor."));
>> +  cmd_xen_module =
>> +    grub_register_command ("xen_module", grub_cmd_xen_module, 0,
>> +                        N_("Load a xen module."));
>> +  linux_mod = mod;
>> +  loaded = linux_loaded;
>> +}
>> +
>> +void
>> +grub_arm64_linux_unregister_xen_boot_command (void)
>> +{
>> +  grub_unregister_command (cmd_xen_hypervisor);
>> +  grub_unregister_command (cmd_xen_module);
>> +}
>> diff --git a/include/grub/arm64/xen_boot.h b/include/grub/arm64/xen_boot.h
>> new file mode 100644
>> index 0000000..8e8f6cb
>> --- /dev/null
>> +++ b/include/grub/arm64/xen_boot.h
>> @@ -0,0 +1,115 @@
>> +/*
>> + *  xen_boot.h - Xen boot header file for Xen boot via FDT
>> + *  on AArch64 architecture.
>> + *  Copyright (C) 2014  Free Software Foundation, Inc.
>> + *
>> + *  GRUB is free software: you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation, either version 3 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  GRUB is distributed in the hope that it will be useful,
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *  GNU General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU General Public License
>> + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef XEN_BOOT_HEADER
>> +#define XEN_BOOT_HEADER 1
>> +
>> +#include <grub/list.h>
>> +#include <grub/types.h>
>> +#include <grub/efi/pe32.h>   /* required by struct xen_hypervisor_header */
>> +
> This file doesn't really look like having anything reusable. Please put
> it directly into .c
>> +#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_OTHER_MIN_ALIGN  MODULE_DEFAULT_ALIGN
>> +#define MODULE_CUSTOM_MIN_ALIGN  MODULE_DEFAULT_ALIGN
>> +
>> +#define MODULE_IMAGE_COMPATIBLE  "multiboot,kernel\0multiboot,module"
>> +#define MODULE_INITRD_COMPATIBLE  "multiboot,ramdisk\0multiboot,module"
>> +#define MODULE_OTHER_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_OTHER,
>> +  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;
>> +};
>> +
>> +void grub_arm64_linux_register_xen_boot_command (grub_dl_t mod, int *loaded);
>> +void grub_arm64_linux_unregister_xen_boot_command (void);
>> +
>> +static __inline grub_addr_t
>> +xen_boot_address_align (grub_addr_t start, grub_size_t align)
>> +{
>> +  return (align ? (ALIGN_UP (start, align)) : start);
>> +}
>> +
>> +#endif /* ! XEN_BOOT_HEADER */
>>
>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
                     ` (3 preceding siblings ...)
  2015-07-23  5:16   ` [PATCH v3 4/4] arm64: Add the introduction of xen boot commands in docs/grub.texi fu.wei
@ 2015-08-04  8:34   ` Fu Wei
  2015-09-08  3:38     ` Fu Wei
  4 siblings, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-08-04  8:34 UTC (permalink / raw)
  To: The development of GNU GRUB, Andrei Borzenkov, Vladimir Serbinenko
  Cc: xen-devel, Ian Campbell, Stefano Stabellini, Jon Masters,
	Leif Lindholm, Ryan Harkin, Linaro UEFI Mailman List, Fu Wei

Hi Vladimir,

this patchset follows all your comment of v2 patchset.
Do you have any suggestion on this patchset?

Great thanks for your help.


On 23 July 2015 at 13:16,  <fu.wei@linaro.org> wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
>   - This adds support for the Xen boot on ARM specification for arm64.
>
>   - Add and export some accessor functions of "loaded" flag and
>     grub_linux_get_fdt function in include/grub/arm64/linux.h for xen boot.
>
>   - 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.
>
>   - Add the support of xen_hypervisor, xen_linux and xen_initrd
>     in util/grub.d/20_linux_xen.in
>
>   - Add the introduction of all xen boot commands in docs/grub.texi
>
>   - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
>     https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB
>
> Changelog:
> v3: create separate module for xen boot: xen_boot
>     create separate commands for different types of module
>     delete order-dependent for commands of xen module
>     simplify the code
>
> v2: remove the patches which have been accepted.
>     according to Vladimir's suggestion, change the command manes
>     and relevant code:
>         multiboot-->xen_hypervisor
>         module-->xen_module
>     improve the option parsing support for xen_hypervisor/xen_module commands.
>     add a patch for adding xen_hypervisor/xen_module support
>     in util/grub.d/20_linux_xen.in.
>     update docs/grub.texi patch for the new command names.
>
> v1: The first version upstream patchset to grub-devel mailing list
>
>
> Fu Wei (4):
>   arm64: Add and export some accessor functions for xen boot
>   arm64: Add xen_boot module file
>   * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
>   arm64: Add the introduction of xen boot commands in docs/grub.texi
>
>  docs/grub.texi                    |  56 ++++
>  grub-core/Makefile.core.def       |   7 +
>  grub-core/loader/arm64/linux.c    |  13 +
>  grub-core/loader/arm64/xen_boot.c | 685 ++++++++++++++++++++++++++++++++++++++
>  include/grub/arm64/linux.h        |   6 +-
>  util/grub.d/20_linux_xen.in       |  16 +-
>  6 files changed, 779 insertions(+), 4 deletions(-)
>  create mode 100644 grub-core/loader/arm64/xen_boot.c
>
> --
> 1.8.3.1
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-08-04  8:34   ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) Fu Wei
@ 2015-09-08  3:38     ` Fu Wei
  2015-09-30 16:00       ` Stefano Stabellini
  0 siblings, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-09-08  3:38 UTC (permalink / raw)
  To: The development of GNU GRUB, Andrei Borzenkov, Vladimir Serbinenko
  Cc: xen-devel, Ian Campbell, Stefano Stabellini, Jon Masters,
	Leif Lindholm, Ryan Harkin, Linaro UEFI Mailman List, Fu Wei

Hi Vladimir,

Do you have any suggestion on this patchset?
Do I need to improve anything?

Great thanks for your help.

On 4 August 2015 at 16:34, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Vladimir,
>
> this patchset follows all your comment of v2 patchset.
> Do you have any suggestion on this patchset?
>
> Great thanks for your help.
>
>
> On 23 July 2015 at 13:16,  <fu.wei@linaro.org> wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>>   - This adds support for the Xen boot on ARM specification for arm64.
>>
>>   - Add and export some accessor functions of "loaded" flag and
>>     grub_linux_get_fdt function in include/grub/arm64/linux.h for xen boot.
>>
>>   - 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.
>>
>>   - Add the support of xen_hypervisor, xen_linux and xen_initrd
>>     in util/grub.d/20_linux_xen.in
>>
>>   - Add the introduction of all xen boot commands in docs/grub.texi
>>
>>   - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
>>     https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB
>>
>> Changelog:
>> v3: create separate module for xen boot: xen_boot
>>     create separate commands for different types of module
>>     delete order-dependent for commands of xen module
>>     simplify the code
>>
>> v2: remove the patches which have been accepted.
>>     according to Vladimir's suggestion, change the command manes
>>     and relevant code:
>>         multiboot-->xen_hypervisor
>>         module-->xen_module
>>     improve the option parsing support for xen_hypervisor/xen_module commands.
>>     add a patch for adding xen_hypervisor/xen_module support
>>     in util/grub.d/20_linux_xen.in.
>>     update docs/grub.texi patch for the new command names.
>>
>> v1: The first version upstream patchset to grub-devel mailing list
>>
>>
>> Fu Wei (4):
>>   arm64: Add and export some accessor functions for xen boot
>>   arm64: Add xen_boot module file
>>   * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
>>   arm64: Add the introduction of xen boot commands in docs/grub.texi
>>
>>  docs/grub.texi                    |  56 ++++
>>  grub-core/Makefile.core.def       |   7 +
>>  grub-core/loader/arm64/linux.c    |  13 +
>>  grub-core/loader/arm64/xen_boot.c | 685 ++++++++++++++++++++++++++++++++++++++
>>  include/grub/arm64/linux.h        |   6 +-
>>  util/grub.d/20_linux_xen.in       |  16 +-
>>  6 files changed, 779 insertions(+), 4 deletions(-)
>>  create mode 100644 grub-core/loader/arm64/xen_boot.c
>>
>> --
>> 1.8.3.1
>>
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> Ph: +86 21 61221326(direct)
> Ph: +86 186 2020 4684 (mobile)
> Room 1512, Regus One Corporate Avenue,Level 15,
> One Corporate Avenue,222 Hubin Road,Huangpu District,
> Shanghai,China 200021



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-09-08  3:38     ` Fu Wei
@ 2015-09-30 16:00       ` Stefano Stabellini
  2015-10-01 16:19         ` Stefano Stabellini
  2015-10-29  6:06         ` Fu Wei
  0 siblings, 2 replies; 40+ messages in thread
From: Stefano Stabellini @ 2015-09-30 16:00 UTC (permalink / raw)
  To: Fu Wei
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Vladimir Serbinenko,
	Leif Lindholm, Ryan Harkin, Linaro UEFI Mailman List,
	Jon Masters

Hi Fu,

I backported your patches to the CentOS aarch64 grub2 rpm.  I am testing
it on X-Gene with EFI firmware. It works fine when booting Xen, but
booting native kernels (no Xen) doesn't work anymore. Grub prints

error: out of memory.

Press any key to continue...

grub is still able to continue and load Linux, but then the kernel fails
to boot with "Cannot open root device", even though the grub config is
still same as before and the rootfs (which is xfs) hasn't changed.
Reverting the patches solved the problem.

Do you have any ideas on what is causing the issue? Maybe the initramfs
hasn't been properly loaded?


Thanks,

Stefano


On Tue, 8 Sep 2015, Fu Wei wrote:
> Hi Vladimir,
> 
> Do you have any suggestion on this patchset?
> Do I need to improve anything?
> 
> Great thanks for your help.
> 
> On 4 August 2015 at 16:34, Fu Wei <fu.wei@linaro.org> wrote:
> > Hi Vladimir,
> >
> > this patchset follows all your comment of v2 patchset.
> > Do you have any suggestion on this patchset?
> >
> > Great thanks for your help.
> >
> >
> > On 23 July 2015 at 13:16,  <fu.wei@linaro.org> wrote:
> >> From: Fu Wei <fu.wei@linaro.org>
> >>
> >>   - This adds support for the Xen boot on ARM specification for arm64.
> >>
> >>   - Add and export some accessor functions of "loaded" flag and
> >>     grub_linux_get_fdt function in include/grub/arm64/linux.h for xen boot.
> >>
> >>   - 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.
> >>
> >>   - Add the support of xen_hypervisor, xen_linux and xen_initrd
> >>     in util/grub.d/20_linux_xen.in
> >>
> >>   - Add the introduction of all xen boot commands in docs/grub.texi
> >>
> >>   - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
> >>     https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB
> >>
> >> Changelog:
> >> v3: create separate module for xen boot: xen_boot
> >>     create separate commands for different types of module
> >>     delete order-dependent for commands of xen module
> >>     simplify the code
> >>
> >> v2: remove the patches which have been accepted.
> >>     according to Vladimir's suggestion, change the command manes
> >>     and relevant code:
> >>         multiboot-->xen_hypervisor
> >>         module-->xen_module
> >>     improve the option parsing support for xen_hypervisor/xen_module commands.
> >>     add a patch for adding xen_hypervisor/xen_module support
> >>     in util/grub.d/20_linux_xen.in.
> >>     update docs/grub.texi patch for the new command names.
> >>
> >> v1: The first version upstream patchset to grub-devel mailing list
> >>
> >>
> >> Fu Wei (4):
> >>   arm64: Add and export some accessor functions for xen boot
> >>   arm64: Add xen_boot module file
> >>   * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
> >>   arm64: Add the introduction of xen boot commands in docs/grub.texi
> >>
> >>  docs/grub.texi                    |  56 ++++
> >>  grub-core/Makefile.core.def       |   7 +
> >>  grub-core/loader/arm64/linux.c    |  13 +
> >>  grub-core/loader/arm64/xen_boot.c | 685 ++++++++++++++++++++++++++++++++++++++
> >>  include/grub/arm64/linux.h        |   6 +-
> >>  util/grub.d/20_linux_xen.in       |  16 +-
> >>  6 files changed, 779 insertions(+), 4 deletions(-)
> >>  create mode 100644 grub-core/loader/arm64/xen_boot.c
> >>
> >> --
> >> 1.8.3.1
> >>
> >
> >
> >
> > --
> > Best regards,
> >
> > Fu Wei
> > Software Engineer
> > Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> > Ph: +86 21 61221326(direct)
> > Ph: +86 186 2020 4684 (mobile)
> > Room 1512, Regus One Corporate Avenue,Level 15,
> > One Corporate Avenue,222 Hubin Road,Huangpu District,
> > Shanghai,China 200021
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> Ph: +86 21 61221326(direct)
> Ph: +86 186 2020 4684 (mobile)
> Room 1512, Regus One Corporate Avenue,Level 15,
> One Corporate Avenue,222 Hubin Road,Huangpu District,
> Shanghai,China 200021
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-09-30 16:00       ` Stefano Stabellini
@ 2015-10-01 16:19         ` Stefano Stabellini
  2015-10-29  2:43           ` Fu Wei
  2015-10-29  6:06         ` Fu Wei
  1 sibling, 1 reply; 40+ messages in thread
From: Stefano Stabellini @ 2015-10-01 16:19 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Andrei Borzenkov, Vladimir Serbinenko, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List, Jon Masters, Fu Wei

On Wed, 30 Sep 2015, Stefano Stabellini wrote:
> Hi Fu,
> 
> I backported your patches to the CentOS aarch64 grub2 rpm.  I am testing
> it on X-Gene with EFI firmware. It works fine when booting Xen, but
> booting native kernels (no Xen) doesn't work anymore. Grub prints
> 
> error: out of memory.
> 
> Press any key to continue...
> 
> grub is still able to continue and load Linux, but then the kernel fails
> to boot with "Cannot open root device", even though the grub config is
> still same as before and the rootfs (which is xfs) hasn't changed.
> Reverting the patches solved the problem.
> 
> Do you have any ideas on what is causing the issue? Maybe the initramfs
> hasn't been properly loaded?

It looks like the following chunk of commit
f8451af8251a3866cb8b7307b9917dd5d34fbd0a "arm64: Export useful functions
from linux.c" causes troubles:


diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
index 117232f..a63a11a 100644
--- a/grub-core/loader/linux.c
+++ b/grub-core/loader/linux.c
@@ -205,7 +205,8 @@ grub_initrd_init (int argc, char *argv[],
       initrd_ctx->nfiles++;
       initrd_ctx->components[i].size
        = grub_file_size (initrd_ctx->components[i].file);
-      initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
+      if (argc != 1)
+       initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
     }
 
   if (newc)


Simply removing this change seems to fix the issue and Xen still boots
fine.

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-10-01 16:19         ` Stefano Stabellini
@ 2015-10-29  2:43           ` Fu Wei
  0 siblings, 0 replies; 40+ messages in thread
From: Fu Wei @ 2015-10-29  2:43 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Andrei Borzenkov, Vladimir Serbinenko, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List, Jon Masters

Hi Stefano,

Sorry for late response, I will try to test my latest patch ASAP. but
I don't see this problem before.
will let you know the result , thanks for your testing

On 2 October 2015 at 00:19, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> On Wed, 30 Sep 2015, Stefano Stabellini wrote:
>> Hi Fu,
>>
>> I backported your patches to the CentOS aarch64 grub2 rpm.  I am testing
>> it on X-Gene with EFI firmware. It works fine when booting Xen, but
>> booting native kernels (no Xen) doesn't work anymore. Grub prints
>>
>> error: out of memory.
>>
>> Press any key to continue...
>>
>> grub is still able to continue and load Linux, but then the kernel fails
>> to boot with "Cannot open root device", even though the grub config is
>> still same as before and the rootfs (which is xfs) hasn't changed.
>> Reverting the patches solved the problem.
>>
>> Do you have any ideas on what is causing the issue? Maybe the initramfs
>> hasn't been properly loaded?
>
> It looks like the following chunk of commit
> f8451af8251a3866cb8b7307b9917dd5d34fbd0a "arm64: Export useful functions
> from linux.c" causes troubles:
>
>
> diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
> index 117232f..a63a11a 100644
> --- a/grub-core/loader/linux.c
> +++ b/grub-core/loader/linux.c
> @@ -205,7 +205,8 @@ grub_initrd_init (int argc, char *argv[],
>        initrd_ctx->nfiles++;
>        initrd_ctx->components[i].size
>         = grub_file_size (initrd_ctx->components[i].file);
> -      initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
> +      if (argc != 1)
> +       initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
>      }
>
>    if (newc)
>
>
> Simply removing this change seems to fix the issue and Xen still boots
> fine.



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-09-30 16:00       ` Stefano Stabellini
  2015-10-01 16:19         ` Stefano Stabellini
@ 2015-10-29  6:06         ` Fu Wei
  2015-10-29 11:00           ` Stefano Stabellini
  1 sibling, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-10-29  6:06 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Andrei Borzenkov, Vladimir Serbinenko, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List, Jon Masters

Hi Stefano,

I have tried my grub on Foundation model, but I did not get this
error, I guess that is the UEFI problem ?

On 1 October 2015 at 00:00, Stefano Stabellini
<stefano.stabellini@eu.citrix.com> wrote:
> Hi Fu,
>
> I backported your patches to the CentOS aarch64 grub2 rpm.  I am testing
> it on X-Gene with EFI firmware. It works fine when booting Xen, but
> booting native kernels (no Xen) doesn't work anymore. Grub prints
>
> error: out of memory.
>
> Press any key to continue...
>
> grub is still able to continue and load Linux, but then the kernel fails
> to boot with "Cannot open root device", even though the grub config is
> still same as before and the rootfs (which is xfs) hasn't changed.
> Reverting the patches solved the problem.
>
> Do you have any ideas on what is causing the issue? Maybe the initramfs
> hasn't been properly loaded?
>
>
> Thanks,
>
> Stefano
>
>
> On Tue, 8 Sep 2015, Fu Wei wrote:
>> Hi Vladimir,
>>
>> Do you have any suggestion on this patchset?
>> Do I need to improve anything?
>>
>> Great thanks for your help.
>>
>> On 4 August 2015 at 16:34, Fu Wei <fu.wei@linaro.org> wrote:
>> > Hi Vladimir,
>> >
>> > this patchset follows all your comment of v2 patchset.
>> > Do you have any suggestion on this patchset?
>> >
>> > Great thanks for your help.
>> >
>> >
>> > On 23 July 2015 at 13:16,  <fu.wei@linaro.org> wrote:
>> >> From: Fu Wei <fu.wei@linaro.org>
>> >>
>> >>   - This adds support for the Xen boot on ARM specification for arm64.
>> >>
>> >>   - Add and export some accessor functions of "loaded" flag and
>> >>     grub_linux_get_fdt function in include/grub/arm64/linux.h for xen boot.
>> >>
>> >>   - 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.
>> >>
>> >>   - Add the support of xen_hypervisor, xen_linux and xen_initrd
>> >>     in util/grub.d/20_linux_xen.in
>> >>
>> >>   - Add the introduction of all xen boot commands in docs/grub.texi
>> >>
>> >>   - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
>> >>     https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB
>> >>
>> >> Changelog:
>> >> v3: create separate module for xen boot: xen_boot
>> >>     create separate commands for different types of module
>> >>     delete order-dependent for commands of xen module
>> >>     simplify the code
>> >>
>> >> v2: remove the patches which have been accepted.
>> >>     according to Vladimir's suggestion, change the command manes
>> >>     and relevant code:
>> >>         multiboot-->xen_hypervisor
>> >>         module-->xen_module
>> >>     improve the option parsing support for xen_hypervisor/xen_module commands.
>> >>     add a patch for adding xen_hypervisor/xen_module support
>> >>     in util/grub.d/20_linux_xen.in.
>> >>     update docs/grub.texi patch for the new command names.
>> >>
>> >> v1: The first version upstream patchset to grub-devel mailing list
>> >>
>> >>
>> >> Fu Wei (4):
>> >>   arm64: Add and export some accessor functions for xen boot
>> >>   arm64: Add xen_boot module file
>> >>   * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
>> >>   arm64: Add the introduction of xen boot commands in docs/grub.texi
>> >>
>> >>  docs/grub.texi                    |  56 ++++
>> >>  grub-core/Makefile.core.def       |   7 +
>> >>  grub-core/loader/arm64/linux.c    |  13 +
>> >>  grub-core/loader/arm64/xen_boot.c | 685 ++++++++++++++++++++++++++++++++++++++
>> >>  include/grub/arm64/linux.h        |   6 +-
>> >>  util/grub.d/20_linux_xen.in       |  16 +-
>> >>  6 files changed, 779 insertions(+), 4 deletions(-)
>> >>  create mode 100644 grub-core/loader/arm64/xen_boot.c
>> >>
>> >> --
>> >> 1.8.3.1
>> >>
>> >
>> >
>> >
>> > --
>> > Best regards,
>> >
>> > Fu Wei
>> > Software Engineer
>> > Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
>> > Ph: +86 21 61221326(direct)
>> > Ph: +86 186 2020 4684 (mobile)
>> > Room 1512, Regus One Corporate Avenue,Level 15,
>> > One Corporate Avenue,222 Hubin Road,Huangpu District,
>> > Shanghai,China 200021
>>
>>
>>
>> --
>> Best regards,
>>
>> Fu Wei
>> Software Engineer
>> Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
>> Ph: +86 21 61221326(direct)
>> Ph: +86 186 2020 4684 (mobile)
>> Room 1512, Regus One Corporate Avenue,Level 15,
>> One Corporate Avenue,222 Hubin Road,Huangpu District,
>> Shanghai,China 200021
>>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 0/4] arm64: Add Xen boot support (via fdt)
  2015-10-29  6:06         ` Fu Wei
@ 2015-10-29 11:00           ` Stefano Stabellini
  0 siblings, 0 replies; 40+ messages in thread
From: Stefano Stabellini @ 2015-10-29 11:00 UTC (permalink / raw)
  To: Fu Wei
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Vladimir Serbinenko,
	Leif Lindholm, Ryan Harkin, Linaro UEFI Mailman List,
	Jon Masters

Yes, it happens when booting from grub from UEFI firmware: I tested it
on X-Gene.

Cheers,

Stefano

On Thu, 29 Oct 2015, Fu Wei wrote:
> Hi Stefano,
> 
> I have tried my grub on Foundation model, but I did not get this
> error, I guess that is the UEFI problem ?
> 
> On 1 October 2015 at 00:00, Stefano Stabellini
> <stefano.stabellini@eu.citrix.com> wrote:
> > Hi Fu,
> >
> > I backported your patches to the CentOS aarch64 grub2 rpm.  I am testing
> > it on X-Gene with EFI firmware. It works fine when booting Xen, but
> > booting native kernels (no Xen) doesn't work anymore. Grub prints
> >
> > error: out of memory.
> >
> > Press any key to continue...
> >
> > grub is still able to continue and load Linux, but then the kernel fails
> > to boot with "Cannot open root device", even though the grub config is
> > still same as before and the rootfs (which is xfs) hasn't changed.
> > Reverting the patches solved the problem.
> >
> > Do you have any ideas on what is causing the issue? Maybe the initramfs
> > hasn't been properly loaded?
> >
> >
> > Thanks,
> >
> > Stefano
> >
> >
> > On Tue, 8 Sep 2015, Fu Wei wrote:
> >> Hi Vladimir,
> >>
> >> Do you have any suggestion on this patchset?
> >> Do I need to improve anything?
> >>
> >> Great thanks for your help.
> >>
> >> On 4 August 2015 at 16:34, Fu Wei <fu.wei@linaro.org> wrote:
> >> > Hi Vladimir,
> >> >
> >> > this patchset follows all your comment of v2 patchset.
> >> > Do you have any suggestion on this patchset?
> >> >
> >> > Great thanks for your help.
> >> >
> >> >
> >> > On 23 July 2015 at 13:16,  <fu.wei@linaro.org> wrote:
> >> >> From: Fu Wei <fu.wei@linaro.org>
> >> >>
> >> >>   - This adds support for the Xen boot on ARM specification for arm64.
> >> >>
> >> >>   - Add and export some accessor functions of "loaded" flag and
> >> >>     grub_linux_get_fdt function in include/grub/arm64/linux.h for xen boot.
> >> >>
> >> >>   - 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.
> >> >>
> >> >>   - Add the support of xen_hypervisor, xen_linux and xen_initrd
> >> >>     in util/grub.d/20_linux_xen.in
> >> >>
> >> >>   - Add the introduction of all xen boot commands in docs/grub.texi
> >> >>
> >> >>   - The example of this support is <How to boot Xen with GRUB on AArch64 the Foundation FVP model>
> >> >>     https://wiki.linaro.org/LEG/Engineering/Grub2/Xen_booting_on_Foundation_FVP_model_by_GRUB
> >> >>
> >> >> Changelog:
> >> >> v3: create separate module for xen boot: xen_boot
> >> >>     create separate commands for different types of module
> >> >>     delete order-dependent for commands of xen module
> >> >>     simplify the code
> >> >>
> >> >> v2: remove the patches which have been accepted.
> >> >>     according to Vladimir's suggestion, change the command manes
> >> >>     and relevant code:
> >> >>         multiboot-->xen_hypervisor
> >> >>         module-->xen_module
> >> >>     improve the option parsing support for xen_hypervisor/xen_module commands.
> >> >>     add a patch for adding xen_hypervisor/xen_module support
> >> >>     in util/grub.d/20_linux_xen.in.
> >> >>     update docs/grub.texi patch for the new command names.
> >> >>
> >> >> v1: The first version upstream patchset to grub-devel mailing list
> >> >>
> >> >>
> >> >> Fu Wei (4):
> >> >>   arm64: Add and export some accessor functions for xen boot
> >> >>   arm64: Add xen_boot module file
> >> >>   * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
> >> >>   arm64: Add the introduction of xen boot commands in docs/grub.texi
> >> >>
> >> >>  docs/grub.texi                    |  56 ++++
> >> >>  grub-core/Makefile.core.def       |   7 +
> >> >>  grub-core/loader/arm64/linux.c    |  13 +
> >> >>  grub-core/loader/arm64/xen_boot.c | 685 ++++++++++++++++++++++++++++++++++++++
> >> >>  include/grub/arm64/linux.h        |   6 +-
> >> >>  util/grub.d/20_linux_xen.in       |  16 +-
> >> >>  6 files changed, 779 insertions(+), 4 deletions(-)
> >> >>  create mode 100644 grub-core/loader/arm64/xen_boot.c
> >> >>
> >> >> --
> >> >> 1.8.3.1
> >> >>
> >> >
> >> >
> >> >
> >> > --
> >> > Best regards,
> >> >
> >> > Fu Wei
> >> > Software Engineer
> >> > Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> >> > Ph: +86 21 61221326(direct)
> >> > Ph: +86 186 2020 4684 (mobile)
> >> > Room 1512, Regus One Corporate Avenue,Level 15,
> >> > One Corporate Avenue,222 Hubin Road,Huangpu District,
> >> > Shanghai,China 200021
> >>
> >>
> >>
> >> --
> >> Best regards,
> >>
> >> Fu Wei
> >> Software Engineer
> >> Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> >> Ph: +86 21 61221326(direct)
> >> Ph: +86 186 2020 4684 (mobile)
> >> Room 1512, Regus One Corporate Avenue,Level 15,
> >> One Corporate Avenue,222 Hubin Road,Huangpu District,
> >> Shanghai,China 200021
> >>
> 
> 
> 
> -- 
> Best regards,
> 
> Fu Wei
> Software Engineer
> Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> Ph: +86 21 61221326(direct)
> Ph: +86 186 2020 4684 (mobile)
> Room 1512, Regus One Corporate Avenue,Level 15,
> One Corporate Avenue,222 Hubin Road,Huangpu District,
> Shanghai,China 200021
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot
  2015-07-23  5:16   ` [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot fu.wei
@ 2015-10-29 12:03     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-10-30  7:11       ` Fu Wei
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-10-29 12:03 UTC (permalink / raw)
  To: fu.wei, grub-devel, arvidjaar
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi


[-- Attachment #1.1: Type: text/plain, Size: 2408 bytes --]

On 23.07.2015 07:16, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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 987f5b9..cf6026e 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;
> +}
> +
Accessor functions are usually useless in GRUB. We have no public API to
respect. So it only adds clutter. Also "loaded" flag is static for а
good reason: it's specific to linux.c. I'm going to move fdt part to
fdt.c and have uniform interface for both linux and xen.
>  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);
> +
EXPORT_* are necessary only for core. Not for modules.
>  #endif /* ! GRUB_LINUX_CPU_HEADER */
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 2/4] arm64: Add xen_boot module file
  2015-07-23  5:16   ` [PATCH v3 2/4] arm64: Add xen_boot module file fu.wei
@ 2015-10-29 14:27     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-10-30  8:08       ` Fu Wei
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-10-29 14:27 UTC (permalink / raw)
  To: fu.wei, grub-devel, arvidjaar
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi


[-- Attachment #1.1: Type: text/plain, Size: 23108 bytes --]

Committed without the xen_module command. Its argument parsing was
non-trivial and I don't quite get what its intent is. Can you resubmit?
On 23.07.2015 07:16, fu.wei@linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
> 
> 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(+)
> 
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index a6101de..796f7e9 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -1648,6 +1648,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);
> +}
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  2015-07-23  5:16   ` [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64 fu.wei
@ 2015-10-29 15:25     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-10-29 19:53       ` Andrei Borzenkov
  2015-10-30  8:44       ` Fu Wei
  0 siblings, 2 replies; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-10-29 15:25 UTC (permalink / raw)
  To: fu.wei, grub-devel, arvidjaar
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi


[-- Attachment #1.1: Type: text/plain, Size: 632 bytes --]

> +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
> +
Please do not hardcode an assumption that grub-mkconfig is executed on
the same machine as GRUB is booted. I know that we have instances of
such assumption in some cases but we'd like to eliminate them. Alternatives:
- Check arch on boot time
- Check that new xen commands are supported (define a new feature)
Please add xen_* aliases on x86 as well



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  2015-10-29 15:25     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2015-10-29 19:53       ` Andrei Borzenkov
  2015-10-30  8:44       ` Fu Wei
  1 sibling, 0 replies; 40+ messages in thread
From: Andrei Borzenkov @ 2015-10-29 19:53 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko, fu.wei, grub-devel
  Cc: xen-devel, Ian.Campbell, stefano.stabellini, jcm, leif.lindholm,
	ryan.harkin, linaro-uefi

29.10.2015 18:25, Vladimir 'φ-coder/phcoder' Serbinenko пишет:
>> +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
>> +
> Please do not hardcode an assumption that grub-mkconfig is executed on
> the same machine as GRUB is booted. I know that we have instances of
> such assumption in some cases but we'd like to eliminate them. Alternatives:
> - Check arch on boot time

This makes it even more difficult for os-prober to parse grub.cfg. We 
need some alternative before going this route.

> - Check that new xen commands are supported (define a new feature)
> Please add xen_* aliases on x86 as well
>
>

Yes, that's better.

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot
  2015-10-29 12:03     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2015-10-30  7:11       ` Fu Wei
  0 siblings, 0 replies; 40+ messages in thread
From: Fu Wei @ 2015-10-30  7:11 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Jon Masters, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List

Hi Vladimir,

Good idea! I can see your patch for it in master branch.

Great thanks for your help, I will try this ASAP :-)


On 29 October 2015 at 20:03, Vladimir 'φ-coder/phcoder' Serbinenko
<phcoder@gmail.com> wrote:
> On 23.07.2015 07:16, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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 987f5b9..cf6026e 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;
>> +}
>> +
> Accessor functions are usually useless in GRUB. We have no public API to
> respect. So it only adds clutter. Also "loaded" flag is static for а
> good reason: it's specific to linux.c. I'm going to move fdt part to
> fdt.c and have uniform interface for both linux and xen.
>>  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);
>> +
> EXPORT_* are necessary only for core. Not for modules.
>>  #endif /* ! GRUB_LINUX_CPU_HEADER */
>>
>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 2/4] arm64: Add xen_boot module file
  2015-10-29 14:27     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2015-10-30  8:08       ` Fu Wei
  2015-11-03 14:57         ` Fu Wei
  0 siblings, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-10-30  8:08 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Jon Masters, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List

Hi Vladimir,

yes, Thanks for your modification :-)

I just follow the xen boot protocol :
http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot

xen_module is just for "--type" option, I will discuss this with Xen
developer for this.
If we need this option, I will resubmit  it :-)

Great thanks!

On 29 October 2015 at 22:27, Vladimir 'φ-coder/phcoder' Serbinenko
<phcoder@gmail.com> wrote:
> Committed without the xen_module command. Its argument parsing was
> non-trivial and I don't quite get what its intent is. Can you resubmit?
> On 23.07.2015 07:16, fu.wei@linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> 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(+)
>>
>> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
>> index a6101de..796f7e9 100644
>> --- a/grub-core/Makefile.core.def
>> +++ b/grub-core/Makefile.core.def
>> @@ -1648,6 +1648,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);
>> +}
>>
>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  2015-10-29 15:25     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-10-29 19:53       ` Andrei Borzenkov
@ 2015-10-30  8:44       ` Fu Wei
  2015-10-30  9:50         ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-10-30  8:44 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Jon Masters, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List

Hi Vladimir,

Great thanks for your suggestion! :-)

On 29 October 2015 at 23:25, Vladimir 'φ-coder/phcoder' Serbinenko
<phcoder@gmail.com> wrote:
>> +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
>> +
> Please do not hardcode an assumption that grub-mkconfig is executed on
> the same machine as GRUB is booted. I know that we have instances of
> such assumption in some cases but we'd like to eliminate them. Alternatives:
> - Check arch on boot time


> - Check that new xen commands are supported (define a new feature)
> Please add xen_* aliases on x86 as well
I would like to go this way, but could you provide some help or a
little example for :
(1) How to check the new xen commands(or xen_boot module)
(2)add xen_* aliases on x86, is that like something below?

diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
index c4d9689..b88d51b 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -696,10 +696,14 @@ GRUB_MOD_INIT (xen)
                                   0, N_("Load Linux."));
   cmd_multiboot = grub_register_command ("multiboot", grub_cmd_xen,
                                         0, N_("Load Linux."));
+  cmd_multiboot = grub_register_command ("xen_hypervisor", grub_cmd_xen,
+                                        0, N_("Load Linux."));
   cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
                                      0, N_("Load initrd."));
   cmd_module = grub_register_command ("module", grub_cmd_module,
                                      0, N_("Load module."));
+  cmd_module = grub_register_command ("xen_linux", grub_cmd_module,
+                                     0, N_("Load module."));
   my_mod = mod;
 }

But how to deal with xen_initrd ?
Could you help me ?

Great thanks !!

>
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  2015-10-30  8:44       ` Fu Wei
@ 2015-10-30  9:50         ` Vladimir 'φ-coder/phcoder' Serbinenko
  2015-10-30 10:07           ` Andrei Borzenkov
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-10-30  9:50 UTC (permalink / raw)
  To: Fu Wei
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Jon Masters, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List


[-- Attachment #1.1: Type: text/plain, Size: 2410 bytes --]

On 30.10.2015 09:44, Fu Wei wrote:
> Hi Vladimir,
> 
> Great thanks for your suggestion! :-)
> 
> On 29 October 2015 at 23:25, Vladimir 'φ-coder/phcoder' Serbinenko
> <phcoder@gmail.com> wrote:
>>> +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
>>> +
>> Please do not hardcode an assumption that grub-mkconfig is executed on
>> the same machine as GRUB is booted. I know that we have instances of
>> such assumption in some cases but we'd like to eliminate them. Alternatives:
>> - Check arch on boot time
> 
> 
>> - Check that new xen commands are supported (define a new feature)
>> Please add xen_* aliases on x86 as well
> I would like to go this way, but could you provide some help or a
> little example for :
> (1) How to check the new xen commands(or xen_boot module)
> (2)add xen_* aliases on x86, is that like something below?
> 
see grub-core/normal/main.c the features array.
> diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
> index c4d9689..b88d51b 100644
> --- a/grub-core/loader/i386/xen.c
> +++ b/grub-core/loader/i386/xen.c
> @@ -696,10 +696,14 @@ GRUB_MOD_INIT (xen)
>                                    0, N_("Load Linux."));
>    cmd_multiboot = grub_register_command ("multiboot", grub_cmd_xen,
>                                          0, N_("Load Linux."));
> +  cmd_multiboot = grub_register_command ("xen_hypervisor", grub_cmd_xen,
> +                                        0, N_("Load Linux."));
>    cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
>                                       0, N_("Load initrd."));
>    cmd_module = grub_register_command ("module", grub_cmd_module,
>                                       0, N_("Load module."));
> +  cmd_module = grub_register_command ("xen_linux", grub_cmd_module,
> +                                     0, N_("Load module."));
>    my_mod = mod;
>  }
> 
> But how to deal with xen_initrd ?
> Could you help me ?
> 
Just another alias to module. Possibly you might want to add a code to
xen_initrd tto check that xen_linux was already run
> Great thanks !!
> 
>>
>>
> 
> 
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

[-- Attachment #2: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64
  2015-10-30  9:50         ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2015-10-30 10:07           ` Andrei Borzenkov
  0 siblings, 0 replies; 40+ messages in thread
From: Andrei Borzenkov @ 2015-10-30 10:07 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Jon Masters, Leif Lindholm, Ryan Harkin,
	Linaro UEFI Mailman List, Fu Wei

On Fri, Oct 30, 2015 at 12:50 PM, Vladimir 'φ-coder/phcoder'
Serbinenko <phcoder@gmail.com> wrote:
>>
>> But how to deal with xen_initrd ?
>> Could you help me ?
>>
> Just another alias to module. Possibly you might want to add a code to
> xen_initrd tto check that xen_linux was already run

I think we need to be careful here. We need to think about future
extenstions (in particular to other architectures) and options
handling. E.g. initrd never accepted any option and we cannot really
add one probably now; but xen_initrd did IIRC (or may be I was
mistaken with xen_module). What I mean, we should allow additional
options from the very beginning, not just making it exact alias.

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 2/4] arm64: Add xen_boot module file
  2015-10-30  8:08       ` Fu Wei
@ 2015-11-03 14:57         ` Fu Wei
  2015-11-03 15:22           ` Ian Campbell
  0 siblings, 1 reply; 40+ messages in thread
From: Fu Wei @ 2015-11-03 14:57 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Ian Campbell,
	Stefano Stabellini, Andrei Borzenkov, Jon Masters, Leif Lindholm,
	Ryan Harkin, Linaro UEFI Mailman List

Hi Vladimir,

After discussing with Ian Campbell,   Since we already can load all
the necessary binaries for Xen boot on arm64 for now,  we don't really
need "xen_module" command now.
But maybe someday , xen need a new type of binary in boot time, then
we still need this support.

So I will submit  a   "xen_module" command patch soon, in case we need it.

Great thanks ! :-)

On 30 October 2015 at 16:08, Fu Wei <fu.wei@linaro.org> wrote:
> Hi Vladimir,
>
> yes, Thanks for your modification :-)
>
> I just follow the xen boot protocol :
> http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/Multiboot
>
> xen_module is just for "--type" option, I will discuss this with Xen
> developer for this.
> If we need this option, I will resubmit  it :-)
>
> Great thanks!
>
> On 29 October 2015 at 22:27, Vladimir 'φ-coder/phcoder' Serbinenko
> <phcoder@gmail.com> wrote:
>> Committed without the xen_module command. Its argument parsing was
>> non-trivial and I don't quite get what its intent is. Can you resubmit?
>> On 23.07.2015 07:16, fu.wei@linaro.org wrote:
>>> From: Fu Wei <fu.wei@linaro.org>
>>>
>>> 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(+)
>>>
>>> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
>>> index a6101de..796f7e9 100644
>>> --- a/grub-core/Makefile.core.def
>>> +++ b/grub-core/Makefile.core.def
>>> @@ -1648,6 +1648,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);
>>> +}
>>>
>>
>>
>
>
>
> --
> Best regards,
>
> Fu Wei
> Software Engineer
> Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
> Ph: +86 21 61221326(direct)
> Ph: +86 186 2020 4684 (mobile)
> Room 1512, Regus One Corporate Avenue,Level 15,
> One Corporate Avenue,222 Hubin Road,Huangpu District,
> Shanghai,China 200021



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 2/4] arm64: Add xen_boot module file
  2015-11-03 14:57         ` Fu Wei
@ 2015-11-03 15:22           ` Ian Campbell
  2015-11-05  9:46             ` Fu Wei
  0 siblings, 1 reply; 40+ messages in thread
From: Ian Campbell @ 2015-11-03 15:22 UTC (permalink / raw)
  To: Fu Wei, Vladimir 'φ-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB, xen-devel, Stefano Stabellini,
	Andrei Borzenkov, Jon Masters, Leif Lindholm, Ryan Harkin,
	Linaro UEFI Mailman List

On Tue, 2015-11-03 at 22:57 +0800, Fu Wei wrote:
> Hi Vladimir,
> 
> After discussing with Ian Campbell,   Since we already can load all
> the necessary binaries for Xen boot on arm64 for now,  we don't really
> need "xen_module" command now.
> But maybe someday , xen need a new type of binary in boot time, then
> we still need this support.

You mean support for "--type" passed to the xen_module command, right? I
thought the xen_module stuff had been applied. Or am I misunderstanding
which bits have been applied?

> So I will submit  a   "xen_module" command patch soon, in case we need
> it.

Just to clarify, my suggestion was to repost the bits which were omitted
from the prior patches just so that they are available in the ML archives
etc should anyone ever want to resurrect them in the future.

Ian.


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 2/4] arm64: Add xen_boot module file
  2015-11-03 15:22           ` Ian Campbell
@ 2015-11-05  9:46             ` Fu Wei
  0 siblings, 0 replies; 40+ messages in thread
From: Fu Wei @ 2015-11-05  9:46 UTC (permalink / raw)
  To: Ian Campbell
  Cc: The development of GNU GRUB, xen-devel, Stefano Stabellini,
	Andrei Borzenkov,
	Vladimir 'φ-coder/phcoder' Serbinenko,
	Leif Lindholm, Ryan Harkin, Linaro UEFI Mailman List,
	Jon Masters

Hi Ian,

On 3 November 2015 at 23:22, Ian Campbell <ian.campbell@citrix.com> wrote:
> On Tue, 2015-11-03 at 22:57 +0800, Fu Wei wrote:
>> Hi Vladimir,
>>
>> After discussing with Ian Campbell,   Since we already can load all
>> the necessary binaries for Xen boot on arm64 for now,  we don't really
>> need "xen_module" command now.
>> But maybe someday , xen need a new type of binary in boot time, then
>> we still need this support.
>
> You mean support for "--type" passed to the xen_module command, right? I
> thought the xen_module stuff had been applied. Or am I misunderstanding
> which bits have been applied?

Actually, I mean: xen-module command is for "--type" support. If we
don't need "--type" now, we can delete  xen-module code(which has been
deleted by Vladimir from my patch, so now, the upstream grub has not
--type support).
Vladimir has applied most of my patch, except xen-module command code.

>
>> So I will submit  a   "xen_module" command patch soon, in case we need
>> it.
>
> Just to clarify, my suggestion was to repost the bits which were omitted
> from the prior patches just so that they are available in the ML archives
> etc should anyone ever want to resurrect them in the future.

yes, that is what I am gonna do.

>
> Ian.
>



-- 
Best regards,

Fu Wei
Software Engineer
Red Hat Software (Beijing) Co.,Ltd.Shanghai Branch
Ph: +86 21 61221326(direct)
Ph: +86 186 2020 4684 (mobile)
Room 1512, Regus One Corporate Avenue,Level 15,
One Corporate Avenue,222 Hubin Road,Huangpu District,
Shanghai,China 200021

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v2 0/4] arm64,xen: add xen_boot support into grup-mkconfig
       [not found] <=fu.wei@linaro.org>
  2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
  2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
@ 2016-02-25  6:50 ` fu.wei
  2 siblings, 0 replies; 40+ messages in thread
From: fu.wei @ 2016-02-25  6:50 UTC (permalink / raw)
  To: grub-devel, arvidjaar, phcoder
  Cc: xen-devel, Ian.Campbell, jcm, julien.grall, leif.lindholm,
	linaro-uefi, Fu Wei

From: Fu Wei <fu.wei@linaro.org>

This patchset add xen_boot support into grup-mkconfig for
generating xen boot entrances automatically

Also update the docs/grub.texi for new xen_boot commands.

This patchset has been tested on Foudation model with a bug fix:
http://lists.gnu.org/archive/html/grub-devel/2016-02/msg00205.html

ChangeLog:
v2: add "--nounzip" option support in xen_module
    use "feature_xen_boot" instead of "grub_xen_boot"
    update the introduction of xen boot commands in docs/grub.texi

v1 :first upstream patchset:
    http://lists.gnu.org/archive/html/grub-devel/2016-02/msg00264.html

Fu Wei (4):
  arm64: add "--nounzip" option support in xen_module command
  * util/grub.d/20_linux_xen.in: Add xen_boot command support
  i386,xen: Add xen_hypervisor and xen_module aliases for i386
  arm64: update the introduction of xen boot commands in     
    docs/grub.texi

 docs/grub.texi                    | 32 +++++++++-----------------------
 grub-core/loader/arm64/xen_boot.c | 17 +++++++++++++++++
 grub-core/loader/i386/xen.c       |  7 +++++++
 grub-core/normal/main.c           |  2 +-
 util/grub.d/20_linux_xen.in       | 13 ++++++++++---
 5 files changed, 44 insertions(+), 27 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2016-02-25  6:50 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <=fu.wei@linaro.org>
2015-07-13  8:53 ` [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot fu.wei
2015-07-13  8:53   ` [PATCH v2 1/3] arm64: Add Xen boot support file fu.wei
2015-07-15 16:18     ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-07-16 16:46       ` Ian Campbell
2015-07-23 10:16       ` Fu Wei
2015-07-13  8:53   ` [PATCH v2 2/3] util/grub.d/20_linux_xen.in: Add arm64 support fu.wei
2015-07-14  3:53     ` Andrei Borzenkov
2015-07-14  9:41       ` Ian Campbell
2015-07-14 15:23         ` [Xen-devel] " Konrad Rzeszutek Wilk
2015-07-14 13:09       ` Fu Wei
2015-07-15 16:24         ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-07-13  8:54   ` [PATCH v2 3/3] arm64: Add the introduction of Xen boot command fu.wei
2015-07-14  9:29   ` [Xen-devel] [PATCH v2 0/3] arm64: Add multiboot support (via fdt) for Xen boot Ian Campbell
2015-07-14 11:56     ` Fu Wei
2015-07-15 15:56   ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-07-23  5:16 ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) fu.wei
2015-07-23  5:16   ` [PATCH v3 1/4] arm64: Add and export some accessor functions for xen boot fu.wei
2015-10-29 12:03     ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-10-30  7:11       ` Fu Wei
2015-07-23  5:16   ` [PATCH v3 2/4] arm64: Add xen_boot module file fu.wei
2015-10-29 14:27     ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-10-30  8:08       ` Fu Wei
2015-11-03 14:57         ` Fu Wei
2015-11-03 15:22           ` Ian Campbell
2015-11-05  9:46             ` Fu Wei
2015-07-23  5:16   ` [PATCH v3 3/4] * util/grub.d/20_linux_xen.in: Add support of the XEN boot on aarch64 fu.wei
2015-10-29 15:25     ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-10-29 19:53       ` Andrei Borzenkov
2015-10-30  8:44       ` Fu Wei
2015-10-30  9:50         ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-10-30 10:07           ` Andrei Borzenkov
2015-07-23  5:16   ` [PATCH v3 4/4] arm64: Add the introduction of xen boot commands in docs/grub.texi fu.wei
2015-08-04  8:34   ` [PATCH v3 0/4] arm64: Add Xen boot support (via fdt) Fu Wei
2015-09-08  3:38     ` Fu Wei
2015-09-30 16:00       ` Stefano Stabellini
2015-10-01 16:19         ` Stefano Stabellini
2015-10-29  2:43           ` Fu Wei
2015-10-29  6:06         ` Fu Wei
2015-10-29 11:00           ` Stefano Stabellini
2016-02-25  6:50 ` [PATCH v2 0/4] arm64,xen: add xen_boot support into grup-mkconfig fu.wei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).