loader/i386/linux: Transfer EDID information to kernel
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. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Neal Gompa <ngompa13@gmail.com> Reviewed-by: Michael Chang <mchang@suse.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
a8379e693b
commit
e1b9d92a8b
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user