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

Reply via email to