bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 grub] hurdhelper: Add helper for loading GNU/Hurd multiboot mo


From: Damien Zammit
Subject: [PATCH v2 grub] hurdhelper: Add helper for loading GNU/Hurd multiboot modules
Date: Sun, 16 Jul 2023 10:40:29 +0000

This adds a new grub module called hurdhelper.

This module simplifies the loading of hurd multiboot modules
by allowing them to be loaded in one line (in order of loading).

A typical use case would be:

 grub> insmod hurdhelper
 grub> multiboot /boot/gnumach-1.8-486-dbg.gz root=part:2:device:wd0 noide
 grub> hurdmodules pci-arbiter acpi rumpdisk ext2fs exec
 grub> boot

This could, for example, allow hurd to be booted from the grub shell manually
without remembering and typing dozens of commands.

Signed-off-by: Damien Zammit <damien@zamaudio.com>
---
 grub-core/Makefile.core.def   |   8 ++
 grub-core/loader/hurdhelper.c | 201 ++++++++++++++++++++++++++++++++++
 grub-core/loader/multiboot.c  |   6 +
 include/grub/multiboot.h      |   1 +
 include/grub/multiboot2.h     |   1 +
 5 files changed, 217 insertions(+)
 create mode 100644 grub-core/loader/hurdhelper.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8022e1c0a..f2cdc3008 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1788,6 +1788,14 @@ module = {
   enable = i386_xen_pvh;
 };
 
