grub-devel
[Top][All Lists]
Advanced

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

[PATCH] Add functionality for passing information to FreeBSD kernel


From: eric
Subject: [PATCH] Add functionality for passing information to FreeBSD kernel
Date: Sun, 5 Apr 2020 17:10:05 -0400

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 */
 
-- 
2.25.1




reply via email to

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