[RFC PATCH 18/18] tests: dedicated multiboot, module DTB bootstrap test (aarch64)

Paulo Duarte <[email protected]>
Newsgroups gmane.os.hurd.bugs
Message-ID <[email protected]>
The main aarch64 test suite boots gnumach via u-boot running under
QEMU, which uses `fdt mknod` to inject the multiboot,module DTB
nodes documented in aarch64/BOOTING.  That exercises the kernel's
DTB reader through a real bootloader.  Add a second, smaller path
that exercises the same kernel code directly via QEMU's `-device
guest-loader` — which synthesises the same /chosen/multiboot,module
nodes without a bootloader in between.

Why have both:

  * **Fault isolation.**  If the main u-boot tests start failing,
    the dedicated test tells us whether it's u-boot/boot.scr/FAT
    image generation breaking or the kernel itself.  Without this
    test, a regression in our scripting machinery looks identical
    to a kernel regression and we'd have to debug from scratch.

  * **Lower-dependency smoke test.**  The dedicated test needs only
    qemu-system-aarch64.  No u-boot, no mkimage, no mkfs.vfat.
    If the u-boot infrastructure breaks for environmental reasons
    (qemu version, u-boot defconfig change in nixpkgs), the
    dedicated test still validates the kernel.

  * **Documentation by example.**  Shows the bare-metal Bugaev path
    concretely: this is what an embedded board with u-boot's
    `fdt mknod` ends up handing the kernel; here's the qemu
    equivalent that skips the bootloader.

test-multiboot-module-aarch64 reuses the test-hello module (its
only job is "kernel boots, runs the module, prints
TEST_SUCCESS_MARKER") so the test cost is just the runner script
+ a Makefrag.am entry, not a new test source.

The runner template lives in tests/run-multiboot-module-qemu.sh.template
rather than extending tests/run-qemu.sh.template — guest-loader's
bootargs= parameter needs eval-based shell quoting to thread
'${host-port}' / '$(...)' fragments verbatim to the boot-script
parser, and that machinery shouldn't pollute the main runner that
every other test uses.

Gated on HOST_aarch64 in tests/Makefrag.am; no effect on x86
builds.  Adds one to the aarch64 test count: 11 standard u-boot
tests + 1 multiboot-module test = 12, matching x86's 12.
---
 tests/Makefrag.am                           | 11 +++++
 tests/run-multiboot-module-qemu.sh.template | 45 +++++++++++++++++++++
 tests/user-qemu.mk                          | 25 ++++++++++++
 3 files changed, 81 insertions(+)
 create mode 100644 tests/run-multiboot-module-qemu.sh.template

diff --git a/tests/Makefrag.am b/tests/Makefrag.am
index d690adb8..206b0c6f 100644
--- a/tests/Makefrag.am
+++ b/tests/Makefrag.am
@@ -39,12 +39,23 @@ if !HOST_aarch64
 TESTS += tests/test-multiboot
 endif
 TESTS += $(USER_TESTS)
+# tests/test-multiboot-module-aarch64 exercises the multiboot,module
+# DTB convention via QEMU's -device guest-loader — the alternate
+# bootstrap path for users hand-building modules with u-boot's `fdt
+# mknod` per aarch64/BOOTING.  The rest of the test suite runs via
+# GRUB + linux,initrd-* (the standard arm64 boot protocol), so this
+# is the only test that gates the multiboot,module reader against
+# regressions.
+if HOST_aarch64
+TESTS += tests/test-multiboot-module-aarch64
+endif
 
 EXTRA_DIST += \
 	tests/README \
 	tests/grub.cfg.single.template \
 	tests/uboot.script.template \
 	tests/run-qemu.sh.template \
+	tests/run-multiboot-module-qemu.sh.template \
 	tests/include/syscalls.h \
 	tests/include/testlib.h \
 	tests/include/device/cons.h \