+module = {
+  name = hurdhelper;
+  common = loader/hurdhelper.c;
+  enable = x86;
+  enable = i386_pc;
+  enable = i386_multiboot;
+};
+
 module = {
   name = xen_boot;
   arm64 = loader/arm64/xen_boot.c;
diff --git a/grub-core/loader/hurdhelper.c b/grub-core/loader/hurdhelper.c
new file mode 100644
index 000000000..bc25a6b7a
--- /dev/null
+++ b/grub-core/loader/hurdhelper.c
@@ -0,0 +1,201 @@
+/* hurdhelper.c - helper for loading GNU/Hurd multiboot modules. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022  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/loader.h>
+#include <grub/command.h>
+#ifdef GRUB_USE_MULTIBOOT2
+#include <grub/multiboot2.h>
+#define GRUB_MULTIBOOT(x) grub_multiboot2_ ## x
+#else
+#include <grub/multiboot.h>
+#define GRUB_MULTIBOOT(x) grub_multiboot_ ## x
+#endif
+#include <grub/cpu/multiboot.h>
+#include <grub/memory.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+
+#define MBI_STRLEN 512
+
+#define HURD_FS_PARAMS1                
"--multiboot-command-line=${kernel-command-line}"
+#define HURD_FS_PARAMS2                "--store-type=typed"
+#define HURD_FS_PARAMS3                "${root}"
+#define HURD_HOST_PRIV         "--host-priv-port=${host-port}"
+#define HURD_DEV_MASTER                "--device-master-port=${device-port}"
+#define HURD_PREFIX            "/hurd/"
+#define LIB_PREFIX             "/lib/"
+#define FS_TASK                        "ext2fs"
+#define EXEC_TASK              "exec"
+#define LD_SO_1                        "ld.so.1"
+#define STATIC_SUFFIX          ".static"
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_dl_t my_mod;
+
+static int
+is_fs_task (char *arg)
+{
+  if (!grub_strncmp(arg, FS_TASK, 6))
+    return 1;
+  else
+    return 0;
+}
+
+static int
+is_exec_task (char *arg)
+{
+  if (!grub_strncmp(arg, EXEC_TASK, 4))
+    return 1;
+  else
+    return 0;
+}
+
+static const char *
+lookup_suffix (char *arg)
+{
+  if (is_exec_task(arg))
+    return "";
+  else
+    return STATIC_SUFFIX;
+}
+
+static int
+zalloc_array(char *base[], int members, int size)
+{
+  int i;
+
+  for (i = 0; i < members; i++)
+    {
+      base[i] = grub_zalloc(size);
+      if (!base[i])
+        goto free_and_fail;
+    }
+  return 0;
+
+free_and_fail:
+  for (i--; i > 0; i--)
+    grub_free(base[i]);
+  return 1;
+}
+
+static grub_err_t
+grub_cmd_hurdmodules (grub_command_t cmd __attribute__ ((unused)),
+                     int argc, char *argv[])
+{
+  int err;
+
+  if (argc < 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("minimum two filenames 
expected"));
+
+  /* first module has different args */
+  {
+    char *new_argv[10];
+    err = zalloc_array(new_argv, 10, MBI_STRLEN);
+    if (err)
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create array for 
hurdhelper");
+    grub_snprintf(new_argv[0], MBI_STRLEN, "%s%s%s", HURD_PREFIX, argv[0], 
lookup_suffix(argv[0]));
+    grub_snprintf(new_argv[1], MBI_STRLEN, "%s", argv[0]);
+    grub_snprintf(new_argv[2], MBI_STRLEN, "%s", HURD_HOST_PRIV);
+    grub_snprintf(new_argv[3], MBI_STRLEN, "%s", HURD_DEV_MASTER);
+    grub_snprintf(new_argv[4], MBI_STRLEN, "%s", is_fs_task(argv[0]) ? 
HURD_FS_PARAMS1 : "");
+    grub_snprintf(new_argv[5], MBI_STRLEN, "--next-task=${%s-task}", argv[1]);
+    grub_snprintf(new_argv[6], MBI_STRLEN, "%s", is_fs_task(argv[0]) ? 
HURD_FS_PARAMS2 : "");
+    grub_snprintf(new_argv[7], MBI_STRLEN, "%s", is_fs_task(argv[0]) ? 
HURD_FS_PARAMS3 : "");
+    grub_snprintf(new_argv[8], MBI_STRLEN, "$(task-create)");
+    grub_snprintf(new_argv[9], MBI_STRLEN, "$(task-resume)");
+    err = GRUB_MULTIBOOT (cmd_module) (10, new_argv);
+    grub_free(new_argv[0]);
+    grub_free(new_argv[1]);
+    grub_free(new_argv[2]);
+    grub_free(new_argv[3]);
+    grub_free(new_argv[4]);
+    grub_free(new_argv[5]);
+    grub_free(new_argv[6]);
+    grub_free(new_argv[7]);
+    grub_free(new_argv[8]);
+    grub_free(new_argv[9]);
+    if (err)
+      return err;
+  }
+
+  argc--;
+  argv++;
+  for (; argc > 1 && !is_exec_task(argv[0]); argc--, argv++)
+    {
+      char *new_argv[7];
+      err = zalloc_array(new_argv, 7, MBI_STRLEN);
+      if (err)
+        return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create array for 
hurdhelper");
+      grub_snprintf(new_argv[0], MBI_STRLEN, "%s%s%s", HURD_PREFIX, argv[0], 
lookup_suffix(argv[0]));
+      grub_snprintf(new_argv[1], MBI_STRLEN, "%s", argv[0]);
+      grub_snprintf(new_argv[2], MBI_STRLEN, "%s", is_fs_task(argv[0]) ? 
HURD_FS_PARAMS1 : "");
+      grub_snprintf(new_argv[3], MBI_STRLEN, "--next-task=${%s-task}", 
argv[1]);
+      grub_snprintf(new_argv[4], MBI_STRLEN, "%s", is_fs_task(argv[0]) ? 
HURD_FS_PARAMS2 : "");
+      grub_snprintf(new_argv[5], MBI_STRLEN, "%s", is_fs_task(argv[0]) ? 
HURD_FS_PARAMS3 : "");
+      grub_snprintf(new_argv[6], MBI_STRLEN, "$(%s-task=task-create)", 
argv[0]);
+      err = GRUB_MULTIBOOT (cmd_module) (7, new_argv);
+      grub_free(new_argv[0]);
+      grub_free(new_argv[1]);
+      grub_free(new_argv[2]);
+      grub_free(new_argv[3]);
+      grub_free(new_argv[4]);
+      grub_free(new_argv[5]);
+      grub_free(new_argv[6]);
+      if (err)
+        return err;
+    }
+
+  /* exec module has different args */
+  {
+    char *new_argv[4];
+    err = zalloc_array(new_argv, 4, MBI_STRLEN);
+    if (err)
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create array for 
hurdhelper");
+    grub_snprintf(new_argv[0], MBI_STRLEN, "%s%s", LIB_PREFIX, LD_SO_1);
+    grub_snprintf(new_argv[1], MBI_STRLEN, "%s", EXEC_TASK);
+    grub_snprintf(new_argv[2], MBI_STRLEN, "%s%s", HURD_PREFIX, EXEC_TASK);
+    grub_snprintf(new_argv[3], MBI_STRLEN, "$(%s-task=task-create)", 
EXEC_TASK);
+    err = GRUB_MULTIBOOT (cmd_module) (4, new_argv);
+    grub_free(new_argv[0]);
+    grub_free(new_argv[1]);
+    grub_free(new_argv[2]);
+    grub_free(new_argv[3]);
+    if (err)
+      return err;
+  }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_hurdmodules;
+
+GRUB_MOD_INIT(hurdhelper)
+{
+  cmd_hurdmodules =
+    grub_register_command ("hurdmodules", grub_cmd_hurdmodules,
+                          0, N_("Load a HURD of multiboot modules."));
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(hurdhelper)
+{
+  grub_unregister_command (cmd_hurdmodules);
+}
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
index facb13f3d..1edb9048d 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -440,6 +440,12 @@ grub_cmd_module (grub_command_t cmd __attribute__ 
((unused)),
   return GRUB_ERR_NONE;
 }
 
+grub_err_t
+GRUB_MULTIBOOT (cmd_module) (int argc, char *argv[])
+{
+  return grub_cmd_module (NULL, argc, argv);
+}
+
 static grub_command_t cmd_multiboot, cmd_module;
 
 GRUB_MOD_INIT(multiboot)
diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h
index bd0a9873e..d801c5ecd 100644
--- a/include/grub/multiboot.h
+++ b/include/grub/multiboot.h
@@ -46,6 +46,7 @@ void grub_multiboot_free_mbi (void);
 grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]);
 grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
                                      int argc, char *argv[]);
+grub_err_t grub_multiboot_cmd_module (int argc, char *argv[]);
 void grub_multiboot_set_bootdev (void);
 void
 grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
index 502d34ef1..6f790863c 100644
--- a/include/grub/multiboot2.h
+++ b/include/grub/multiboot2.h
@@ -38,6 +38,7 @@ void grub_multiboot2_free_mbi (void);
 grub_err_t grub_multiboot2_init_mbi (int argc, char *argv[]);
 grub_err_t grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
                                      int argc, char *argv[]);
+grub_err_t grub_multiboot2_cmd_module (int argc, char *argv[]);
 void grub_multiboot2_set_bootdev (void);
 void
 grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize,
-- 
2.40.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]