Signed-off-by: Stefan Reinauer <stepan@coresystems.de>

Index: i386/linux_load.c
===================================================================
--- i386/linux_load.c	(revision 131)
+++ i386/linux_load.c	(working copy)
@@ -21,7 +21,6 @@
  *
  * Based on work by Steve Gehlbach.
  * Portions are taken from mkelfImage.
- *
  * 2003-09 by SONE Takeshi
  */
 
@@ -36,145 +35,12 @@
 #define DEBUG_THIS CONFIG_DEBUG_LINUXLOAD
 #include <debug.h>
 
-#define LINUX_PARAM_LOC 0x90000
-#define COMMAND_LINE_LOC 0x91000
-#define GDT_LOC 0x92000
-#define STACK_LOC 0x93000
+#include "linux_load.h"
 
-#define E820MAX	32		/* number of entries in E820MAP */
-struct e820entry {
-	unsigned long long addr;	/* start of memory segment */
-	unsigned long long size;	/* size of memory segment */
-	unsigned long type;	/* type of memory segment */
-#define E820_RAM	1
-#define E820_RESERVED	2
-#define E820_ACPI	3	/* usable as RAM once ACPI tables have been read */
-#define E820_NVS	4
-};
-
-/* The header of Linux/i386 kernel */
-struct linux_header {
-	u8 reserved1[0x1f1];	/* 0x000 */
-	u8 setup_sects;		/* 0x1f1 */
-	u16 root_flags;		/* 0x1f2 */
-	u8 reserved2[6];	/* 0x1f4 */
-	u16 vid_mode;		/* 0x1fa */
-	u16 root_dev;		/* 0x1fc */
-	u16 boot_sector_magic;	/* 0x1fe */
-	/* 2.00+ */
-	u8 reserved3[2];	/* 0x200 */
-	u8 header_magic[4];	/* 0x202 */
-	u16 protocol_version;	/* 0x206 */
-	u32 realmode_swtch;	/* 0x208 */
-	u16 start_sys;		/* 0x20c */
-	u16 kver_addr;		/* 0x20e */
-	u8 type_of_loader;	/* 0x210 */
-	u8 loadflags;		/* 0x211 */
-	u16 setup_move_size;	/* 0x212 */
-	u32 code32_start;	/* 0x214 */
-	u32 ramdisk_image;	/* 0x218 */
-	u32 ramdisk_size;	/* 0x21c */
-	u8 reserved4[4];	/* 0x220 */
-	/* 2.01+ */
-	u16 heap_end_ptr;	/* 0x224 */
-	u8 reserved5[2];	/* 0x226 */
-	/* 2.02+ */
-	u32 cmd_line_ptr;	/* 0x228 */
-	/* 2.03+ */
-	u32 initrd_addr_max;	/* 0x22c */
-} __attribute__ ((packed));
-
-/* Paramters passed to 32-bit part of Linux
- * This is another view of the structure above.. */
-struct linux_params {
-	u8 orig_x;		/* 0x00 */
-	u8 orig_y;		/* 0x01 */
-	u16 ext_mem_k;		/* 0x02 -- EXT_MEM_K sits here */
-	u16 orig_video_page;	/* 0x04 */
-	u8 orig_video_mode;	/* 0x06 */
-	u8 orig_video_cols;	/* 0x07 */
-	u16 unused2;		/* 0x08 */
-	u16 orig_video_ega_bx;	/* 0x0a */
-	u16 unused3;		/* 0x0c */
-	u8 orig_video_lines;	/* 0x0e */
-	u8 orig_video_isVGA;	/* 0x0f */
-	u16 orig_video_points;	/* 0x10 */
-
-	/* VESA graphic mode -- linear frame buffer */
-	u16 lfb_width;		/* 0x12 */
-	u16 lfb_height;		/* 0x14 */
-	u16 lfb_depth;		/* 0x16 */
-	u32 lfb_base;		/* 0x18 */
-	u32 lfb_size;		/* 0x1c */
-	u16 cl_magic;		/* 0x20 */
-#define CL_MAGIC_VALUE 0xA33F
-	u16 cl_offset;		/* 0x22 */
-	u16 lfb_linelength;	/* 0x24 */
-	u8 red_size;		/* 0x26 */
-	u8 red_pos;		/* 0x27 */
-	u8 green_size;		/* 0x28 */
-	u8 green_pos;		/* 0x29 */
-	u8 blue_size;		/* 0x2a */
-	u8 blue_pos;		/* 0x2b */
-	u8 rsvd_size;		/* 0x2c */
-	u8 rsvd_pos;		/* 0x2d */
-	u16 vesapm_seg;		/* 0x2e */
-	u16 vesapm_off;		/* 0x30 */
-	u16 pages;		/* 0x32 */
-	u8 reserved4[12];	/* 0x34 -- 0x3f reserved for future expansion */
-
-	//struct apm_bios_info apm_bios_info;   /* 0x40 */
-	u8 apm_bios_info[0x40];
-	//struct drive_info_struct drive_info;  /* 0x80 */
-	u8 drive_info[0x20];
-	//struct sys_desc_table sys_desc_table; /* 0xa0 */
-	u8 sys_desc_table[0x140];
-	u32 alt_mem_k;		/* 0x1e0 */
-	u8 reserved5[4];	/* 0x1e4 */
-	u8 e820_map_nr;		/* 0x1e8 */
-	u8 reserved6[9];	/* 0x1e9 */
-	u16 mount_root_rdonly;	/* 0x1f2 */
-	u8 reserved7[4];	/* 0x1f4 */
-	u16 ramdisk_flags;	/* 0x1f8 */
-#define RAMDISK_IMAGE_START_MASK  	0x07FF
-#define RAMDISK_PROMPT_FLAG		0x8000
-#define RAMDISK_LOAD_FLAG		0x4000
-	u8 reserved8[2];	/* 0x1fa */
-	u16 orig_root_dev;	/* 0x1fc */
-	u8 reserved9[1];	/* 0x1fe */
-	u8 aux_device_info;	/* 0x1ff */
-	u8 reserved10[2];	/* 0x200 */
-	u8 param_block_signature[4];	/* 0x202 */
-	u16 param_block_version;	/* 0x206 */
-	u8 reserved11[8];	/* 0x208 */
-	u8 loader_type;		/* 0x210 */
-#define LOADER_TYPE_LOADLIN         1
-#define LOADER_TYPE_BOOTSECT_LOADER 2
-#define LOADER_TYPE_SYSLINUX        3
-#define LOADER_TYPE_ETHERBOOT       4
-#define LOADER_TYPE_KERNEL          5
-	u8 loader_flags;	/* 0x211 */
-	u8 reserved12[2];	/* 0x212 */
-	u32 kernel_start;	/* 0x214 */
-	u32 initrd_start;	/* 0x218 */
-	u32 initrd_size;	/* 0x21c */
-	u8 reserved12_5[8];	/* 0x220 */
-	u32 cmd_line_ptr;	/* 0x228 */
-	u8 reserved13[164];	/* 0x22c */
-	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
-	u8 reserved16[688];	/* 0x550 */
-#define COMMAND_LINE_SIZE 256
-	/* Command line is copied here by 32-bit i386/kernel/head.S.
-	 * So I will follow the boot protocol, rather than putting it
-	 * directly here. --ts1 */
-	u8 command_line[COMMAND_LINE_SIZE];	/* 0x800 */
-	u8 reserved17[1792];	/* 0x900 - 0x1000 */
-};
-
 u64 forced_memsize;
 
 /* Load the first part the file and check if it's Linux */
