The existing load_boot_modules_from_dtb() reader walks
/chosen/multiboot,module nodes — a hand-rolled convention from
bugaevc/wip-aarch64 designed for bare-metal multi-module Hurd
boot via u-boot's `fdt mknod`.  No off-the-shelf bootloader
emits it, which is why our test harness has been using QEMU's
-device guest-loader to synthesise it.

Add a fallback for the standard arm64 boot protocol: when no
multiboot,module nodes are found, look for /chosen/linux,initrd-
start + linux,initrd-end + /chosen/bootargs and treat the pair
as a single bootstrap module.  Single-module by design — the
standard protocol has only one initrd slot.  Production
multi-module boots stay on the multiboot,module path above.

GRUB on arm64-efi emits this form natively when given `linux
<kernel>` + `initrd <module>`, which lets the upstream test
harness drive gnumach on arm64 the same way it drives x86:
grub-mkrescue ISO -> qemu -cdrom test.iso, no per-arch
boot-runner machinery.

The multiboot,module reader has no unit-test coverage on its
own (it lives for bare-metal users with the u-boot setup
documented in aarch64/BOOTING); the test suite added in
subsequent commits exercises both paths — the initrd path
through every per-test ISO run, and the multiboot,module path
through a dedicated test that boots via guest-loader.
---
 aarch64/aarch64/model_dep.c | 50 +++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/aarch64/aarch64/model_dep.c b/aarch64/aarch64/model_dep.c
index 9c09c052..b1f1611c 100644
--- a/aarch64/aarch64/model_dep.c
+++ b/aarch64/aarch64/model_dep.c
@@ -444,6 +444,56 @@ static __attribute__((noinline)) void 
load_boot_modules_from_dtb(void)
                i++;
        }
 
+       /*
+        *      Fall back to the standard arm64 boot protocol's initrd if no
+        *      multiboot,module nodes were found.  GRUB on arm64-efi, and any
+        *      stock arm bootloader using the linux command, emits the initial
+        *      ramdisk via /chosen/linux,initrd-start + linux,initrd-end and
+        *      the kernel command line via /chosen/bootargs.  Treat that pair
+        *      as a single bootstrap module so test harnesses (and anyone who
+        *      doesn't want to hand-roll the multiboot,module nodes per
+        *      aarch64/BOOTING) can drive gnumach through unmodified GRUB.
+        *
+        *      Single-module by design — the standard protocol has only one
+        *      initrd slot.  Production multi-module boots use the
+        *      multiboot,module path above.
+        */
+       if (i == 0) {
+               struct dtb_prop start_prop, end_prop, bootargs_prop;
+
+               start_prop = dtb_node_find_prop(&chosen, "linux,initrd-start");
+               end_prop = dtb_node_find_prop(&chosen, "linux,initrd-end");
+               bootargs_prop = dtb_node_find_prop(&chosen, "bootargs");
+
+               if (!DTB_IS_SENTINEL(start_prop) &&
+                   !DTB_IS_SENTINEL(end_prop) &&
+                   !DTB_IS_SENTINEL(bootargs_prop)) {
+                       vm_offset_t     off1 = 0, off2 = 0;
+                       uint64_t        initrd_start, initrd_end;
+
+                       initrd_start = dtb_prop_read_cells(&start_prop,
+                                                          start_prop.length / 
4,
+                                                          &off1);
+                       initrd_end = dtb_prop_read_cells(&end_prop,
+                                                        end_prop.length / 4,
+                                                        &off2);
+
+                       printf("module 0 (initrd): %s\n",
+                              (const char *) bootargs_prop.data);
+                       boot_modules[0].string = kvtophys((vm_offset_t)
+                                                         bootargs_prop.data);
+                       boot_modules[0].mod_start = initrd_start;
+                       boot_modules[0].mod_end = initrd_end;
+                       boot_modules[0].reserved = 0;
+
+                       pmap_reserve_phys_range(
+                               round_page(boot_modules[0].mod_start),
+                               round_page(boot_modules[0].mod_end));
+
+                       i = 1;
+               }
+       }
+
        if (i == 0)
                panic("No bootstrap modules loaded with Mach\n");
 
-- 
2.54.0


Reply via email to