Support for disk images when loading ramdisks

Pierre Pronchery <[email protected]>
Newsgroups gmane.os.netbsd.devel.kernel
Message-ID <[email protected]>
		Hi tech-kern@,

For the purposes of smolBSD (https://smolbsd.org <https://smolbsd.org/>) and as presented
together with iMil@ (Cc’d here) during FOSDEM 2026
(https://fosdem.org/2026/schedule/event/BGPF3M-smolbsd/), I have written
a first patch supporting disk images when loading ramdisks: the code
looks for the presence of a GPT header in the second block (offset 512),
looks for the first partition marked with the "bootme" attribute, and
then uses this partition as the actual ramdisk filesystem.

It only adds this capacity when booting amd64 platforms in generic PVH
mode so far. However, it seems to me that this could also be useful in
at least two aspects:
- Saving disk space in NetBSD releases,
- Providing users with ready to use disk images.

I believe that distributing bootable disk images instead of filesystem
images is easier to handle for users, e.g., when flashing USB drives or
setting up virtualised environments. It would also be less confusing to
provide a single works-everywhere file for e.g., rescue operations,
usable as a virtual disk image or directly as a ramdisk. The memory cost
is just a few kilobytes of unused, unreclaimed memory. (The EFI/GPT
headers)

Your feedback is welcome about this capability; with a sufficient
consensus I could look into extending this patch for more situations and
platforms.

Also note that the generic PVH specification allows for parameters to be
assigned for each and every module provided at boot time; this could
allow different selection mechanisms for the partition to boot. (e.g.,
NAME=…)

Anyhow, you can find this work in the khorben/ramdisk-gpt branch of our
NetBSDfr/NetBSD-src GitHub fork, at:
https://github.com/NetBSDfr/NetBSD-src/tree/khorben/ramdisk-gpt


The corresponding diff is attached here as well.



Cheers & HTH,
-- 
khorben
0001-x86_machdep.c-support-ramdisk-filesystems-on-GPT.patch (application/octet-stream, 3.1 KB)
From 4ef4267f20998365c41d56e277813aa4fc13217e Mon Sep 17 00:00:00 2001
From: Pierre Pronchery <[email protected]>
Date: Wed, 4 Feb 2026 23:06:14 +0100
Subject: [PATCH] x86_machdep.c: support ramdisk filesystems on GPT

This allows supplying disk images as ramdisks when booting NetBSD in
generic PVH mode on NetBSD/amd64. The code looks for the presence of a
GPT header in the second block (offset 512), looks for the first
partition marked with the "bootme" attribute, and then uses this
partition as the actual ramdisk filesystem.

The block size is currently assumed to being fixed at 512 bytes.

Tested on NetBSD/amd64.
---
 sys/arch/x86/x86/x86_machdep.c | 44 +++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/sys/arch/x86/x86/x86_machdep.c b/sys/arch/x86/x86/x86_machdep.c
index e6eed198cbab..9bdc29dbc579 100644
--- a/sys/arch/x86/x86/x86_machdep.c
+++ b/sys/arch/x86/x86/x86_machdep.c
@@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.160 2025/12/05 17:58:12 khorben Ex
 #include <sys/sysctl.h>
 #include <sys/extent.h>
 #include <sys/rnd.h>
+#include <sys/disklabel_gpt.h>
 
 #include <x86/bootspace.h>
 #include <x86/cpuvar.h>
@@ -216,13 +217,15 @@ mm_md_physacc(paddr_t pa, vm_prot_t prot)
 
 #ifdef MODULAR
 #ifdef XEN
-void x86_add_xen_modules(void);
-void
+static void
 x86_add_xen_modules(void)
 {
 #if defined(XENPVHVM) || defined(XENPVH)
 	uint32_t i;
 	struct hvm_modlist_entry *modlist;
+	char name[37] = "pvh-filesystem";
+	uint64_t size;
+	char * addr;
 
 	if (hvm_start_info->nr_modules == 0) {
 		aprint_verbose("No Xen module info at boot\n");
@@ -258,13 +261,38 @@ x86_add_xen_modules(void)
 #endif
 #if defined(MEMORY_DISK_HOOKS) && defined(MEMORY_DISK_DYNAMIC)
 		} else {
+			const uint32_t blksz = 512;
+			char * lba0 = (char *)((uintptr_t)modlist[i].paddr + KERNBASE);
+			struct gpt_hdr * gh = (struct gpt_hdr *)(lba0 + blksz * GPT_HDR_BLKNO);
+			struct gpt_ent * ge;
+			uint32_t j;
+
+			size = modlist[i].size;
+			addr = lba0;
+			/* look for a GPT partition table */
+			if (size > sizeof(*gh) * 2 &&
+			    gh->hdr_size == GPT_HDR_SIZE &&
+			    gh->hdr_entsz == sizeof(*ge) &&
+			    memcmp(gh->hdr_sig, GPT_HDR_SIG, sizeof(gh->hdr_sig)) == 0) {
+				ge = (struct gpt_ent *)(lba0 + gh->hdr_lba_table * blksz);
+
+				for (j = 0; j < gh->hdr_entries; j++) {
+					uint32_t k;
+
+					/* look for a bootable partition */
+					if (ge[j].ent_attr & GPT_ENT_ATTR_BOOTME) {
+						for (k = 0; k < sizeof(ge->ent_name) / sizeof(*ge->ent_name); k++)
+							name[k] = ge[j].ent_name[k];
+						name[sizeof(name) - 1] = '\0';
+						size = (ge[j].ent_lba_end - ge[j].ent_lba_start) * blksz;
+						addr = lba0 + ge[j].ent_lba_start * blksz;
+						break;
+					}
+				}
+			}
 			aprint_debug("File-system image path=%s len=%"PRIu64" pa=%p\n",
-			    "pvh-filesystem",
-			    modlist[i].size,
-			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE));
-			md_root_setconf(
-			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE),
-			    modlist[i].size);
+			    name, size, addr);
+			md_root_setconf(addr, size);
 #endif
 		}
 	}