-static u32 load_linux_header(struct linux_header *hdr)
+static u32 load_linux_header(struct linux_params *hdr)
 {
 	int load_high;
 	u32 kern_addr;
@@ -184,16 +50,16 @@
 		return 0;
 	}
 
-	if (hdr->boot_sector_magic != 0xaa55) {
+	if (hdr->hdr.boot_flag != 0xaa55) {
 		printf("Not a Linux kernel image\n");
 		return 0;
 	}
 
 	/* Linux is found. Print some information */
-	if (memcmp(hdr->header_magic, "HdrS", 4) != 0) {
+	if (memcmp(hdr->hdr.header, "HdrS", 4) != 0) {
 		/* This may be floppy disk image or something.
 		 * Perform a simple (incomplete) sanity check. */
-		if (hdr->setup_sects >= 16 || file_size() - (hdr->setup_sects << 9) >= 512 << 10) {
+		if (hdr->hdr.setup_sects >= 16 || file_size() - (hdr->hdr.setup_sects << 9) >= 512 << 10) {
 			printf("This looks like a bootdisk image but not like Linux...\n");
 			return 0;
 		}
@@ -201,14 +67,14 @@
 		printf("Possible very old Linux");
 		/* This kernel does not even have a protocol version.
 		 * Force the value. */
-		hdr->protocol_version = 0;	/* pre-2.00 */
+		hdr->hdr.version = 0;	/* pre-2.00 */
 	} else {
 		printf("Found Linux");
 	}
 
-	if (hdr->protocol_version >= 0x200 && hdr->kver_addr) {
+	if (hdr->hdr.version >= 0x200 && hdr->hdr.kernel_version) {
 		char kver[256];
-		file_seek(hdr->kver_addr + 0x200);
+		file_seek(hdr->hdr.kernel_version + 0x200);
 		if (file_read(kver, sizeof kver) != 0) {
 			kver[255] = 0;
 			printf(" version %s", kver);
@@ -217,9 +83,9 @@
 	debug(" (protocol %#x)", hdr->protocol_version);
 
 	load_high = 0;
-	if (hdr->protocol_version >= 0x200) {
-		debug(" (loadflags %#x)", hdr->loadflags);
-		load_high = hdr->loadflags & 1;
+	if (hdr->hdr.version >= 0x200) {
+		debug(" (loadflags %#x)", hdr->hdr.loadflags);
+		load_high = hdr->hdr.loadflags & 1;
 	}
 	if (load_high) {
 		printf(" bzImage");
@@ -236,27 +102,30 @@
 
 /* Set up parameters for 32-bit kernel */
 static void
-init_linux_params(struct linux_params *params, struct linux_header *hdr)
+init_linux_params(struct linux_params *params, struct linux_params *hdr)
 {
 	debug("Setting up paramters at %#lx\n", virt_to_phys(params));
 	memset(params, 0, sizeof *params);
 
 	/* Copy some useful values from header */
-	params->mount_root_rdonly = hdr->root_flags;
-	params->orig_root_dev = hdr->root_dev;
+	params->hdr.root_flags = hdr->hdr.root_flags;
+	params->hdr.root_dev = hdr->hdr.root_dev;
 
 	/* Video parameters.
 	 * This assumes we have VGA in standard 80x25 text mode,
 	 * just like our vga.c does.
 	 * Cursor position is filled later to allow some more printf's.
 	 */
-	params->orig_video_mode = 3;
-	params->orig_video_cols = 80;
-	params->orig_video_lines = 25;
-	params->orig_video_isVGA = 1;
-	params->orig_video_points = 16;
+	params->screen_info.orig_video_mode = 3;
+	params->screen_info.orig_video_cols = 80;
+	params->screen_info.orig_video_lines = 25;
+	params->screen_info.orig_video_isVGA = 1;
+	params->screen_info.orig_video_points = 16;
 
-	params->loader_type = 0xff;	/* Unregistered Linux loader */
+	params->hdr.loader_type = 0xff;	/* Unregistered Linux loader */
+
+	/* Set it to 16M instead of 4G */
+	params->hdr.kernel_alignment = 16*1024*1024;
 }
 
 /* Memory map */
@@ -280,7 +149,7 @@
 			debug("%016Lx - %016Lx (%d)\n", linux_map->addr,
 			      linux_map->addr + linux_map->size,
 			      linux_map->type);
-			params->e820_map_nr = i + 1;
+			params->e820_entries = i + 1;
 		}
 
 		/* Find out top of RAM. XXX This ignores hole above 1MB */
@@ -296,37 +165,39 @@
 	params->alt_mem_k = (ramtop - (1 << 20)) >> 10;
 	/* old style, 64MB max */
 	if (ramtop >= (64 << 20))
-		params->ext_mem_k = (63 << 10);
+		params->screen_info.ext_mem_k = (63 << 10);
 	else
-		params->ext_mem_k = params->alt_mem_k;
-	debug("ext_mem_k=%d, alt_mem_k=%d\n", params->ext_mem_k,
-	      params->alt_mem_k);
+		params->screen_info.ext_mem_k = params->alt_mem_k;
+	debug("ext_mem_k=%d, alt_mem_k=%d\n", params->screen_info.ext_mem_k,
+	      params->screen_info.alt_mem_k);
 }
 
 /* Video mode */
 static void set_video_mode(struct linux_params *params)
 {
 #if CONFIG_COREBOOT_VIDEO_CONSOLE
+	struct screen_info *screen_info = &params->screen_info;
+
 	/* Are we running on a framebuffer console? */
 	if (!lib_sysinfo.framebuffer)
 		return;
 
-	params->lfb_width = lib_sysinfo.framebuffer->x_resolution;
-	params->lfb_height = lib_sysinfo.framebuffer->y_resolution;
-	params->lfb_depth = lib_sysinfo.framebuffer->bits_per_pixel;
-	params->lfb_linelength = lib_sysinfo.framebuffer->bytes_per_line;
-	params->lfb_base = lib_sysinfo.framebuffer->physical_address;
+	screen_info->lfb_width = lib_sysinfo.framebuffer->x_resolution;
+	screen_info->lfb_height = lib_sysinfo.framebuffer->y_resolution;
+	screen_info->lfb_depth = lib_sysinfo.framebuffer->bits_per_pixel;
+	screen_info->lfb_linelength = lib_sysinfo.framebuffer->bytes_per_line;
+	screen_info->lfb_base = lib_sysinfo.framebuffer->physical_address;
 	// prolly not enough for the boot splash?!
-	params->lfb_size =
-	    (params->lfb_linelength * params->lfb_height + 65535) >> 16;
-	params->red_size = lib_sysinfo.framebuffer->red_mask_size;
-	params->red_pos = lib_sysinfo.framebuffer->red_mask_pos;
-	params->green_size = lib_sysinfo.framebuffer->green_mask_size;
-	params->green_pos = lib_sysinfo.framebuffer->green_mask_pos;
-	params->blue_size = lib_sysinfo.framebuffer->blue_mask_size;
-	params->blue_pos = lib_sysinfo.framebuffer->blue_mask_pos;
-	params->rsvd_size = lib_sysinfo.framebuffer->reserved_mask_size;
-	params->rsvd_pos = lib_sysinfo.framebuffer->reserved_mask_pos;
+	screen_info->lfb_size =
+	    (screen_info->lfb_linelength * screen_info->lfb_height + 65535) >> 16;
+	screen_info->red_size = lib_sysinfo.framebuffer->red_mask_size;
+	screen_info->red_pos = lib_sysinfo.framebuffer->red_mask_pos;
+	screen_info->green_size = lib_sysinfo.framebuffer->green_mask_size;
+	screen_info->green_pos = lib_sysinfo.framebuffer->green_mask_pos;
+	screen_info->blue_size = lib_sysinfo.framebuffer->blue_mask_size;
+	screen_info->blue_pos = lib_sysinfo.framebuffer->blue_mask_pos;
+	screen_info->rsvd_size = lib_sysinfo.framebuffer->reserved_mask_size;
+	screen_info->rsvd_pos = lib_sysinfo.framebuffer->reserved_mask_pos;
 #endif
 }
 
@@ -455,26 +326,26 @@
 
 /* Set command line location */
 static void set_command_line_loc(struct linux_params *params,
-				 struct linux_header *hdr)
+				 struct linux_params *hdr)
 {
-	if (hdr->protocol_version >= 0x202) {
+	if (hdr->hdr.version >= 0x202) {
 		/* new style */
-		params->cmd_line_ptr = COMMAND_LINE_LOC;
+		params->hdr.cmd_line_ptr = COMMAND_LINE_LOC;
 	} else {
 		/* old style */
-		params->cl_magic = CL_MAGIC_VALUE;
-		params->cl_offset = COMMAND_LINE_LOC - LINUX_PARAM_LOC;
+		params->screen_info.cl_magic = CL_MAGIC_VALUE;
+		params->screen_info.cl_offset = COMMAND_LINE_LOC - LINUX_PARAM_LOC;
 	}
 }
 
 /* Load 32-bit part of kernel */
-static int load_linux_kernel(struct linux_header *hdr, u32 kern_addr)
+static int load_linux_kernel(struct linux_params *hdr, u32 kern_addr)
 {
 	u32 kern_offset, kern_size;
 
-	if (hdr->setup_sects == 0)
-		hdr->setup_sects = 4;
-	kern_offset = (hdr->setup_sects + 1) * 512;
+	if (hdr->hdr.setup_sects == 0)
+		hdr->hdr.setup_sects = 4;
+	kern_offset = (hdr->hdr.setup_sects + 1) * 512;
 	file_seek(kern_offset);
 	kern_size = file_size() - kern_offset;
 	debug("offset=%#x addr=%#x size=%#x\n", kern_offset, kern_addr,
@@ -496,7 +367,7 @@
 	return kern_size;
 }
 
-static int load_initrd(struct linux_header *hdr,
+static int load_initrd(struct linux_params *hdr,
 		       u32 kern_end, struct linux_params *params,
 		       const char *initrd_file)
 {
@@ -522,8 +393,8 @@
 
 	/* Find out the kernel's restriction on how high the initrd can be
 	 * placed */
-	if (hdr->protocol_version >= 0x203)
-		max = hdr->initrd_addr_max;
+	if (hdr->hdr.version >= 0x203)
+		max = hdr->hdr.ramdisk_max;
 	else
 		max = 0x38000000;	/* Hardcoded value for older kernels */
 
@@ -586,8 +457,8 @@
 	}
 	printf("ok\n");
 
-	params->initrd_start = start;
-	params->initrd_size = size;
+	params->hdr.ramdisk_start = start;
+	params->hdr.ramdisk_size = size;
 
 	return 0;
 }
@@ -680,8 +551,8 @@
 	/* Update VGA cursor position.
 	 * This must be here because the printf changes the value! */
 	video_console_get_cursor(&cursor_x, &cursor_y, &cursor_en);
-	params->orig_x = cursor_x;
-	params->orig_y = cursor_y;
+	params->screen_info.orig_x = cursor_x;
+	params->screen_info.orig_y = cursor_y;
 #endif
 
 #ifdef CONFIG_PCMCIA_CF
@@ -701,7 +572,7 @@
 
 int linux_load(const char *file, const char *cmdline)
 {
-	struct linux_header hdr;
+	static struct linux_params hdr;
 	struct linux_params *params;
 	u32 kern_addr, kern_size;
 	char *initrd_file = 0;
Index: i386/linux_load.h
===================================================================
--- i386/linux_load.h	(revision 0)
+++ i386/linux_load.h	(revision 0)
@@ -0,0 +1,213 @@
+/*
+ * This file is part of FILO.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <libpayload.h>
+
+#define COMMAND_LINE_SIZE 256
+
+#define LINUX_PARAM_LOC  0x90000
+#define COMMAND_LINE_LOC 0x91000
+#define GDT_LOC		 0x92000
+#define STACK_LOC	 0x93000
+
+#define EDD_MBR_SIG_MAX	16	
+#define E820MAX		128	/* number of entries in E820MAP */
+struct e820entry {
+	u64 addr;	/* start of memory segment */
+	u64 size;	/* size of memory segment */
+	u32 type;	/* type of memory segment */
+#define E820_RAM	1
+#define E820_RESERVED	2
+#define E820_ACPI	3	/* usable as RAM once ACPI tables have been read */
+#define E820_NVS	4
+#define E820_UNUSABLE	5
+};
+
+struct screen_info {
+	u8  orig_x;			/* 0x00 */
+	u8  orig_y;			/* 0x01 */
+	u16 ext_mem_k;			/* 0x02 */
+	u16 orig_video_page;		/* 0x04 */
+	u8  orig_video_mode;		/* 0x06 */
+	u8  orig_video_cols;		/* 0x07 */
+	u16 unused2;			/* 0x08 */
+	u16 orig_video_ega_bx;		/* 0x0a */
+	u16 unused3;			/* 0x0c */
+	u8  orig_video_lines;		/* 0x0e */
+	u8  orig_video_isVGA;		/* 0x0f */
+	u16 orig_video_points;		/* 0x10 */
+
+	/* VESA graphic mode -- linear frame buffer */
+	u16 lfb_width;			/* 0x12 */
+	u16 lfb_height;			/* 0x14 */
+	u16 lfb_depth;			/* 0x16 */
+	u32 lfb_base;			/* 0x18 */
+	u32 lfb_size;			/* 0x1c */
+	u16 cl_magic;			/* 0x20 */
+#define CL_MAGIC_VALUE 0xA33F
+	u16 cl_offset;			/* 0x22 */
+	u16 lfb_linelength;		/* 0x24 */
+	u8  red_size;			/* 0x26 */
+	u8  red_pos;			/* 0x27 */
+	u8  green_size;			/* 0x28 */
+	u8  green_pos;			/* 0x29 */
+	u8  blue_size;			/* 0x2a */
+	u8  blue_pos;			/* 0x2b */
+	u8  rsvd_size;			/* 0x2c */
+	u8  rsvd_pos;			/* 0x2d */
+	u16 vesapm_seg;			/* 0x2e */
+	u16 vesapm_off;			/* 0x30 */
+	u16 pages;			/* 0x32 */
+	u16 vesa_attributes;		/* 0x34 */
+	u32 capabilities;		/* 0x36 */
+	u8  reserved[6];		/* 0x3a -- 0x3f reserved for future expansion */
+} __attribute__((packed));
+
+struct apm_bios_info {
+	u8  reserved[0x14];
+} __attribute__((packed));
+
+struct ist_info {
+	u8  reserved[0x10];
+} __attribute__((packed));
+
+struct sys_desc_table {
+	u16 length;
+	u8  reserved[14];
+} __attribute__((packed));
+
+struct edid_info {
+	u8  reserved[0x1c0 - 0x140];
+} __attribute__((packed));
+
+struct efi_info {
+	u32 efi_loader_signature;
+	u32 efi_systab;
+	u32 efi_memdesc_size;
+	u32 efi_memdesc_version;
+	u32 efi_memmap;
+	u32 efi_memmap_size;
+	u32 efi_systab_hi;
+	u32 efi_memmap_hi;
+} __attribute__((packed));
+
+struct edd_device_params {
+	u8 reserved[74];
+} __attribute__((packed));
+
+#define EDDMAXNR 6
+struct edd_info {
+	u8  device;
+	u8  version;
+	u16 interface_support;
+	u16 legacy_max_cylinder;
+	u8  legacy_max_head;
+	u8  legacy_sectors_per_track;
+	struct edd_device_params params;
+} __attribute__((packed));
+
+struct setup_header {
+	/* Documentation/x86/boot.txt starts here */
+	u8  setup_sects;		/* 0x1f1 */
+	u16 root_flags;			/* 0x1f2 */
+	u32 syssize;			/* 0x1f4 */
+	u16 ram_size;			/* 0x1f8 */
+#define RAMDISK_IMAGE_START_MASK  	0x07FF
+#define RAMDISK_PROMPT_FLAG		0x8000
+#define RAMDISK_LOAD_FLAG		0x4000
+	u16 vid_mode;			/* 0x1fa */
+	u16 root_dev;			/* 0x1fc */
+	u16 boot_flag;			/* 0x1fe */
+	u16 jump;			/* 0x200 */
+	u8  header[4];			/* 0x202 */
+	u16 version;			/* 0x206 */
+	u32 realmode_swtch;		/* 0x208 */
+	u16 start_sys_seg;		/* 0x20c */
+	u16 kernel_version;		/* 0x20e */
+	u8  loader_type;		/* 0x210 */
+#define LOADER_TYPE_LOADLIN         	0x1
+#define LOADER_TYPE_BOOTSECT_LOADER 	0x2
+#define LOADER_TYPE_SYSLINUX        	0x3
+#define LOADER_TYPE_ETHERBOOT       	0x4
+#define LOADER_TYPE_KERNEL          	0x5
+	u8  loadflags;			/* 0x211 */
+#define LOADED_HIGH			(1 << 0)
+#define QUIET_FLAG			(1 << 5)
+#define KEEP_SEGMENTS			(1 << 6)
+#define CAN_USE_HEAP			(1 << 7)
+	u16 setup_move_size;		/* 0x212 */
+	u32 code32_start;		/* 0x214 */
+	u32 ramdisk_start;		/* 0x218 */
+	u32 ramdisk_size;		/* 0x21c */
+	u32 bootsect_kludge;		/* 0x220 */
+	/* 2.01+ */
+	u16 heap_end_ptr;		/* 0x224 */
+	/* 2.02+ */
+	u8  ext_loader_ver;		/* 0x226 */
+	u8  ext_loader_type;		/* 0x227 */
+	u32 cmd_line_ptr;		/* 0x228 */
+	/* 2.03+ */
+	u32 ramdisk_max;		/* 0x22c */
+	/* 2.05+ */
+	u32 kernel_alignment;		/* 0x230 */
+	u8  relocatable_kernel;		/* 0x234 */
+	/* 2.10+ */
+	u8 min_alignment;		/* 0x235 */
+	u8 reserved[2];			/* 0x236 */
+	/* 2.06+ */
+	u32 cmdlinux_size;		/* 0x238 */
+	/* 2.07+ */
+	u32 hardware_subarch;		/* 0x23c */
+	u64  hardware_subarch_data;	/* 0x240 */
+	/* 2.08+ */
+	u32 payload_offset;		/* 0x248 */
+	u32 payload_length;		/* 0x24c */
+	/* 2.09+ */
+	u64 setup_data;			/* 0x250 */
+	/* 2.10+ */
+	u64 pref_address;		/* 0x258 */
+	u32 init_size;			/* 0x260 */
+} __attribute__((packed));
+
+/* Paramters passed to 32-bit part of Linux */
+struct linux_params {
+	struct screen_info screen_info;		/* 0x000 */
+	struct apm_bios_info apm_bios_info;	/* 0x040 */
+	u8  reserved1[0x60 - 0x54];
+	struct ist_info ist_info;		/* 0x060 */
+	u8  reserved2[0x80 - 0x70];
+	u8  hd0_info[0x10];			/* 0x080 */
+	u8  hd1_info[0x10];			/* 0x090 */
+	struct sys_desc_table sys_desc_table;	/* 0x0a0 */
+	u8  reserved3[0x140 - 0xb0];
+	struct edid_info edid_info;		/* 0x140 */
+	struct efi_info efi_info;		/* 0x1c0 */
+	u32 alt_mem_k;				/* 0x1e0 */
+	u32 scratch;				/* 0x1e4 */
+	u8  e820_entries;			/* 0x1e8 */
+	u8  eddbuf_entries;			/* 0x1e9 */
+	u8  edd_mbr_sig_buf_entries;		/* 0x1ea */
+	u8  reserved4[0x1f1-0x1eb];
+	struct setup_header hdr;		/* 0x1f1 */
+	u8  reserved5[0x290-0x1f1-sizeof(struct setup_header)];
+	u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];/* 0x290 */
+	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
+	u8  reserved7[0xd00 - 0xcd0];
+	struct edd_info eddbuf[EDDMAXNR];	/* 0xd00 */
+	u8  reserved8[0x1000 - 0xeec];
+} __attribute__((packed));
+
