[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH grub] hurdhelper: Add helper to load GNU/Hurd multiboot modules
From: |
Damien Zammit |
Subject: |
[PATCH grub] hurdhelper: Add helper to load GNU/Hurd multiboot modules |
Date: |
Fri, 30 Sep 2022 12:53:27 +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:
insmod multiboot
insmod hurdhelper
multiboot /boot/gnumach-1.8-486-dbg.gz root=part:2:device:wd0
hurdmodules /hurd/acpi.static /hurd/pci-arbiter.static
/hurd/rumpdisk.static \
/hurd/ext2fs.static /hurd/exec.static
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 | 190 ++++++++++++++++++++++++++++++++++++++++++
grub-core/loader/multiboot.c | 6 ++
include/grub/multiboot.h | 1 +
include/grub/multiboot2.h | 1 +
5 files changed, 206 insertions(+)
create mode 100644 grub-core/loader/hurdhelper.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 5212dfab1..240520189 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1800,6 +1800,14 @@ module = {
};
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;
enable = arm64;
diff --git a/grub-core/loader/hurdhelper.c b/grub-core/loader/hurdhelper.c
new file mode 100644
index 000000000..e868ec96a
--- /dev/null
+++ b/grub-core/loader/hurdhelper.c
@@ -0,0 +1,190 @@
+/* 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 HURD_CMDLINE
"--multiboot-command-line=${kernel-command-line}"
+#define HURD_HOST_PRIV "--host-priv-port=${host-port}"
+#define HURD_DEV_MASTER "--device-master-port=${device-port}"
+
+#define ACPI_TASK "acpi"
+#define PCI_TASK "pci-arbiter"
+#define DISK_TASK "rumpdisk"
+#define FS_TASK "ext2fs"
+#define EXEC_TASK "exec"
+
+#define MAX_MODULES 16
+#define MAX_PARAMS 32
+#define MAX_STRLEN 256
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_dl_t my_mod;
+static char *hurd_argv[MAX_MODULES][MAX_PARAMS];
+
+static const char *
+lookup_task (char *arg)
+{
+ char *start;
+ if ((start = grub_strrchr(arg, '/')))
+ start++;
+ else
+ start = arg;
+
+ if (!grub_strncmp(start, ACPI_TASK, 4))
+ return ACPI_TASK;
+ else if (!grub_strncmp(start, PCI_TASK, 11))
+ return PCI_TASK;
+ else if (!grub_strncmp(start, DISK_TASK, 8))
+ return DISK_TASK;
+ else if (!grub_strncmp(start, FS_TASK, 6))
+ return FS_TASK;
+ else if (!grub_strncmp(start, EXEC_TASK, 4))
+ return EXEC_TASK;
+ else
+ return "unknown";
+}
+
+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;
+ int i = 0;
+
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("minimum two filenames
expected"));
+
+ /* first module has different args */
+ {
+ err = zalloc_array(hurd_argv[i], 11, MAX_STRLEN);
+ if (err)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create array for
hurdhelper");
+ grub_snprintf(hurd_argv[i][0], MAX_STRLEN, "%s", argv[i]);
+ grub_snprintf(hurd_argv[i][1], MAX_STRLEN, "%s", lookup_task(argv[i]));
+ grub_snprintf(hurd_argv[i][2], MAX_STRLEN, HURD_HOST_PRIV);
+ grub_snprintf(hurd_argv[i][3], MAX_STRLEN, HURD_DEV_MASTER);
+ if (!grub_strncmp(lookup_task(argv[i]), FS_TASK, 6))
+ {
+ grub_snprintf(hurd_argv[i][4], MAX_STRLEN, HURD_CMDLINE);
+ grub_snprintf(hurd_argv[i][5], MAX_STRLEN, "-T");
+ grub_snprintf(hurd_argv[i][6], MAX_STRLEN, "typed");
+ grub_snprintf(hurd_argv[i][7], MAX_STRLEN, "${root}");
+ grub_snprintf(hurd_argv[i][8], MAX_STRLEN,
"--exec-server-task=${%s-task}",
+ lookup_task(argv[i+1]));
+ }
+ else
+ grub_snprintf(hurd_argv[i][8], MAX_STRLEN, "--next-task=${%s-task}",
lookup_task(argv[i+1]));
+ grub_snprintf(hurd_argv[i][9], MAX_STRLEN, "$(task-create)");
+ grub_snprintf(hurd_argv[i][10], MAX_STRLEN, "$(task-resume)");
+ err = GRUB_MULTIBOOT (cmd_module) (11, hurd_argv[i]);
+ if (err)
+ return err;
+ i++;
+ }
+
+ argc--;
+
+ for (; argc > 1; argc--)
+ {
+ err = zalloc_array(hurd_argv[i], 8, MAX_STRLEN);
+ if (err)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create array for
hurdhelper");
+ grub_snprintf(hurd_argv[i][0], MAX_STRLEN, "%s", argv[i]);
+ grub_snprintf(hurd_argv[i][1], MAX_STRLEN, "%s", lookup_task(argv[i]));
+ if (!grub_strncmp(lookup_task(argv[i]), FS_TASK, 6))
+ {
+ grub_snprintf(hurd_argv[i][2], MAX_STRLEN, HURD_CMDLINE);
+ grub_snprintf(hurd_argv[i][3], MAX_STRLEN, "-T");
+ grub_snprintf(hurd_argv[i][4], MAX_STRLEN, "typed");
+ grub_snprintf(hurd_argv[i][5], MAX_STRLEN, "${root}");
+ grub_snprintf(hurd_argv[i][6], MAX_STRLEN,
"--exec-server-task=${%s-task}",
+ lookup_task(argv[i+1]));
+ }
+ else
+ grub_snprintf(hurd_argv[i][6], MAX_STRLEN, "--next-task=${%s-task}",
lookup_task(argv[i+1]));
+ grub_snprintf(hurd_argv[i][7], MAX_STRLEN, "$(%s-task=task-create)",
lookup_task(argv[i]));
+ err = GRUB_MULTIBOOT (cmd_module) (8, hurd_argv[i]);
+ if (err)
+ return err;
+ i++;
+ }
+
+ /* last module has different args */
+ {
+ err = zalloc_array(hurd_argv[i], 3, MAX_STRLEN);
+ if (err)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create array for
hurdhelper");
+ grub_snprintf(hurd_argv[i][0], MAX_STRLEN, "%s", argv[i]);
+ grub_snprintf(hurd_argv[i][1], MAX_STRLEN, "%s", lookup_task(argv[i]));
+ grub_snprintf(hurd_argv[i][2], MAX_STRLEN, "$(%s-task=task-create)",
lookup_task(argv[i]));
+ err = GRUB_MULTIBOOT (cmd_module) (3, hurd_argv[i]);
+ 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 94be512c4..e733dfa60 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 d8847f753..2f5eaa951 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 b90aa6989..1f4ce0933 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.13.1
- [PATCH grub] hurdhelper: Add helper to load GNU/Hurd multiboot modules,
Damien Zammit <=