-- 
2.52.0
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEjPEp1wC4bxBrX8svMDjL25iGlwMFAmmJdtcACgkQMDjL25iG
lwO5eg//VYO4tYvxZ56yxhl7s7eftj/WEtXjAe3iQM+ZoCpSIhV79B9S5lto5D+5
AfK34jk3+/gDpHFSMrnVE3fa41fD7sadho4gUNKtj56VfqHle6AhvxUPHZneLVu3
nU+hvkAnFpLxKSkMht3o4as/iFNYI+QqLEvJ3ncoqnqrY/JzTr6ZJf+WKSbzkiUS
AE2QhRiDfkdg7xvfQ8iEmc7ypBqrWU29kmQOUXKp+sY/LXZ1LFAfa531RlQqtt9q
MRzykO00AU45A2G4t8FMzf78pws3aCbFyr0yZI6AfGhEZbF65xWB7e1T03TKCtKO
ODbDWYxeuajnWQEIoIGitAt/Kfjr+SfxnPxsBA9oxIk4pOt0LlBKPCl5Z9UoDwLf
iN/OqIv8H/ZqtVoAYNcycjQf7FafIxMi23DzNu4l0oCqLnm6tqwSya9M+kqS/03l
bTVtMZSmruWj3v9xWIBtc1efgkrxgzJ5rCtNCCE48lxYLF1uNwx/LiK8wTQX3plH
P7iWWR6tsDmplezeBt7dmD6ivdsgGjqJU8voQoRHAdE46okB7oChGhG0ZoB6W9gJ
6CKJ2OXo/3Nm4Qz0ADc43Hw8SfPumMHGJUxDu7vunWMolPfdVDqcAm/ZdGVAMd3w
9SAc/jRbFH2b61ZivZ9LJ4HUx9fR28fkrVK27DZ5VaKwz5ZHBdk=
=2Vtu
-----END PGP SIGNATURE-----
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.