grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Add functionality for passing information to FreeBSD kernel


From: Eric McCorkle
Subject: Re: [PATCH] Add functionality for passing information to FreeBSD kernel
Date: Sun, 5 Apr 2020 17:20:16 -0400
User-agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0

A couple of things...

First, these calls are in grub_cmd_freebsd, not grub_freebsd_boot.  They
seem to get dropped on the floor when placed in the latter, and I'm not
sure why.  This is going to cause some problems, because the EFI memory
map (which is produced by exit_boot_services) needs to get written out
as another metadata item, or else FreeBSD won't be able to use EFI
runtime services.  From the looks of things, this is a larger
restructuring than what I've done here.

Also, the GELI keys need to get passed into the kernel via keybuf
metadata.  I think I want to pull GELI code in from the FreeBSD loader,
as it's structured to do that (the current implementation has some
issues as well: it leaves key material on the stack).


On 4/5/20 5:10 PM, address@hidden wrote:
> From: Eric McCorkle <address@hidden>
> 
> Fixes GRUB with FreeBSD to pass EFI frame buffer info into the kernel at boot.
> 
> ---
>  grub-core/loader/i386/bsd.c        | 81 ++++++++++++++++++++++++++++++
>  include/grub/i386/freebsd_linker.h |  9 ++++
>  2 files changed, 90 insertions(+)
> 
> diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
> index eb82391db..d3dc1d27f 100644
> --- a/grub-core/loader/i386/bsd.c
> +++ b/grub-core/loader/i386/bsd.c
> @@ -76,6 +76,21 @@ static grub_uint32_t openbsd_root;
>  static struct grub_relocator *relocator = NULL;
>  static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk;
>  
> +#ifdef GRUB_MACHINE_EFI
> +struct freebsd_efi_fb
> +{
> +  grub_uint64_t fb_addr;
> +  grub_uint64_t fb_size;
> +  grub_uint32_t fb_height;
> +  grub_uint32_t fb_width;
> +  grub_uint32_t fb_stride;
> +  grub_uint32_t fb_mask_red;
> +  grub_uint32_t fb_mask_green;
> +  grub_uint32_t fb_mask_blue;
> +  grub_uint32_t fb_mask_reserved;
> +};
> +#endif
> +
>  struct bsd_tag
>  {
>    struct bsd_tag *next;
> @@ -591,6 +606,63 @@ freebsd_get_zfs (void)
>    grub_free (uuid);
>  }
>  
> +static grub_err_t
> +grub_freebsd_setup_fw_handle (void)
> +{
> +  grub_err_t err = GRUB_ERR_NONE;
> +#ifdef GRUB_MACHINE_EFI
> +
> +  /* Add EFI firmware handle */
> +  err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
> +                           FREEBSD_MODINFOMD_FW_HANDLE,
> +                           &grub_efi_system_table,
> +                           sizeof (grub_efi_system_table));
> +#endif
> +  return err;
> +}
> +
> +static grub_err_t
> +grub_freebsd_setup_video (void)
> +{
> +  grub_err_t err = GRUB_ERR_NONE;
> +
> +#ifdef GRUB_MACHINE_EFI
> +
> +  /* Add EFI frame buffer info */
> +  struct freebsd_efi_fb efifb;
> +  struct grub_video_mode_info mode_info;
> +  void *framebuffer;
> +
> +  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
> +
> +  if (err)
> +    return err;
> +
> +  efifb.fb_addr = (grub_addr_t) framebuffer;
> +  efifb.fb_height = mode_info.height;
> +  efifb.fb_width = mode_info.width;
> +  efifb.fb_stride = mode_info.pitch / mode_info.bytes_per_pixel;
> +  efifb.fb_size = mode_info.height * mode_info.pitch;
> +  efifb.fb_mask_red =
> +    ((1 << mode_info.red_mask_size) - 1) <<
> +    mode_info.red_field_pos;
> +  efifb.fb_mask_green =
> +    ((1 << mode_info.green_mask_size) - 1) <<
> +    mode_info.green_field_pos;
> +  efifb.fb_mask_blue =
> +    ((1 << mode_info.blue_mask_size) - 1) <<
> +    mode_info.blue_field_pos;
> +  efifb.fb_mask_reserved =
> +    ((1 << mode_info.reserved_mask_size) - 1) <<
> +    mode_info.reserved_field_pos;
> +  err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
> +                           FREEBSD_MODINFOMD_EFI_FB,
> +                           &efifb, sizeof (efifb));
> +#endif
> +
> +  return err;
> +}
> +
>  static grub_err_t
>  grub_freebsd_boot (void)
>  {
> @@ -1563,11 +1635,20 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int 
> argc, char *argv[])
>         if (err)
>           return err;
>  
> +          err = grub_freebsd_setup_fw_handle ();
> +          if (err)
> +            return err;
> +
> +          err = grub_freebsd_setup_video ();
> +          if (err)
> +            return err;
> +
>         err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
>                                  FREEBSD_MODINFOMD_KERNEND, &data, len);
>         if (err)
>           return err;
>       }
> +
>        grub_bsd_get_device (&freebsd_biosdev, &unit, &slice, &part);
>        freebsd_zfsguid = 0;
>        if (!is_64bit)
> diff --git a/include/grub/i386/freebsd_linker.h 
> b/include/grub/i386/freebsd_linker.h
> index 3c1eb64b6..2dab21678 100644
> --- a/include/grub/i386/freebsd_linker.h
> +++ b/include/grub/i386/freebsd_linker.h
> @@ -65,9 +65,18 @@
>  #define FREEBSD_MODINFOMD_HOWTO              0x0007  /* boothowto */
>  #define FREEBSD_MODINFOMD_KERNEND    0x0008  /* kernend */
>  #define FREEBSD_MODINFOMD_SHDR               0x0009  /* section header table 
> */
> +#define FREEBSD_MODINFOMD_CTORS_ADDR    0x000a  /* address of .ctors */
> +#define FREEBSD_MODINFOMD_CTORS_SIZE    0x000b  /* size of .ctors */
> +#define FREEBSD_MODINFOMD_FW_HANDLE     0x000c  /* firmware dependent handle 
> */
> +#define FREEBSD_MODINFOMD_KEYBUF        0x000d  /* crypto key intake buffer 
> */
>  #define FREEBSD_MODINFOMD_NOCOPY     0x8000  /* don't copy this metadata to 
> the kernel */
>  
>  #define FREEBSD_MODINFOMD_SMAP               0x1001
> +#define FREEBSD_MODINFOMD_SMAP_XATTR    0x1002
> +#define FREEBSD_MODINFOMD_DTBP          0x1003
> +#define FREEBSD_MODINFOMD_EFI_MAP       0x1004
> +#define FREEBSD_MODINFOMD_EFI_FB        0x1005
> +#define FREEBSD_MODINFOMD_EFI_MODULEP   0x1006
>  
>  #define FREEBSD_MODINFOMD_DEPLIST    (0x4001 | FREEBSD_MODINFOMD_NOCOPY)  /* 
> depends on */
>  
> 

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]