loader/i386/linux: Update linux_kernel_params to match upstream

Update linux_kernel_params to match the v6.13.7 upstream version of boot_params.
Refactor most things out into structs, as the Linux kernel does.

edid_info should be a struct with "unsigned char dummy[128]" and efi_info should
be a struct as well, starting at 0x1c0. However, for backwards compatibility,
GRUB can have efi_systab at 0x1b8 and padding at 0x1bc (or padding at both spots).
This cuts into the end of edid_info. Make edid_info inline and only make it go
up to 0x1b8.

Signed-off-by: Patrick Colp <patrick.colp@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Patrick Colp 2025-04-03 14:04:11 -07:00 committed by Daniel Kiper
parent 6b64f297e5
commit 204a6ddfb3
2 changed files with 446 additions and 286 deletions

View File

@ -124,7 +124,7 @@ find_mmap_size (void)
grub_mmap_iterate (count_hook, &count);
mmap_size = count * sizeof (struct grub_e820_mmap);
mmap_size = count * sizeof (struct grub_boot_e820_entry);
/* Increase the size a bit for safety, because GRUB allocates more on
later. */
@ -212,20 +212,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
}
static grub_err_t
grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
grub_e820_add_region (struct grub_boot_e820_entry *e820_entry, int *e820_num,
grub_uint64_t start, grub_uint64_t size,
grub_uint32_t type)
{
int n = *e820_num;
if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
(e820_map[n - 1].type == type))
e820_map[n - 1].size += size;
if ((n > 0) && (e820_entry[n - 1].addr + e820_entry[n - 1].size == start) &&
(e820_entry[n - 1].type == type))
e820_entry[n - 1].size += size;
else
{
e820_map[n].addr = start;
e820_map[n].size = size;
e820_map[n].type = type;
e820_entry[n].addr = start;
e820_entry[n].size = size;
e820_entry[n].type = type;
(*e820_num)++;
}
return GRUB_ERR_NONE;
@ -253,43 +253,43 @@ grub_linux_setup_video (struct linux_kernel_params *params)
return 1;
}
params->lfb_width = mode_info.width;
params->lfb_height = mode_info.height;
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
params->screen_info.lfb_width = mode_info.width;
params->screen_info.lfb_height = mode_info.height;
params->screen_info.lfb_depth = mode_info.bpp;
params->screen_info.lfb_linelength = mode_info.pitch;
params->lfb_base = (grub_size_t) framebuffer;
params->screen_info.lfb_base = (grub_size_t) framebuffer;
#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
params->ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32);
params->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
params->screen_info.ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32);
params->screen_info.capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
#endif
params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536);
params->screen_info.lfb_size = ALIGN_UP (params->screen_info.lfb_linelength * params->screen_info.lfb_height, 65536);
params->red_mask_size = mode_info.red_mask_size;
params->red_field_pos = mode_info.red_field_pos;
params->green_mask_size = mode_info.green_mask_size;
params->green_field_pos = mode_info.green_field_pos;
params->blue_mask_size = mode_info.blue_mask_size;
params->blue_field_pos = mode_info.blue_field_pos;
params->reserved_mask_size = mode_info.reserved_mask_size;
params->reserved_field_pos = mode_info.reserved_field_pos;
params->screen_info.red_size = mode_info.red_mask_size;
params->screen_info.red_pos = mode_info.red_field_pos;
params->screen_info.green_size = mode_info.green_mask_size;
params->screen_info.green_pos = mode_info.green_field_pos;
params->screen_info.blue_size = mode_info.blue_mask_size;
params->screen_info.blue_pos = mode_info.blue_field_pos;
params->screen_info.rsvd_size = mode_info.reserved_mask_size;
params->screen_info.rsvd_pos = mode_info.reserved_field_pos;
if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y'))
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
else
{
switch (driver_id)
{
case GRUB_VIDEO_DRIVER_VBE:
params->lfb_size >>= 16;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
params->screen_info.lfb_size >>= 16;
params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_VESA;
break;
case GRUB_VIDEO_DRIVER_EFI_UGA:
case GRUB_VIDEO_DRIVER_EFI_GOP:
params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB;
params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_EFIFB;
break;
/* FIXME: check if better id is available. */
@ -307,7 +307,7 @@ grub_linux_setup_video (struct linux_kernel_params *params)
case GRUB_VIDEO_DRIVER_SDL:
case GRUB_VIDEO_DRIVER_NONE:
case GRUB_VIDEO_ADAPTER_CAPTURE:
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
break;
}
}
@ -332,9 +332,9 @@ grub_linux_setup_video (struct linux_kernel_params *params)
/* 6 is default after mode reset. */
width = 6;
params->red_mask_size = params->green_mask_size
= params->blue_mask_size = width;
params->reserved_mask_size = 0;
params->screen_info.red_size = params->screen_info.green_size
= params->screen_info.blue_size = width;
params->screen_info.rsvd_size = 0;
}
#endif
@ -391,7 +391,7 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size,
{
struct grub_linux_boot_ctx *ctx = data;
if (grub_e820_add_region (ctx->params->e820_map, &ctx->e820_num,
if (grub_e820_add_region (ctx->params->e820_table, &ctx->e820_num,
addr, size, type))
return 1;
@ -423,10 +423,10 @@ grub_linux_boot (void)
"bootpath", bootpath,
grub_strlen (bootpath) + 1,
&len);
linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
linux_params.ofw_num_items = 1;
linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
linux_params.ofw_idt = 0;
linux_params.olpc_ofw_header.ofw_magic = GRUB_LINUX_OFW_SIGNATURE;
linux_params.olpc_ofw_header.ofw_version = 1;
linux_params.olpc_ofw_header.cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
linux_params.olpc_ofw_header.irq_desc_table = 0;
}
#endif
@ -471,19 +471,19 @@ grub_linux_boot (void)
if (grub_linux_setup_video (&linux_params))
{
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
linux_params.video_mode = 0x3;
linux_params.screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_TEXT;
linux_params.screen_info.orig_video_mode = 0x3;
#else
linux_params.have_vga = 0;
linux_params.video_mode = 0;
linux_params.video_width = 0;
linux_params.video_height = 0;
linux_params.screen_info.orig_video_isVGA = 0;
linux_params.screen_info.orig_video_mode = 0;
linux_params.screen_info.orig_video_cols = 0;
linux_params.screen_info.orig_video_lines = 0;
#endif
}
#ifndef GRUB_MACHINE_IEEE1275
if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
if (linux_params.screen_info.orig_video_isVGA == GRUB_VIDEO_LINUX_TYPE_TEXT)
#endif
{
grub_term_output_t term;
@ -494,19 +494,19 @@ grub_linux_boot (void)
|| grub_strcmp (term->name, "ofconsole") == 0)
{
struct grub_term_coordinate pos = grub_term_getxy (term);
linux_params.video_cursor_x = pos.x;
linux_params.video_cursor_y = pos.y;
linux_params.video_width = grub_term_width (term);
linux_params.video_height = grub_term_height (term);
linux_params.screen_info.orig_x = pos.x;
linux_params.screen_info.orig_y = pos.y;
linux_params.screen_info.orig_video_cols = grub_term_width (term);
linux_params.screen_info.orig_video_lines = grub_term_height (term);
found = 1;
break;
}
if (!found)
{
linux_params.video_cursor_x = 0;
linux_params.video_cursor_y = 0;
linux_params.video_width = 80;
linux_params.video_height = 25;
linux_params.screen_info.orig_x = 0;
linux_params.screen_info.orig_y = 0;
linux_params.screen_info.orig_video_cols = 80;
linux_params.screen_info.orig_video_lines = 25;
}
}
@ -517,8 +517,8 @@ grub_linux_boot (void)
mmap_size = find_mmap_size ();
/* Make sure that each size is aligned to a page boundary. */
cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096);
if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS))
cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects
if (cl_offset < ((grub_size_t) linux_params.hdr.setup_sects << GRUB_DISK_SECTOR_BITS))
cl_offset = ALIGN_UP ((grub_size_t) (linux_params.hdr.setup_sects
<< GRUB_DISK_SECTOR_BITS), 4096);
ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);
@ -567,17 +567,17 @@ grub_linux_boot (void)
ctx.params = real_mode_mem;
*ctx.params = linux_params;
ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset;
ctx.params->hdr.cmd_line_ptr = ctx.real_mode_target + cl_offset;
grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline,
maximal_cmdline_size);
grub_dprintf ("linux", "code32_start = %x\n",
(unsigned) ctx.params->code32_start);
(unsigned) ctx.params->hdr.code32_start);
ctx.e820_num = 0;
if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx))
return grub_errno;
ctx.params->mmap_size = ctx.e820_num;
ctx.params->e820_entries = ctx.e820_num;
#ifdef GRUB_MACHINE_EFI
{
@ -596,42 +596,42 @@ grub_linux_boot (void)
efi_mmap_target = ctx.real_mode_target
+ ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem);
/* Pass EFI parameters. */
if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208)
if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0208)
{
ctx.params->v0208.efi_mem_desc_size = efi_desc_size;
ctx.params->v0208.efi_mem_desc_version = efi_desc_version;
ctx.params->v0208.efi_mmap = efi_mmap_target;
ctx.params->v0208.efi_mmap_size = efi_mmap_size;
ctx.params->efi_info.v0208.efi_memdesc_size = efi_desc_size;
ctx.params->efi_info.v0208.efi_memdesc_version = efi_desc_version;
ctx.params->efi_info.v0208.efi_memmap = efi_mmap_target;
ctx.params->efi_info.v0208.efi_memmap_size = efi_mmap_size;
#ifdef __x86_64__
ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32);
ctx.params->efi_info.v0208.efi_memmap_hi = (efi_mmap_target >> 32);
#endif
}
else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206)
else if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0206)
{
ctx.params->v0206.efi_mem_desc_size = efi_desc_size;
ctx.params->v0206.efi_mem_desc_version = efi_desc_version;
ctx.params->v0206.efi_mmap = efi_mmap_target;
ctx.params->v0206.efi_mmap_size = efi_mmap_size;
ctx.params->efi_info.v0206.efi_memdesc_size = efi_desc_size;
ctx.params->efi_info.v0206.efi_memdesc_version = efi_desc_version;
ctx.params->efi_info.v0206.efi_memmap = efi_mmap_target;
ctx.params->efi_info.v0206.efi_memmap_size = efi_mmap_size;
}
else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0204)
else if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0204)
{
ctx.params->v0204.efi_mem_desc_size = efi_desc_size;
ctx.params->v0204.efi_mem_desc_version = efi_desc_version;
ctx.params->v0204.efi_mmap = efi_mmap_target;
ctx.params->v0204.efi_mmap_size = efi_mmap_size;
ctx.params->efi_info.v0204.efi_memdesc_size = efi_desc_size;
ctx.params->efi_info.v0204.efi_memdesc_version = efi_desc_version;
ctx.params->efi_info.v0204.efi_memmap = efi_mmap_target;
ctx.params->efi_info.v0204.efi_memmap_size = efi_mmap_size;
}
}
#endif
#if defined (__x86_64__) && defined (GRUB_MACHINE_EFI)
if (grub_le_to_cpu16 (ctx.params->version) >= 0x020c &&
(linux_params.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0)
if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x020c &&
(linux_params.hdr.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0)
{
struct grub_relocator64_efi_state state64;
state64.rsi = ctx.real_mode_target;
state64.rip = ctx.params->code32_start + LINUX_X86_STARTUP64_OFFSET;
state64.rip = ctx.params->hdr.code32_start + LINUX_X86_STARTUP64_OFFSET;
return grub_relocator64_efi_boot (relocator, state64);
}
#endif
@ -641,7 +641,7 @@ grub_linux_boot (void)
state.ebp = state.edi = state.ebx = 0;
state.esi = ctx.real_mode_target;
state.esp = ctx.real_mode_target;
state.eip = ctx.params->code32_start;
state.eip = ctx.params->hdr.code32_start;
return grub_relocator32_boot (relocator, state, 0);
}
@ -791,7 +791,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, len - 0x1F1);
grub_memcpy (&linux_params.hdr.setup_sects, &lh.setup_sects, len - 0x1F1);
/* We've already read lh so there is no need to read it second time. */
len -= sizeof(lh);
@ -805,62 +805,62 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
linux_params.kernel_alignment = ((grub_uint32_t) 1 << align);
linux_params.ps_mouse = linux_params.padding11 = 0;
linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
linux_params.hdr.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
linux_params.hdr.kernel_alignment = ((grub_uint32_t) 1 << align);
linux_params.hdr.boot_flag = 0;
linux_params.hdr.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
/* These two are used (instead of cmd_line_ptr) by older versions of Linux,
and otherwise ignored. */
linux_params.cl_magic = GRUB_LINUX_CL_MAGIC;
linux_params.cl_offset = 0x1000;
linux_params.screen_info.cl_magic = GRUB_LINUX_CL_MAGIC;
linux_params.screen_info.cl_offset = 0x1000;
linux_params.ramdisk_image = 0;
linux_params.ramdisk_size = 0;
linux_params.hdr.ramdisk_image = 0;
linux_params.hdr.ramdisk_size = 0;
linux_params.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
linux_params.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
linux_params.hdr.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
linux_params.hdr.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
/* These are not needed to be precise, because Linux uses these values
only to raise an error when the decompression code cannot find good
space. */
linux_params.ext_mem = ((32 * 0x100000) >> 10);
linux_params.alt_mem = ((32 * 0x100000) >> 10);
linux_params.screen_info.ext_mem_k = ((32 * 0x100000) >> 10);
linux_params.alt_mem_k = ((32 * 0x100000) >> 10);
/* Ignored by Linux. */
linux_params.video_page = 0;
linux_params.screen_info.orig_video_page = 0;
/* Only used when `video_mode == 0x7', otherwise ignored. */
linux_params.video_ega_bx = 0;
linux_params.screen_info.orig_video_ega_bx = 0;
linux_params.font_size = 16; /* XXX */
linux_params.screen_info.orig_video_points = 16; /* XXX */
#ifdef GRUB_MACHINE_EFI
#ifdef __x86_64__
if (grub_le_to_cpu16 (linux_params.version) < 0x0208 &&
if (grub_le_to_cpu16 (linux_params.hdr.version) < 0x0208 &&
((grub_addr_t) grub_efi_system_table >> 32) != 0) {
grub_errno = grub_error (GRUB_ERR_BAD_OS, "kernel does not support 64-bit addressing");
goto fail;
}
#endif
if (grub_le_to_cpu16 (linux_params.version) >= 0x0208)
if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0208)
{
linux_params.v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
linux_params.v0208.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table;
linux_params.efi_info.v0208.efi_loader_signature = GRUB_LINUX_EFI_SIGNATURE;
linux_params.efi_info.v0208.efi_systab = (grub_uint32_t) (grub_addr_t) grub_efi_system_table;
#ifdef __x86_64__
linux_params.v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
linux_params.efi_info.v0208.efi_systab_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
#endif
}
else if (grub_le_to_cpu16 (linux_params.version) >= 0x0206)
else if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0206)
{
linux_params.v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
linux_params.v0206.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table;
linux_params.efi_info.v0206.efi_loader_signature = GRUB_LINUX_EFI_SIGNATURE;
linux_params.efi_info.v0206.efi_systab = (grub_uint32_t) (grub_addr_t) grub_efi_system_table;
}
else if (grub_le_to_cpu16 (linux_params.version) >= 0x0204)
else if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0204)
{
linux_params.v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
linux_params.v0204.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table;
linux_params.efi_info.v0204.efi_loader_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
linux_params.efi_info.v0204.efi_systab = (grub_uint32_t) (grub_addr_t) grub_efi_system_table;
}
#endif
@ -999,7 +999,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
}
else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0)
{
linux_params.loadflags |= GRUB_LINUX_FLAG_QUIET;
linux_params.hdr.loadflags |= GRUB_LINUX_FLAG_QUIET;
}
/* Create kernel command line. */
@ -1074,9 +1074,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
aligned_size = ALIGN_UP (size, 4096);
/* Get the highest address available for the initrd. */
if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0203)
{
addr_max = grub_cpu_to_le32 (linux_params.initrd_addr_max);
addr_max = grub_cpu_to_le32 (linux_params.hdr.initrd_addr_max);
/* XXX in reality, Linux specifies a bogus value, so
it is necessary to make sure that ADDR_MAX does not exceed
@ -1139,9 +1139,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
grub_dprintf ("linux", "Initrd (%p) at 0x%" PRIxGRUB_ADDR ", size=0x%" PRIxGRUB_SIZE "\n",
initrd_mem, initrd_mem_target, size);
linux_params.ramdisk_image = initrd_mem_target;
linux_params.ramdisk_size = size;
linux_params.root_dev = 0x0100; /* XXX */
linux_params.hdr.ramdisk_image = initrd_mem_target;
linux_params.hdr.ramdisk_size = size;
linux_params.hdr.root_dev = 0x0100; /* XXX */
fail:
grub_initrd_close (&initrd_ctx);

View File

@ -51,6 +51,9 @@
/* Maximum number of MBR signatures to store. */
#define EDD_MBR_SIG_MAX 16
/* Number of edd_info structs starting at EDDBUF. */
#define EDDMAXNR 6
#ifdef __x86_64__
#define GRUB_LINUX_EFI_SIGNATURE \
@ -87,22 +90,273 @@
#define GRUB_E820_NVS 4
#define GRUB_E820_BADRAM 5
struct grub_e820_mmap
#define GRUB_E820_MAX_ENTRIES_ZEROPAGE 128
struct grub_screen_info
{
grub_uint8_t orig_x; /* 0x00 */
grub_uint8_t orig_y; /* 0x01 */
grub_uint16_t ext_mem_k; /* 0x02 */
grub_uint16_t orig_video_page; /* 0x04 */
grub_uint8_t orig_video_mode; /* 0x06 */
grub_uint8_t orig_video_cols; /* 0x07 */
grub_uint8_t flags; /* 0x08 */
grub_uint8_t unused2; /* 0x09 */
grub_uint16_t orig_video_ega_bx; /* 0x0a */
grub_uint16_t unused3; /* 0x0c */
grub_uint8_t orig_video_lines; /* 0x0e */
grub_uint8_t orig_video_isVGA; /* 0x0f */
grub_uint16_t orig_video_points; /* 0x10 */
/* VESA graphic mode -- linear frame buffer */
grub_uint16_t lfb_width; /* 0x12 */
grub_uint16_t lfb_height; /* 0x14 */
grub_uint16_t lfb_depth; /* 0x16 */
grub_uint32_t lfb_base; /* 0x18 */
grub_uint32_t lfb_size; /* 0x1c */
grub_uint16_t cl_magic, cl_offset; /* 0x20 */
grub_uint16_t lfb_linelength; /* 0x24 */
grub_uint8_t red_size; /* 0x26 */
grub_uint8_t red_pos; /* 0x27 */
grub_uint8_t green_size; /* 0x28 */
grub_uint8_t green_pos; /* 0x29 */
grub_uint8_t blue_size; /* 0x2a */
grub_uint8_t blue_pos; /* 0x2b */
grub_uint8_t rsvd_size; /* 0x2c */
grub_uint8_t rsvd_pos; /* 0x2d */
grub_uint16_t vesapm_seg; /* 0x2e */
grub_uint16_t vesapm_off; /* 0x30 */
grub_uint16_t pages; /* 0x32 */
grub_uint16_t vesa_attributes; /* 0x34 */
grub_uint32_t capabilities; /* 0x36 */
grub_uint32_t ext_lfb_base; /* 0x3a */
grub_uint8_t _reserved[2]; /* 0x3e */
} GRUB_PACKED;
struct grub_apm_bios_info
{
grub_uint16_t version;
grub_uint16_t cseg;
grub_uint32_t offset;
grub_uint16_t cseg_16;
grub_uint16_t dseg;
grub_uint16_t flags;
grub_uint16_t cseg_len;
grub_uint16_t cseg_16_len;
grub_uint16_t dseg_len;
};
struct grub_ist_info
{
grub_uint32_t signature;
grub_uint32_t command;
grub_uint32_t event;
grub_uint32_t perf_level;
};
struct grub_sys_desc_table
{
grub_uint16_t length;
grub_uint8_t table[14];
};
struct grub_olpc_ofw_header {
grub_uint32_t ofw_magic; /* OFW signature */
grub_uint32_t ofw_version;
grub_uint32_t cif_handler; /* callback into OFW */
grub_uint32_t irq_desc_table;
} GRUB_PACKED;
struct grub_setup_header
{
grub_uint8_t setup_sects; /* The size of the setup in sectors */
grub_uint16_t root_flags; /* If the root is mounted readonly */
grub_uint32_t syssize; /* obsolete */
grub_uint16_t ram_size; /* obsolete */
grub_uint16_t vid_mode; /* Video mode control */
grub_uint16_t root_dev; /* Default root device number */
grub_uint16_t boot_flag; /* 1fe */
grub_uint16_t jump; /* Jump instruction */
grub_uint32_t header; /* Magic signature "HdrS" */
grub_uint16_t version; /* Boot protocol version supported */
grub_uint32_t realmode_swtch; /* Boot loader hook */
grub_uint16_t start_sys; /* The load-low segment (obsolete) */
grub_uint16_t kernel_version; /* Points to kernel version string */
grub_uint8_t type_of_loader; /* Boot loader identifier */
grub_uint8_t loadflags; /* Boot protocol option flags */
grub_uint16_t setup_move_size; /* Move to high memory size */
grub_uint32_t code32_start; /* Boot loader hook */
grub_uint32_t ramdisk_image; /* initrd load address */
grub_uint32_t ramdisk_size; /* initrd size */
grub_uint32_t bootsect_kludge; /* obsolete */
grub_uint16_t heap_end_ptr; /* Free memory after setup end */
grub_uint8_t ext_loader_ver; /* Extended loader version */
grub_uint8_t ext_loader_type; /* Extended loader type */
grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */
grub_uint32_t initrd_addr_max; /* Maximum initrd address */
grub_uint32_t kernel_alignment; /* Alignment of the kernel */
grub_uint8_t relocatable_kernel; /* Is the kernel relocatable */
grub_uint8_t min_alignment;
grub_uint16_t xloadflags;
grub_uint32_t cmdline_size; /* Size of the kernel command line */
grub_uint32_t hardware_subarch;
grub_uint64_t hardware_subarch_data;
grub_uint32_t payload_offset;
grub_uint32_t payload_length;
grub_uint64_t setup_data;
grub_uint64_t pref_address;
grub_uint32_t init_size;
grub_uint32_t handover_offset;
grub_uint32_t kernel_info_offset;
} GRUB_PACKED;
struct grub_boot_e820_entry
{
grub_uint64_t addr;
grub_uint64_t size;
grub_uint32_t type;
} GRUB_PACKED;
struct grub_edd_device_params
{
grub_uint16_t length;
grub_uint16_t info_flags;
grub_uint32_t num_default_cylinders;
grub_uint32_t num_default_heads;
grub_uint32_t sectors_per_track;
grub_uint64_t number_of_sectors;
grub_uint16_t bytes_per_sector;
grub_uint32_t dpte_ptr; /* 0xFFFFFFFF for our purposes */
grub_uint16_t key; /* = 0xBEDD */
grub_uint8_t device_path_info_length; /* = 44 */
grub_uint8_t reserved2;
grub_uint16_t reserved3;
grub_uint8_t host_bus_type[4];
grub_uint8_t interface_type[8];
union
{
struct
{
grub_uint16_t base_address;
grub_uint16_t reserved1;
grub_uint32_t reserved2;
} isa;
struct
{
grub_uint8_t bus;
grub_uint8_t slot;
grub_uint8_t function;
grub_uint8_t channel;
grub_uint32_t reserved;
} pci;
/* pcix is same as pci */
struct
{
grub_uint64_t reserved;
} ibnd;
struct
{
grub_uint64_t reserved;
} xprs;
struct
{
grub_uint64_t reserved;
} htpt;
struct
{
grub_uint64_t reserved;
} unknown;
} interface_path;
union
{
struct
{
grub_uint8_t device;
grub_uint8_t reserved1;
grub_uint16_t reserved2;
grub_uint32_t reserved3;
grub_uint64_t reserved4;
} ata;
struct
{
grub_uint8_t device;
grub_uint8_t lun;
grub_uint8_t reserved1;
grub_uint8_t reserved2;
grub_uint32_t reserved3;
grub_uint64_t reserved4;
} atapi;
struct
{
grub_uint16_t id;
grub_uint64_t lun;
grub_uint16_t reserved1;
grub_uint32_t reserved2;
} scsi;
struct
{
grub_uint64_t serial_number;
grub_uint64_t reserved;
} usb;
struct
{
grub_uint64_t eui;
grub_uint64_t reserved;
} i1394;
struct
{
grub_uint64_t wwid;
grub_uint64_t lun;
} fibre;
struct
{
grub_uint64_t identity_tag;
grub_uint64_t reserved;
} i2o;
struct
{
grub_uint32_t array_number;
grub_uint32_t reserved1;
grub_uint64_t reserved2;
} raid;
struct
{
grub_uint8_t device;
grub_uint8_t reserved1;
grub_uint16_t reserved2;
grub_uint32_t reserved3;
grub_uint64_t reserved4;
} sata;
struct
{
grub_uint64_t reserved1;
grub_uint64_t reserved2;
} unknown;
} device_path;
grub_uint8_t reserved4;
grub_uint8_t checksum;
} GRUB_PACKED;
struct grub_edd_info
{
grub_uint8_t device;
grub_uint8_t version;
grub_uint16_t interface_support;
grub_uint16_t legacy_max_cylinder;
grub_uint8_t legacy_max_head;
grub_uint8_t legacy_sectors_per_track;
struct grub_edd_device_params params;
} GRUB_PACKED;
enum
{
GRUB_VIDEO_LINUX_TYPE_TEXT = 0x01,
GRUB_VIDEO_LINUX_TYPE_VESA = 0x23, /* VESA VGA in graphic mode. */
GRUB_VIDEO_LINUX_TYPE_EFIFB = 0x70, /* EFI Framebuffer. */
GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70 /* Linear framebuffer without any additional functions. */
GRUB_VIDEO_LINUX_TYPE_VESA = 0x23, /* VESA VGA in graphic mode. */
GRUB_VIDEO_LINUX_TYPE_EFIFB = 0x70, /* EFI Framebuffer. */
GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70 /* Linear framebuffer without any additional functions. */
};
/* For the Linux/i386 boot protocol version 2.10. */
/* For the Linux/i386 boot protocol version 2.10. */
struct linux_i386_kernel_header
{
grub_uint8_t code1[0x0020];
@ -144,7 +398,7 @@ struct linux_i386_kernel_header
grub_uint16_t heap_end_ptr; /* Free memory after setup end */
grub_uint16_t pad1; /* Unused */
grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */
grub_uint32_t initrd_addr_max; /* Highest address for initrd */
grub_uint32_t initrd_addr_max; /* Highest address for initrd */
grub_uint32_t kernel_alignment;
grub_uint8_t relocatable;
grub_uint8_t min_alignment;
@ -160,187 +414,93 @@ struct linux_i386_kernel_header
grub_uint32_t handover_offset;
} GRUB_PACKED;
/* Boot parameters for Linux based on 2.6.12. This is used by the setup
sectors of Linux, and must be simulated by GRUB on EFI, because
the setup sectors depend on BIOS. */
/*
* Boot parameters for Linux based on 6.13.7 stable. This is used
* by the setup sectors of Linux, and must be simulated by GRUB
* on EFI, because the setup sectors depend on BIOS.
*/
struct linux_kernel_params
{
grub_uint8_t video_cursor_x; /* 0 */
grub_uint8_t video_cursor_y;
grub_uint16_t ext_mem; /* 2 */
grub_uint16_t video_page; /* 4 */
grub_uint8_t video_mode; /* 6 */
grub_uint8_t video_width; /* 7 */
grub_uint8_t padding1[0xa - 0x8];
grub_uint16_t video_ega_bx; /* a */
grub_uint8_t padding2[0xe - 0xc];
grub_uint8_t video_height; /* e */
grub_uint8_t have_vga; /* f */
grub_uint16_t font_size; /* 10 */
grub_uint16_t lfb_width; /* 12 */
grub_uint16_t lfb_height; /* 14 */
grub_uint16_t lfb_depth; /* 16 */
grub_uint32_t lfb_base; /* 18 */
grub_uint32_t lfb_size; /* 1c */
grub_uint16_t cl_magic; /* 20 */
grub_uint16_t cl_offset;
grub_uint16_t lfb_line_len; /* 24 */
grub_uint8_t red_mask_size; /* 26 */
grub_uint8_t red_field_pos;
grub_uint8_t green_mask_size;
grub_uint8_t green_field_pos;
grub_uint8_t blue_mask_size;
grub_uint8_t blue_field_pos;
grub_uint8_t reserved_mask_size;
grub_uint8_t reserved_field_pos;
grub_uint16_t vesapm_segment; /* 2e */
grub_uint16_t vesapm_offset; /* 30 */
grub_uint16_t lfb_pages; /* 32 */
grub_uint16_t vesa_attrib; /* 34 */
grub_uint32_t capabilities; /* 36 */
grub_uint32_t ext_lfb_base; /* 3a */
grub_uint8_t padding3[0x40 - 0x3e];
grub_uint16_t apm_version; /* 40 */
grub_uint16_t apm_code_segment; /* 42 */
grub_uint32_t apm_entry; /* 44 */
grub_uint16_t apm_16bit_code_segment; /* 48 */
grub_uint16_t apm_data_segment; /* 4a */
grub_uint16_t apm_flags; /* 4c */
grub_uint32_t apm_code_len; /* 4e */
grub_uint16_t apm_data_len; /* 52 */
grub_uint8_t padding4[0x60 - 0x54];
grub_uint32_t ist_signature; /* 60 */
grub_uint32_t ist_command; /* 64 */
grub_uint32_t ist_event; /* 68 */
grub_uint32_t ist_perf_level; /* 6c */
grub_uint64_t acpi_rsdp_addr; /* 70 */
grub_uint8_t padding5[0x80 - 0x78];
grub_uint8_t hd0_drive_info[0x10]; /* 80 */
grub_uint8_t hd1_drive_info[0x10]; /* 90 */
grub_uint16_t rom_config_len; /* a0 */
grub_uint8_t padding6[0xb0 - 0xa2];
grub_uint32_t ofw_signature; /* b0 */
grub_uint32_t ofw_num_items; /* b4 */
grub_uint32_t ofw_cif_handler; /* b8 */
grub_uint32_t ofw_idt; /* bc */
grub_uint8_t padding7[0x1b8 - 0xc0];
struct grub_screen_info screen_info; /* 0 */
struct grub_apm_bios_info apm_bios_info; /* 40 */
grub_uint8_t _pad2[4]; /* 54 */
grub_uint64_t tboot_addr; /* 58 */
struct grub_ist_info ist_info; /* 60 */
grub_uint64_t acpi_rsdp_addr; /* 70 */
grub_uint8_t _pad3[8]; /* 78 */
grub_uint8_t hd0_info[16]; /* 80 */
grub_uint8_t hd1_info[16]; /* 90 */
struct grub_sys_desc_table sys_desc_table; /* a0 */
struct grub_olpc_ofw_header olpc_ofw_header; /* b0 */
grub_uint32_t ext_ramdisk_image; /* c0 */
grub_uint32_t ext_ramdisk_size; /* c4 */
grub_uint32_t ext_cmd_line_ptr; /* c8 */
grub_uint8_t _pad4[112]; /* cc */
grub_uint32_t cc_blob_address; /* 13c */
/*
* edid_info should be a struct with "unsigned char dummy[128]" and
* efi_info should be a struct as well, starting at 0x1c0. However,
* for backwards compatibility, GRUB can have efi_systab at 0x1b8 and
* padding at 0x1bc (or padding at both spots). This cuts into the end
* of edid_info. Make edid_info inline and only make it go up to 0x1b8.
*/
grub_uint8_t edid_info[0x1b8 - 0x140]; /* 140 */
union
{
struct
{
grub_uint32_t efi_system_table; /* 1b8 */
grub_uint32_t padding7_1; /* 1bc */
grub_uint32_t efi_signature; /* 1c0 */
grub_uint32_t efi_mem_desc_size; /* 1c4 */
grub_uint32_t efi_mem_desc_version; /* 1c8 */
grub_uint32_t efi_mmap_size; /* 1cc */
grub_uint32_t efi_mmap; /* 1d0 */
} v0204;
{
grub_uint32_t efi_systab; /* 1b8 */
grub_uint32_t padding7_2; /* 1bc */
grub_uint32_t efi_loader_signature; /* 1c0 */
grub_uint32_t efi_memdesc_size; /* 1c4 */
grub_uint32_t efi_memdesc_version; /* 1c8 */
grub_uint32_t efi_memmap_size; /* 1cc */
grub_uint32_t efi_memmap; /* 1d0 */
} v0204;
struct
{
grub_uint32_t padding7_1; /* 1b8 */
grub_uint32_t padding7_2; /* 1bc */
grub_uint32_t efi_signature; /* 1c0 */
grub_uint32_t efi_system_table; /* 1c4 */
grub_uint32_t efi_mem_desc_size; /* 1c8 */
grub_uint32_t efi_mem_desc_version; /* 1cc */
grub_uint32_t efi_mmap; /* 1d0 */
grub_uint32_t efi_mmap_size; /* 1d4 */
{
grub_uint32_t padding7_1; /* 1b8 */
grub_uint32_t padding7_2; /* 1bc */
grub_uint32_t efi_loader_signature; /* 1c0 */
grub_uint32_t efi_systab; /* 1c4 */
grub_uint32_t efi_memdesc_size; /* 1c8 */
grub_uint32_t efi_memdesc_version; /* 1cc */
grub_uint32_t efi_memmap; /* 1d0 */
grub_uint32_t efi_memmap_size; /* 1d4 */
} v0206;
struct
{
grub_uint32_t padding7_1; /* 1b8 */
grub_uint32_t padding7_2; /* 1bc */
grub_uint32_t efi_signature; /* 1c0 */
grub_uint32_t efi_system_table; /* 1c4 */
grub_uint32_t efi_mem_desc_size; /* 1c8 */
grub_uint32_t efi_mem_desc_version; /* 1cc */
grub_uint32_t efi_mmap; /* 1d0 */
grub_uint32_t efi_mmap_size; /* 1d4 */
grub_uint32_t efi_system_table_hi; /* 1d8 */
grub_uint32_t efi_mmap_hi; /* 1dc */
} v0208;
};
{
grub_uint32_t padding7_1; /* 1b8 */
grub_uint32_t padding7_2; /* 1bc */
grub_uint32_t efi_loader_signature; /* 1c0 */
grub_uint32_t efi_systab; /* 1c4 */
grub_uint32_t efi_memdesc_size; /* 1c8 */
grub_uint32_t efi_memdesc_version; /* 1cc */
grub_uint32_t efi_memmap; /* 1d0 */
grub_uint32_t efi_memmap_size; /* 1d4 */
grub_uint32_t efi_systab_hi; /* 1d8 */
grub_uint32_t efi_memmap_hi; /* 1dc */
} v0208;
} efi_info;
grub_uint32_t alt_mem; /* 1e0 */
grub_uint8_t padding8[0x1e8 - 0x1e4];
grub_uint8_t mmap_size; /* 1e8 */
grub_uint8_t padding9[0x1ec - 0x1e9];
grub_uint8_t secure_boot; /* 1ec */
grub_uint8_t padding10[0x1f1 - 0x1ed];
/* Linux setup header copy - BEGIN. */
grub_uint8_t setup_sects; /* The size of the setup in sectors */
grub_uint16_t root_flags; /* If the root is mounted readonly */
grub_uint16_t syssize; /* obsolete */
grub_uint16_t swap_dev; /* obsolete */
grub_uint16_t ram_size; /* obsolete */
grub_uint16_t vid_mode; /* Video mode control */
grub_uint16_t root_dev; /* Default root device number */
grub_uint8_t padding11; /* 1fe */
grub_uint8_t ps_mouse; /* 1ff */
grub_uint16_t jump; /* Jump instruction */
grub_uint32_t header; /* Magic signature "HdrS" */
grub_uint16_t version; /* Boot protocol version supported */
grub_uint32_t realmode_swtch; /* Boot loader hook */
grub_uint16_t start_sys; /* The load-low segment (obsolete) */
grub_uint16_t kernel_version; /* Points to kernel version string */
grub_uint8_t type_of_loader; /* Boot loader identifier */
grub_uint8_t loadflags; /* Boot protocol option flags */
grub_uint16_t setup_move_size; /* Move to high memory size */
grub_uint32_t code32_start; /* Boot loader hook */
grub_uint32_t ramdisk_image; /* initrd load address */
grub_uint32_t ramdisk_size; /* initrd size */
grub_uint32_t bootsect_kludge; /* obsolete */
grub_uint16_t heap_end_ptr; /* Free memory after setup end */
grub_uint8_t ext_loader_ver; /* Extended loader version */
grub_uint8_t ext_loader_type; /* Extended loader type */
grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */
grub_uint32_t initrd_addr_max; /* Maximum initrd address */
grub_uint32_t kernel_alignment; /* Alignment of the kernel */
grub_uint8_t relocatable_kernel; /* Is the kernel relocatable */
grub_uint8_t min_alignment;
grub_uint16_t xloadflags;
grub_uint32_t cmdline_size; /* Size of the kernel command line */
grub_uint32_t hardware_subarch;
grub_uint64_t hardware_subarch_data;
grub_uint32_t payload_offset;
grub_uint32_t payload_length;
grub_uint64_t setup_data;
grub_uint64_t pref_address;
grub_uint32_t init_size;
grub_uint32_t handover_offset;
/* Linux setup header copy - END. */
grub_uint8_t _pad7[40];
grub_uint32_t alt_mem_k; /* 1e0 */
grub_uint32_t scratch; /* 1e4 */
grub_uint8_t e820_entries; /* 1e8 */
grub_uint8_t eddbuf_entries; /* 1e9 */
grub_uint8_t edd_mbr_sig_buf_entries; /* 1ea */
grub_uint8_t kbd_status; /* 1eb */
grub_uint8_t secure_boot; /* 1ec */
grub_uint8_t _pad5[2]; /* 1ed */
grub_uint8_t sentinel; /* 1ef */
grub_uint8_t _pad6[1]; /* 1f0 */
struct grub_setup_header hdr; /* 1f1 */
grub_uint8_t _pad7[0x290 - 0x1f1 - sizeof(struct grub_setup_header)];
grub_uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 290 */
struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */
struct grub_boot_e820_entry e820_table[GRUB_E820_MAX_ENTRIES_ZEROPAGE]; /* 2d0 */
grub_uint8_t _pad8[48]; /* cd0 */
struct grub_edd_info eddbuf[EDDMAXNR]; /* d00 */
grub_uint8_t _pad9[276]; /* eec */
} GRUB_PACKED;
#endif /* ! ASM_FILE */