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-----