Hello,
Mike Kelly, le sam. 26 sept. 2026 23:28:37 +0100, a ecrit:
> The magic is used to select between multiboot1 and multiboot2 boot
> data registration. Multiboot2 implementation is deferred until later
> patches and attempts to boot with multiboot2 will panic for the time
> being.
> ---
> i386/i386at/model_dep.c | 69 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 61 insertions(+), 8 deletions(-)
>
> diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
> index b71ab71b..17cd452c 100644
> --- a/i386/i386at/model_dep.c
> +++ b/i386/i386at/model_dep.c
> @@ -41,6 +41,7 @@
> #include <mach/vm_prot.h>
> #include <mach/machine.h>
> #include <mach/machine/multiboot.h>
> +#include <mach/machine/multiboot2.h>
> #include <mach/xen.h>
>
> #include <kern/assert.h>
> @@ -311,17 +312,13 @@ void db_reset_cpu(void)
> #ifndef MACH_HYP
>
> static void
> -register_boot_data(const struct multiboot_raw_info *mbi)
> +register_mb1_boot_data(const struct multiboot_raw_info *mbi)
> {
> struct multiboot_raw_module *mod;
> struct elf_shdr *shdr;
> unsigned long tmp;
> unsigned int i;
>
> - extern char _start[], _end[];
> -
> - biosmem_register_boot_data(_kvtophys(&_start), _kvtophys(&_end), FALSE);
> -
> /* cmdline and modules are moved to a safe place by i386at_init. */
>
> if ((mbi->flags & MULTIBOOT_LOADER_CMDLINE) && (mbi->cmdline != 0)) {
> @@ -372,6 +369,28 @@ register_boot_data(const struct multiboot_raw_info *mbi)
> mbinfo_register_boot_data(mbi);
> }
>
> +static void
> +register_mb2_boot_data(const struct multiboot2_raw_info *mb2_info)
> +{
> + /* To be implemented. */
> + (void)mb2_info;
Better put a panic here already?
> +}
> +
> +/* Register the boot data for whichever of multiboot1 or multiboot2 is
> + in use. 'mb2_info' is NULL for the multiboot1 case. */
> +static void
> +register_boot_data(const struct multiboot2_raw_info *mb2_info)
> +{
> + extern char _start[], _end[];
> +
> + biosmem_register_boot_data(_kvtophys(&_start), _kvtophys(&_end), FALSE);
> +
> + if (mb2_info == NULL)
> + register_mb1_boot_data(&boot_info);
> + else
> + register_mb2_boot_data(mb2_info);
This intermediate function looks convoluted... I'd say rather move the
content of the register_boot_data function...
> +}
> +
> #endif /* MACH_HYP */
>
> /*
> @@ -379,7 +398,12 @@ register_boot_data(const struct multiboot_raw_info *mbi)
> * Turns on paging and changes the kernel segments to use high linear
> addresses.
> */
> static void
> +#ifndef MACH_XEN
> +/* Initialisation from multiboot1 has mb2_info == NULL */
> +i386at_init(const struct multiboot2_raw_info *mb2_info)
> +#else
> i386at_init(void)
> +#endif
> {
> /*
> * Initialize the PIC prior to any possible call to an spl.
> @@ -400,7 +424,7 @@ i386at_init(void)
> #ifdef MACH_HYP
> biosmem_xen_bootstrap();
> #else /* MACH_HYP */
> - register_boot_data((struct multiboot_raw_info *) &boot_info);
> + register_boot_data(mb2_info);
... directly here, where it makes better sense whether to call
register_mb1_boot_data or register_mb2_boot_data, like is done in a
subsequent patch.
> biosmem_bootstrap((struct multiboot_raw_info *) &boot_info);
> #endif /* MACH_HYP */
>
> @@ -527,8 +551,33 @@ void c_boot_entry(vm_offset_t bi)
> romputc = immc_romputc;
> #endif /* ENABLE_IMMEDIATE_CONSOLE */
>
> - /* Stash the boot_image_info pointer. */
> - boot_info = *(typeof(boot_info)*)phystokv(bi);
> +#ifndef MACH_XEN
> + const struct multiboot2_raw_info *mb2_info = NULL;
> +
> + if (magic == MULTIBOOT2_BOOTLOADER_MAGIC)
> + {
> + /* Mach exposes a copy of 'boot_info' via the "mbinfo"
> + device. A simple method of maintaining that interface
> + is to translate 'mb2_info' into 'boot_info' and capture
> + any multiboot2 specific information (eg. EFI)
> + separately. Thereafter 'mb2_info' can be
> + discarded. This translation cannot happen until after
> + memory bootstrapping which means that we cannot
> + immediately use 'boot_info'. */
> + mb2_info = (const struct multiboot2_raw_info *)phystokv(bi);
> +
> + panic("Multiboot2 not implemented yet");
> + }
> + else if (magic != MULTIBOOT_LOADER_MAGIC)
> + {
> + panic("Invalid multiboot configuration");
> + }
> + else
> +#endif
> + /* Stash the boot_image_info pointer for the XEN and
> + multiboot1 cases. */
> + boot_info = *(typeof(boot_info)*)phystokv(bi);
> +
> int cpu_type;
>
> /* Before we do _anything_ else, print the hello message.
> @@ -570,7 +619,11 @@ void c_boot_entry(vm_offset_t bi)
> /*
> * Do basic VM initialization
> */
> +#ifdef MACH_XEN
> i386at_init();
> +#else
> + i386at_init(mb2_info);
> +#endif
I'd say just let the xen case have mb2_info always NULL and simply avoid
functions having different prototypes?
Actually, for c_boot_entry, it'd be simpler to make
i386/xen/xen_boothdr.S pass the multiboot1 magic by hand rather than
having a different prototype, too.
Samuel