loader/i386/linux: Calculate the setup_header length
Previously the setup_header length was just assumed to be the size of the linux_kernel_params struct. The linux x86 32-bit boot protocol says that the end of the linux_i386_kernel_header is at 0x202 + the byte value at 0x201 in the linux_i386_kernel_header. So, calculate the size of the header using the end of the linux_i386_kernel_header, rather than assume it is the size of the linux_kernel_params struct. Additionally, add some required members to the linux_kernel_params struct and align the content of linux_i386_kernel_header struct with it. New members naming was taken directly from Linux kernel source. linux_kernel_params and linux_i386_kernel_header structs require more cleanup. However, this is not urgent, so, let's do this after release. Just in case... Signed-off-by: Andrew Jeddeloh <andrew.jeddeloh@coreos.com> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com> Reviewed-by: Vladimir Serbinenko <phcoder@google.com> Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
This commit is contained in:
parent
ffe3921538
commit
e683cfb0cf
2 changed files with 27 additions and 3 deletions
|
@ -767,7 +767,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|||
linux_params.kernel_alignment = (1 << align);
|
||||
linux_params.ps_mouse = linux_params.padding10 = 0;
|
||||
|
||||
len = sizeof (linux_params) - sizeof (lh);
|
||||
/*
|
||||
* The Linux 32-bit boot protocol defines the setup header end
|
||||
* to be at 0x202 + the byte value at 0x201.
|
||||
*/
|
||||
len = 0x202 + *((char *) &linux_params.jump + 1);
|
||||
|
||||
/* Verify the struct is big enough so we do not write past the end. */
|
||||
if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) &linux_params) {
|
||||
grub_error (GRUB_ERR_BAD_OS, "Linux setup header too big");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* We've already read lh so there is no need to read it second time. */
|
||||
len -= sizeof(lh);
|
||||
|
||||
if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)
|
||||
{
|
||||
if (!grub_errno)
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
#define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0)
|
||||
#define VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit. */
|
||||
|
||||
/* Maximum number of MBR signatures to store. */
|
||||
#define EDD_MBR_SIG_MAX 16
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define GRUB_LINUX_EFI_SIGNATURE \
|
||||
|
@ -142,6 +145,7 @@ struct linux_i386_kernel_header
|
|||
grub_uint64_t setup_data;
|
||||
grub_uint64_t pref_address;
|
||||
grub_uint32_t init_size;
|
||||
grub_uint32_t handover_offset;
|
||||
} GRUB_PACKED;
|
||||
|
||||
/* Boot parameters for Linux based on 2.6.12. This is used by the setup
|
||||
|
@ -273,6 +277,7 @@ struct linux_kernel_params
|
|||
|
||||
grub_uint8_t padding9[0x1f1 - 0x1e9];
|
||||
|
||||
/* 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 */
|
||||
|
@ -311,9 +316,14 @@ struct linux_kernel_params
|
|||
grub_uint32_t payload_offset;
|
||||
grub_uint32_t payload_length;
|
||||
grub_uint64_t setup_data;
|
||||
grub_uint8_t pad2[120]; /* 258 */
|
||||
struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */
|
||||
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 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 290 */
|
||||
struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */
|
||||
} GRUB_PACKED;
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
|
|
Loading…
Reference in a new issue