Update linux_kernel_params to match the latest upstream (v6.13.7) 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_system_table` 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.c...@oracle.com> --- grub-core/loader/i386/linux.c | 212 +++++++------- include/grub/i386/linux.h | 503 ++++++++++++++++++++++------------ 2 files changed, 436 insertions(+), 279 deletions(-) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index b7c1e057e14f..963650a53393 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -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; @@ -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_mem_desc_size = efi_desc_size; + ctx.params->efi_info.v0208.efi_mem_desc_version = efi_desc_version; + ctx.params->efi_info.v0208.efi_mmap = efi_mmap_target; + ctx.params->efi_info.v0208.efi_mmap_size = efi_mmap_size; #ifdef __x86_64__ - ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32); + ctx.params->efi_info.v0208.efi_mmap_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_mem_desc_size = efi_desc_size; + ctx.params->efi_info.v0206.efi_mem_desc_version = efi_desc_version; + ctx.params->efi_info.v0206.efi_mmap = efi_mmap_target; + ctx.params->efi_info.v0206.efi_mmap_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_mem_desc_size = efi_desc_size; + ctx.params->efi_info.v0204.efi_mem_desc_version = efi_desc_version; + ctx.params->efi_info.v0204.efi_mmap = efi_mmap_target; + ctx.params->efi_info.v0204.efi_mmap_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_signature = GRUB_LINUX_EFI_SIGNATURE; + linux_params.efi_info.v0208.efi_system_table = (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_system_table_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_signature = GRUB_LINUX_EFI_SIGNATURE; + linux_params.efi_info.v0206.efi_system_table = (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_signature = GRUB_LINUX_EFI_SIGNATURE_0204; + linux_params.efi_info.v0204.efi_system_table = (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); diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index d4b550869534..4b16b0de7b69 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -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,36 +90,92 @@ #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_uint64_t addr; - grub_uint64_t size; - grub_uint32_t type; + 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; -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. */ - }; +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; +}; -/* For the Linux/i386 boot protocol version 2.10. */ -struct linux_i386_kernel_header +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 code1[0x0020]; - grub_uint16_t cl_magic; /* Magic number 0xA33F */ - grub_uint16_t cl_offset; /* The offset of command line */ - grub_uint8_t code2[0x01F1 - 0x0020 - 2 - 2]; 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_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; /* 0xAA55 magic 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 */ @@ -124,17 +183,6 @@ struct linux_i386_kernel_header 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 */ -#define LINUX_LOADER_ID_LILO 0x0 -#define LINUX_LOADER_ID_LOADLIN 0x1 -#define LINUX_LOADER_ID_BOOTSECT 0x2 -#define LINUX_LOADER_ID_SYSLINUX 0x3 -#define LINUX_LOADER_ID_ETHERBOOT 0x4 -#define LINUX_LOADER_ID_ELILO 0x5 -#define LINUX_LOADER_ID_GRUB 0x7 -#define LINUX_LOADER_ID_UBOOT 0x8 -#define LINUX_LOADER_ID_XEN 0x9 -#define LINUX_LOADER_ID_GUJIN 0xa -#define LINUX_LOADER_ID_QEMU 0xb 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 */ @@ -142,14 +190,15 @@ struct linux_i386_kernel_header 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_uint16_t pad1; /* Unused */ + 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; /* Highest address for initrd */ - grub_uint32_t kernel_alignment; - grub_uint8_t relocatable; + 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; + 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; @@ -158,142 +207,162 @@ struct linux_i386_kernel_header grub_uint64_t pref_address; grub_uint32_t init_size; grub_uint32_t handover_offset; + grub_uint32_t kernel_info_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. */ -struct linux_kernel_params +struct grub_boot_e820_entry { - 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]; + 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_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_uint16_t base_address; + grub_uint16_t reserved1; + grub_uint32_t reserved2; + } isa; 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 */ - } v0206; + { + 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_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 alt_mem; /* 1e0 */ - - grub_uint8_t padding8[0x1e8 - 0x1e4]; - - grub_uint8_t mmap_size; /* 1e8 */ - - grub_uint8_t padding9[0x1ec - 0x1e9]; + { + 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; - grub_uint8_t secure_boot; /* 1ec */ +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; - grub_uint8_t padding10[0x1f1 - 0x1ed]; +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. */ + }; - /* Linux setup header copy - BEGIN. */ +/* For the Linux/i386 boot protocol version 2.10. */ +struct linux_i386_kernel_header +{ + grub_uint8_t code1[0x0020]; + grub_uint16_t cl_magic; /* Magic number 0xA33F */ + grub_uint16_t cl_offset; /* The offset of command line */ + grub_uint8_t code2[0x01F1 - 0x0020 - 2 - 2]; 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 */ @@ -301,10 +370,7 @@ struct linux_kernel_params 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 boot_flag; /* 0xAA55 magic number */ grub_uint16_t jump; /* Jump instruction */ grub_uint32_t header; /* Magic signature "HdrS" */ grub_uint16_t version; /* Boot protocol version supported */ @@ -312,6 +378,17 @@ struct linux_kernel_params 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 */ +#define LINUX_LOADER_ID_LILO 0x0 +#define LINUX_LOADER_ID_LOADLIN 0x1 +#define LINUX_LOADER_ID_BOOTSECT 0x2 +#define LINUX_LOADER_ID_SYSLINUX 0x3 +#define LINUX_LOADER_ID_ETHERBOOT 0x4 +#define LINUX_LOADER_ID_ELILO 0x5 +#define LINUX_LOADER_ID_GRUB 0x7 +#define LINUX_LOADER_ID_UBOOT 0x8 +#define LINUX_LOADER_ID_XEN 0x9 +#define LINUX_LOADER_ID_GUJIN 0xa +#define LINUX_LOADER_ID_QEMU 0xb 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 */ @@ -319,15 +396,14 @@ struct linux_kernel_params 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_uint16_t pad1; /* Unused */ 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_uint32_t initrd_addr_max; /* Highest address for initrd */ + grub_uint32_t kernel_alignment; + grub_uint8_t relocatable; grub_uint8_t min_alignment; grub_uint16_t xloadflags; - grub_uint32_t cmdline_size; /* Size of the kernel command line */ + grub_uint32_t cmdline_size; grub_uint32_t hardware_subarch; grub_uint64_t hardware_subarch_data; grub_uint32_t payload_offset; @@ -336,11 +412,92 @@ struct linux_kernel_params grub_uint64_t pref_address; grub_uint32_t init_size; grub_uint32_t handover_offset; - /* Linux setup header copy - END. */ +} GRUB_PACKED; - grub_uint8_t _pad7[40]; +/* 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 +{ + 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_system_table` 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; + 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 */ + } 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; + } efi_info; + + 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 */ -- 2.43.5 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel