grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: grub-devel@gnu.org
Cc: Thomas Zimmermann <tzimmermann@suse.de>,
	Daniel Kiper <daniel.kiper@oracle.com>,
	Michael Chang <mchang@suse.com>, Neal Gompa <ngompa13@gmail.com>
Subject: [PATCH v2] loader/i386/linux: Transfer EDID information to kernel
Date: Thu,  2 Oct 2025 14:44:01 +0200	[thread overview]
Message-ID: <20251002124539.46131-1-tzimmermann@suse.de> (raw)

The Linux kernel's struct bootparams provides a field at offset 0x140
for storing an EDID header. Copy the video adapter's data to the field.

The edid_info field was added in 2003 (see "[FBDEV] EDID support from
OpenFirmware on PPC platoforms and from the BIOS on intel platforms."),
but only got useable in 2004 (see "[PATCH] Fix EDID_INFO in zero-page").
The boot protocol was at version 2.03 at that time.

The field was never used much, but with the recent addition of the efidrm
and vesadrm drivers to the kernel, it becomes much more useful. As with
the initial screen setup, these drivers can make use of the provided
EDID information for basic display output.

v2:
- fix coding style (Daniel)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Michael Chang <mchang@suse.com>
Reviewed-by: Neal Gompa <ngompa13@gmail.com>
---
 grub-core/loader/i386/linux.c | 16 ++++++++++++++++
 grub-core/video/video.c       | 21 +++++++++++++++++++++
 include/grub/video.h          |  2 ++
 3 files changed, 39 insertions(+)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 12731feb2..d6e291b2c 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -234,6 +234,7 @@ grub_e820_add_region (struct grub_boot_e820_entry *e820_entry, int *e820_num,
 static grub_err_t
 grub_linux_setup_video (struct linux_kernel_params *params)
 {
+  struct grub_video_edid_info edid_info;
   struct grub_video_mode_info mode_info;
   void *framebuffer;
   grub_err_t err;
@@ -245,6 +246,19 @@ grub_linux_setup_video (struct linux_kernel_params *params)
   if (driver_id == GRUB_VIDEO_DRIVER_NONE)
     return 1;
 
+  err = grub_video_get_edid (&edid_info);
+  if (err != GRUB_ERR_NONE)
+    grub_memset (&edid_info, 0, sizeof (edid_info));
+
+  /*
+   * We cannot transfer any extensions. Therefore clear
+   * the extension flag from the checksum and set the
+   * field to zero. Adding the extension flag to the
+   * checksum does the trick.
+   */
+  edid_info.checksum += edid_info.extension_flag;
+  edid_info.extension_flag = 0;
+
   err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
 
   if (err)
@@ -338,6 +352,8 @@ grub_linux_setup_video (struct linux_kernel_params *params)
     }
 #endif
 
+  grub_memcpy (params->edid_info, &edid_info, sizeof (params->edid_info));
+
   return GRUB_ERR_NONE;
 }
 
diff --git a/grub-core/video/video.c b/grub-core/video/video.c
index 8937da745..ce1ea0288 100644
--- a/grub-core/video/video.c
+++ b/grub-core/video/video.c
@@ -89,6 +89,27 @@ grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
   return GRUB_ERR_NONE;
 }
 
+/* Get information about connected display.  */
+grub_err_t
+grub_video_get_edid (struct grub_video_edid_info *edid_info)
+{
+  grub_err_t err;
+
+  if (grub_video_adapter_active == NULL)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  if (grub_video_adapter_active->get_edid != NULL)
+    {
+      err = grub_video_adapter_active->get_edid (edid_info);
+      if (err != GRUB_ERR_NONE)
+	return err;
+    }
+  else
+    grub_memset (edid_info, 0, sizeof (*edid_info));
+
+  return GRUB_ERR_NONE;
+}
+
 /* Determine optimized blitting formation for specified video mode info.  */
 enum grub_video_blit_format
 grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
diff --git a/include/grub/video.h b/include/grub/video.h
index 9dac0f379..761ee994a 100644
--- a/include/grub/video.h
+++ b/include/grub/video.h
@@ -445,6 +445,8 @@ grub_err_t EXPORT_FUNC (grub_video_get_info) (struct grub_video_mode_info *mode_
 grub_err_t EXPORT_FUNC (grub_video_get_info_and_fini) (struct grub_video_mode_info *mode_info,
 					 void **framebuffer);
 
+grub_err_t EXPORT_FUNC (grub_video_get_edid) (struct grub_video_edid_info *edid_info);
+
 enum grub_video_blit_format EXPORT_FUNC(grub_video_get_blit_format) (struct grub_video_mode_info *mode_info);
 
 grub_err_t grub_video_set_palette (unsigned int start, unsigned int count,
-- 
2.51.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

                 reply	other threads:[~2025-10-02 12:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251002124539.46131-1-tzimmermann@suse.de \
    --to=tzimmermann@suse.de \
    --cc=daniel.kiper@oracle.com \
    --cc=grub-devel@gnu.org \
    --cc=mchang@suse.com \
    --cc=ngompa13@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).