diff --git a/tests/run-multiboot-module-qemu.sh.template b/tests/run-multiboot-module-qemu.sh.template
new file mode 100644
index 00000000..de338613
--- /dev/null
+++ b/tests/run-multiboot-module-qemu.sh.template
@@ -0,0 +1,45 @@
+#!/bin/sh
+# Copyright (C) 2026 Free Software Foundation
+#
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 the program ; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# Boots gnumach via QEMU's `-device guest-loader`, which synthesises
+# /chosen/multiboot,module DTB nodes (bugaevc/wip-aarch64's
+# convention) — distinct from the standard GRUB + linux,initrd path
+# exercised by the rest of the test suite.  Both paths share the
+# kernel's load_boot_modules_from_dtb() reader; this test gates the
+# multiboot,module branch so a regression there gets caught.
+
+set -e
+
+cmd='QEMU_BIN QEMU_OPTS -kernel GNUMACH_BIN -device "guest-loader,kernel=tests/module-hello,addr=GUEST_LOADER_ADDR,bootargs=module-hello \${host-port} \${device-port} \$(task-create) \$(task-resume)"'
+log="tests/test-multiboot-module-aarch64.raw"
+
+echo "temp log $log"
+if which QEMU_BIN >/dev/null ; then
+    if ! eval "timeout -v --foreground --kill-after=3 60s $cmd" \
+            | tee $log | sed -n "/TEST_START_MARKER/"',$p' ; then
+        exit 10  # timeout
+    fi
+    if grep -qi 'TEST_FAILURE_MARKER' $log; then
+        exit 99  # error marker found, test explicitely failed
+    fi
+    if ! grep -q 'TEST_SUCCESS_MARKER' $log; then
+        exit 12  # missing reboot marker, maybe the kernel crashed
+    fi
+else
+    echo "skipping, QEMU_BIN not found"
+    exit 77
+fi
diff --git a/tests/user-qemu.mk b/tests/user-qemu.mk
index a55d4f7b..01aa8a10 100644
--- a/tests/user-qemu.mk
+++ b/tests/user-qemu.mk
@@ -305,6 +305,31 @@ tests/test-%: $(TEST_DEPS) $(srcdir)/tests/run-qemu.sh.template
 		>$@
 	chmod +x $@
 
+# Module load address for the multiboot,module test: RAM_BASE + 256 MB
+# under -M virt (RAM_BASE = 0x40000000), well clear of the kernel
+# image's load area and pmap_bootstrap's page-table allocations.  The
+# DTB node `reg` property guest-loader synthesises exposes this
+# address to gnumach.
+if HOST_aarch64
+TEST_MULTIBOOT_MODULE_ADDR = 0x50000000
+
+tests/test-multiboot-module-aarch64: tests/module-hello $(GNUMACH)	\
+				     $(srcdir)/tests/run-multiboot-module-qemu.sh.template
+	< $(srcdir)/tests/run-multiboot-module-qemu.sh.template	\
+		sed -e "s|QEMU_BIN|$(QEMU_BIN)|g"		\
+		    -e "s|QEMU_OPTS|$(QEMU_OPTS)|g"		\
+		    -e "s|GNUMACH_BIN|$(GNUMACH)|g"		\
+		    -e "s|GUEST_LOADER_ADDR|$(TEST_MULTIBOOT_MODULE_ADDR)|g"	\
+		    -e "s|TEST_START_MARKER|$(TEST_START_MARKER)|g"	\
+		    -e "s|TEST_SUCCESS_MARKER|$(TEST_SUCCESS_MARKER)|g"	\
+		    -e "s|TEST_FAILURE_MARKER|$(TEST_FAILURE_MARKER)|g"	\
+		>$@
+	chmod +x $@
+
+clean-test-multiboot-module-aarch64:
+	rm -f tests/test-multiboot-module-aarch64 tests/test-multiboot-module-aarch64.raw
+endif
+
 clean-test-%:
 	rm -f tests/test-$* tests/test-$*.iso tests/test-$*.log tests/test-$*.raw tests/test-$*.trs tests/module-$*
 
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.