Support for ramdisks when booting in PVH mode
Pierre Pronchery <[email protected]>
| Newsgroups | gmane.os.netbsd.devel.kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi tech-kern@, TL;DR this adds support for booting NetBSD/amd64 with QEMU’s -kernel/-initrd combination. I did not exactly do a good job at pushing for reviews or setting a deadline for my patch adding support for ramdisks when booting NetBSD/amd64 in PVH mode, and it no longer applied on -current for a while now. (See https://mail-index.netbsd.org/tech-kern/2025/03/31/msg030298.html) Thankfully I managed to make it work again last week-end, and I am attaching the updated patch to this message. Important note when testing: it works with plain filesystem images, but not with modules yet. I suppose supporting any combination of filesystem, modules or splash screen images could be done. Please review; with no objections I intend to commit it around this time next week. Thanks! Would have been great to have this in -11, but my bad for waiting/taking too long. Sorry! Cheers & HTH, -- khorben
patch-amd64-add-support-for-initrd-with-VM_GUEST_GENPVH.patch
(application/octet-stream, 6.4 KB)
diff --git a/sys/arch/amd64/amd64/genassym.cf b/sys/arch/amd64/amd64/genassym.cf
index 92291334bc8d..9031dda6a234 100644
--- a/sys/arch/amd64/amd64/genassym.cf
+++ b/sys/arch/amd64/amd64/genassym.cf
@@ -383,6 +383,12 @@ define SIR_XENIPL_HIGH SIR_XENIPL_HIGH
define EVTCHN_UPCALL_MASK offsetof(struct vcpu_info, evtchn_upcall_mask)
define HVM_START_INFO_SIZE sizeof(struct hvm_start_info)
define START_INFO_VERSION offsetof(struct hvm_start_info, version)
+define START_INFO_MODLIST_PADDR offsetof(struct hvm_start_info, modlist_paddr)
+define START_INFO_NR_MODULES offsetof(struct hvm_start_info, nr_modules)
+define HVM_MODLIST_ENTRY_SIZE sizeof(struct hvm_modlist_entry)
+define MODLIST_ENTRY_CMDLINE offsetof(struct hvm_modlist_entry, cmdline_paddr)
+define MODLIST_ENTRY_PADDR offsetof(struct hvm_modlist_entry, paddr)
+define MODLIST_ENTRY_SIZE offsetof(struct hvm_modlist_entry, size)
define MMAP_PADDR offsetof(struct hvm_start_info, memmap_paddr)
define MMAP_ENTRIES offsetof(struct hvm_start_info, memmap_entries)
define MMAP_ENTRY_SIZE sizeof(struct hvm_memmap_table_entry)
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index daf189b02019..24e2e5ce7c51 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1187,7 +1187,69 @@ ENTRY(start_pvh)
shrl $2, %ecx
rep movsl
- /* Copy cmdline_paddr after hvm_start_info */
+ /* Copy hvm_modlist_entry[] after hvm_start_info */
+ xor %ecx, %ecx
+ mov %ecx, START_INFO_MODLIST_PADDR(%eax)
+ movl START_INFO_NR_MODULES(%eax), %ecx /* Get nr_modules */
+ testl %ecx, %ecx /* if(nr_modules == 0) */
+ jz .modlist_copy_done /* goto modlist_copy_done */
+ movl %edi, START_INFO_MODLIST_PADDR(%eax) /* Set new modlist_paddr in hvm_start_info */
+ movl START_INFO_MODLIST_PADDR(%ebx), %esi
+ pushl %eax
+ movl $HVM_MODLIST_ENTRY_SIZE, %eax /* eax = sizeof(hvm_modlist_entry) */
+ mull %ecx /* eax * ecx => edx:eax */
+ movl %eax, %ecx
+ shrl $2, %ecx
+ rep movsl
+ popl %eax
+
+ /* Copy the modules after the hvm_modlist_entry[] */
+ xorl %ecx, %ecx /* ecx = i = 0 */
+.module_copy:
+ /* eax points to our hvm_start_info */
+ /* ecx is our counter (i) */
+ /* Copy the module */
+ movl START_INFO_MODLIST_PADDR(%eax), %edx /* edx = &hvm_modlist_entry[0] */
+ pushl %eax
+ movl $HVM_MODLIST_ENTRY_SIZE, %eax /* eax = sizeof(hvm_modlist_entry) */
+ pushl %ecx
+ pushl %edx
+ mull %ecx /* eax * ecx => edx:eax */
+ popl %edx
+ addl %eax, %edx /* edx = &hvm_modlist_entry[i] */
+ popl %ecx
+ /* Copy the module's cmdline */
+ movl MODLIST_ENTRY_CMDLINE(%edx), %esi
+ xorl %eax, %eax
+ movl %eax, MODLIST_ENTRY_CMDLINE(%edx) /* hvm_modlist_entry[i].cmdline = NULL */
+ cmpl %eax, %esi
+ popl %eax
+ je .module_cmdline_copy_done
+ movl %edi, MODLIST_ENTRY_CMDLINE(%edx) /* Set new cmdline_paddr in hvm_modlist_entry */
+ pushl %eax
+.module_cmdline_copy:
+ movb (%esi), %al
+ movsb
+ cmp $0, %al
+ jne .module_cmdline_copy
+ popl %eax
+.module_cmdline_copy_done:
+ /* Copy the module's content */
+ movl MODLIST_ENTRY_PADDR(%edx), %esi /* esi = hvm_modlist_entry[i].paddr */
+ movl %edi, MODLIST_ENTRY_PADDR(%edx) /* Set new paddr in hvm_modlist_entry */
+ pushl %ecx
+ movl MODLIST_ENTRY_SIZE(%edx), %ecx /* ecx = hvm_modlist_entry[i].size */
+ rep movsb
+ popl %ecx
+ inc %ecx /* i++ */
+ pushl %eax
+ movl START_INFO_NR_MODULES(%ebx), %eax /* eax = nr_modules */
+ cmpl %eax, %ecx /* if (ecx != nr_modules) */
+ popl %eax
+ jne .module_copy /* goto module_copy */
+.modlist_copy_done:
+
+ /* Copy cmdline_paddr after the modules */
movl CMDLINE_PADDR(%ebx), %esi
movl %edi, CMDLINE_PADDR(%eax) /* Set new cmdline_paddr in hvm_start_info */
.cmdline_copy:
diff --git a/sys/arch/amd64/conf/MICROVM b/sys/arch/amd64/conf/MICROVM
index 37724ecafde6..242a06848527 100644
--- a/sys/arch/amd64/conf/MICROVM
+++ b/sys/arch/amd64/conf/MICROVM
@@ -23,3 +23,7 @@ machine amd64 x86 xen
include "arch/x86/conf/MICROVM.common"
options EXEC_ELF64 # exec ELF binaries
+options MODULAR # new style module(7) framework
+
+options MEMORY_DISK_HOOKS # enable md specific hooks
+options MEMORY_DISK_DYNAMIC # enable dynamic resizing
diff --git a/sys/arch/x86/x86/x86_machdep.c b/sys/arch/x86/x86/x86_machdep.c
index bb82cdd451cf..5621fa543d1f 100644
--- a/sys/arch/x86/x86/x86_machdep.c
+++ b/sys/arch/x86/x86/x86_machdep.c
@@ -215,6 +215,62 @@ mm_md_physacc(paddr_t pa, vm_prot_t prot)
}
#ifdef MODULAR
+#ifdef XEN
+void x86_add_xen_modules(void);
+void
+x86_add_xen_modules(void)
+{
+#if defined(XENPVHVM) || defined(XENPVH)
+ uint32_t i;
+ struct hvm_modlist_entry *modlist;
+
+ if (hvm_start_info->nr_modules == 0) {
+ aprint_verbose("No Xen module info at boot\n");
+ return;
+ }
+ aprint_debug("%d Xen module(s) at boot\n", hvm_start_info->nr_modules);
+ modlist = (void *)((uintptr_t)hvm_start_info->modlist_paddr + KERNBASE);
+ for (i = 0; i < hvm_start_info->nr_modules; i++) {
+ if (memcmp(
+ (char *)((uintptr_t)modlist[i].paddr + KERNBASE),
+ "\177ELF", 4) == 0) {
+ aprint_debug("Prep module path=%s len=%"PRIu64" pa=%p\n",
+ "pvh-module",
+ modlist[i].size,
+ (void *)((uintptr_t)modlist[i].paddr + KERNBASE));
+ module_prime(
+ "pvh-module",
+ (void *)((uintptr_t)modlist[i].paddr + KERNBASE),
+ modlist[i].size);
+#ifdef SPLASHSCREEN
+ } else if (memcmp(
+ (char *)((uintptr_t)modlist[i].paddr + KERNBASE),
+ "\211PNG\r\n\032\n", 8) == 0 ||
+ memcmp(
+ (char *)((uintptr_t)modlist[i].paddr + KERNBASE),
+ "\377\330\377", 3) == 0) {
+ aprint_debug("Splash image path=%s len=%"PRIu64" pa=%p\n",
+ "pvh-image", modlist[i].size,
+ (void *)((uintptr_t)modlist[i].paddr + KERNBASE));
+ splash_setimage(
+ (void *)((uintptr_t)modlist[i].paddr + KERNBASE),
+ modlist[i].size);
+#endif
+#if defined(MEMORY_DISK_HOOKS) && defined(MEMORY_DISK_DYNAMIC)
+ } else {
+ 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);
+#endif
+ }
+ }
+#endif
+}
+#endif /* XEN */
/*
* Push any modules loaded by the boot loader.
*/
@@ -922,6 +978,9 @@ init_x86_clusters(void)
#ifdef XEN
if (pvh_boot) {
x86_add_xen_clusters();
+#ifdef MODULAR
+ x86_add_xen_modules();
+#endif
}
#endif /* XEN */
signature.asc
(application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEjPEp1wC4bxBrX8svMDjL25iGlwMFAmknKHUACgkQMDjL25iG lwPE8g/9GCJqAwYZNVA4sPMEymVTmWPA9SAlwIWEGDAx9Bq8jYScSln+q+9djVQg sOmYjkuI1h/PDYXwEnljBotqW6MYWzV7kb9SEb6exEFoIzVVfFImqhZF1STs2Wll Ncfa2K3HEB5e/7luCK3DI5G9Dh07SxumQjRnWg8Wgyhak0aLNsTrlnm44lGnt0nn 0lAjf14K1FVLtIXqgmW0ipw2Ry0w6nXIdoeMXXkU+QP71Fktyt5TUIoInZUgoDXi G9L6swwSpkLgM1WMKTZXurs97BdEPVSIrCSmIKXZbknt+hIotuvQQy+mRqoPG/xa gwtPsYlETnJ7y3FgYoL/YYrTapn6U5H5ikvQbNZSRe5c+OwC3K/5xMQTcadP4y3j eheUThiYevpuAnYEdj0Cbj1QzDueq7Q9K7DTaKOwv+hRX+ZtwQlNG2HoArZXyF90 1z1zT9eEitvHJw6Sp7PMRC28PiWobIPnTHDyM27OF5GOij7sgqLauGCzmcQEZpIo XPCOr8XFSAtZ4/EnKXRGyp2j2KhF9Bvn22gbTG3SFy7efMPLZ2XxnjgCkGEwA+oJ ZCVbRwWEfhiGbdrrts5zGiWBsBMEaMuGrjVxdDunEwj3b7thAZbfSjqjnlTqioBu xlz/TGeUjwhsNQpLklIKaIF4bmnc3xAlJyiU2xj2gXDsw5RPDcY= =1CjS -----END PGP SIGNATURE-----