Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

From: Yinghai Lu
Date: Thu Feb 05 2015 - 00:25:35 EST


On Wed, Feb 4, 2015 at 7:25 PM, Dave Young <dyoung@xxxxxxxxxx> wrote:
>> After this patch, could use patched grub2-x86_64.efi to place
>> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
>> above 4G.
>
> Can you share the grub2 patch for testing?

Please check attached 5 patches. last one is for debug purpose.

You need to apply them on top of

git://git.savannah.gnu.org/grub.git

plus http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch
Subject: [PATCH] update setup_header and boot_params to 2.12

the one that is used by kernel v3.8...


---
include/grub/i386/linux.h | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

Index: grub/include/grub/i386/linux.h
===================================================================
--- grub.orig/include/grub/i386/linux.h
+++ grub/include/grub/i386/linux.h
@@ -130,7 +130,7 @@ struct linux_kernel_header
grub_uint32_t kernel_alignment;
grub_uint8_t relocatable;
grub_uint8_t min_alignment;
- grub_uint8_t pad[2];
+ grub_uint16_t xloadflags;
grub_uint32_t cmdline_size;
grub_uint32_t hardware_subarch;
grub_uint64_t hardware_subarch_data;
@@ -221,7 +221,11 @@ struct linux_kernel_params
grub_uint32_t ofw_cif_handler; /* b8 */
grub_uint32_t ofw_idt; /* bc */

- grub_uint8_t padding7[0x1b8 - 0xc0];
+ 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 padding7[0x1b8 - 0xcc];

union
{
@@ -300,14 +304,18 @@ struct linux_kernel_params
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 pad1[3];
+ 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_uint8_t pad2[120]; /* 258 */
+ grub_uint64_t pref_address;
+ grub_uint32_t init_size;
+ grub_uint32_t handover_offset;
+ grub_uint8_t pad2[104]; /* 248 */
struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */

} GRUB_PACKED;
Subject: [PATCH] x86, efi: add allocate_pages_high

The allocate_pages_max one does not return above 4G.

translate the version in linux kernel.

---
grub-core/kern/efi/mm.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++
include/grub/efi/efi.h | 3 +
2 files changed, 147 insertions(+)

Index: grub/grub-core/kern/efi/mm.c
===================================================================
--- grub.orig/grub-core/kern/efi/mm.c
+++ grub/grub-core/kern/efi/mm.c
@@ -557,3 +557,147 @@ grub_efi_mm_init (void)
grub_efi_free_pages ((grub_addr_t) memory_map,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
}
+
+#define EFI_PAGE_SIZE 0x1000
+static grub_efi_status_t grub2_efi_get_memory_map(grub_efi_uintn_t *map_size,
+ grub_efi_memory_descriptor_t **map,
+ grub_efi_uintn_t *key_ptr,
+ grub_efi_uintn_t *desc_size,
+ grub_efi_uint32_t *desc_ver)
+{
+ grub_efi_memory_descriptor_t *m = NULL;
+ grub_efi_status_t status;
+ grub_efi_uintn_t key;
+ grub_efi_uint32_t desc_version;
+ grub_efi_boot_services_t *b;
+
+ b = grub_efi_system_table->boot_services;
+
+ *map_size = 0;
+ *desc_size = 0;
+ key = 0;
+ status = efi_call_5 (b->get_memory_map, map_size, NULL, &key,
+ desc_size, &desc_version);
+
+ if (status != GRUB_EFI_BUFFER_TOO_SMALL)
+ return GRUB_EFI_LOAD_ERROR;
+
+ /*
+ * Add an additional efi_memory_desc_t because we're doing an
+ * allocation which may be in a new descriptor region.
+ */
+ *map_size += *desc_size;
+ status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
+ *map_size, (void **)&m);
+ if (status != GRUB_EFI_SUCCESS)
+ goto fail;
+
+ status = efi_call_5 (b->get_memory_map, map_size, m, &key,
+ desc_size, &desc_version);
+ if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+ {
+ efi_call_1 (b->free_pool, m);
+ return GRUB_EFI_LOAD_ERROR;
+ }
+
+ if (status != GRUB_EFI_SUCCESS)
+ efi_call_1 (b->free_pool, m);
+
+ if (key_ptr && status == GRUB_EFI_SUCCESS)
+ *key_ptr = key;
+ if (desc_ver && status == GRUB_EFI_SUCCESS)
+ *desc_ver = desc_version;
+
+fail:
+ *map = m;
+ return status;
+}
+
+/*
+ * Allocate at the highest possible address that is not above 'max'.
+ */
+void *grub2_efi_allocate_pages_high(grub_efi_physical_address_t max,
+ grub_efi_uint64_t pages, grub_efi_uint64_t align)
+{
+ grub_efi_boot_services_t *b;
+ grub_efi_uintn_t map_size, desc_size;
+ grub_efi_memory_descriptor_t *map= NULL;
+ grub_efi_status_t status;
+ grub_uint64_t max_addr = 0;
+ grub_uint64_t addr = 0;
+ grub_efi_uintn_t i;
+ grub_uint64_t size = PAGES_TO_BYTES(pages);
+
+ /* Obtain descriptors for available memory. */
+ status = grub2_efi_get_memory_map (&map_size, &map, 0, &desc_size, 0);
+ if (status != GRUB_EFI_SUCCESS)
+ goto fail;
+
+ if (align < EFI_PAGE_SIZE)
+ align = EFI_PAGE_SIZE;
+
+ b = grub_efi_system_table->boot_services;
+
+again:
+ for (i = 0; i < map_size / desc_size; i++)
+ {
+ grub_efi_memory_descriptor_t *desc;
+ unsigned long m = (unsigned long)map;
+ grub_uint64_t start, end;
+
+ desc = (grub_efi_memory_descriptor_t *)(m + (i * desc_size));
+ if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
+ continue;
+
+ if (desc->num_pages < pages)
+ continue;
+
+ start = desc->physical_start;
+ end = start + PAGES_TO_BYTES(desc->num_pages);
+
+ if ((start + size) > end || (start + size) > max)
+ continue;
+
+ if (end - size > max)
+ end = max;
+
+ if ((((end - size)/align)*align) < start)
+ continue;
+
+ start = (((end - size)/align)*align);
+
+ /*
+ * Don't allocate at 0x0. It will confuse code that
+ * checks pointers against NULL.
+ */
+ if (start == 0x0)
+ continue;
+
+ if (start > max_addr)
+ max_addr = start;
+ }
+
+ if (!max_addr)
+ addr = 0;
+ else
+ {
+ status = efi_call_4 (b->allocate_pages,
+ GRUB_EFI_ALLOCATE_ADDRESS, GRUB_EFI_LOADER_DATA,
+ pages, &max_addr);
+ if (status != GRUB_EFI_SUCCESS)
+ {
+ max = max_addr;
+ max_addr = 0;
+ goto again;
+ }
+
+ addr = max_addr;
+ }
+
+ /* Release the memory maps. */
+ efi_call_1 (b->free_pool, map);
+
+fail:
+ return (void *)((grub_addr_t) addr);
+}
+
Index: grub/include/grub/efi/efi.h
===================================================================
--- grub.orig/include/grub/efi/efi.h
+++ grub/include/grub/efi/efi.h
@@ -43,6 +43,9 @@ EXPORT_FUNC(grub_efi_allocate_pages) (gr
void *
EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max,
grub_efi_uintn_t pages);
+void *
+EXPORT_FUNC(grub2_efi_allocate_pages_high) (grub_efi_physical_address_t max,
+ grub_efi_uint64_t pages, grub_efi_uint64_t align);
void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
int
Subject: [PATCH] x86, efi: make initrd load high if it is supported

for kernel after v3.9 and later.

---
grub-core/loader/i386/efi/linux.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)

Index: grub/grub-core/loader/i386/efi/linux.c
===================================================================
--- grub.orig/grub-core/loader/i386/efi/linux.c
+++ grub/grub-core/loader/i386/efi/linux.c
@@ -108,6 +108,8 @@ static grub_err_t
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
+ grub_uint64_t addr_max = 0x3fffffff;
+ int load_high = 0;
grub_file_t *files = 0;
int i, nfiles = 0;
grub_size_t size = 0;
@@ -139,7 +141,14 @@ grub_cmd_initrd (grub_command_t cmd __at
size += ALIGN_UP (grub_file_size (files[i]), 4);
}

- initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
+ if (params->version > grub_cpu_to_le16 (0x020b) &&
+ params->xloadflags & (1<<1)) /* XLF_CAN_BE_LOADED_ABOVE_4G */
+ {
+ addr_max = -1UL;
+ load_high = 1;
+ }
+
+ initrd_mem = grub2_efi_allocate_pages_high (addr_max, BYTES_TO_PAGES(size), 4096);

if (!initrd_mem)
{
@@ -147,8 +156,13 @@ grub_cmd_initrd (grub_command_t cmd __at
goto fail;
}

- params->ramdisk_size = size;
+ params->ramdisk_size = (grub_uint32_t) size;
params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem;
+ if ( load_high )
+ {
+ params->ext_ramdisk_image = (grub_uint64_t) initrd_mem >> 32;
+ params->ext_ramdisk_size = size >> 32;
+ }

ptr = initrd_mem;

@@ -167,8 +181,6 @@ grub_cmd_initrd (grub_command_t cmd __at
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
}

- params->ramdisk_size = size;
-
fail:
for (i = 0; i < nfiles; i++)
grub_file_close (files[i]);
Subject: [PATCH] x86, efi: make kernel/boot_params/cmdline could be above 4G if supported

for kernel that support ext_code32_start.

Also reduce kernel reading to one time only.

---
grub-core/loader/i386/efi/linux.c | 146 +++++++++++++++++++++++---------------
include/grub/i386/linux.h | 4 -
2 files changed, 93 insertions(+), 57 deletions(-)

Index: grub/grub-core/loader/i386/efi/linux.c
===================================================================
--- grub.orig/grub-core/loader/i386/efi/linux.c
+++ grub/grub-core/loader/i386/efi/linux.c
@@ -192,14 +192,27 @@ grub_cmd_initrd (grub_command_t cmd __at
return grub_errno;
}

+static void copy_setup_header(unsigned char *param, unsigned char *h)
+{
+ unsigned long setup_header_size = h[0x201] + 0x202 - 0x1f1;
+
+ /* only copy setup_header */
+ if (setup_header_size > 0x7f)
+ setup_header_size = 0x7f;
+ memcpy(param + 0x1f1, h + 0x1f1, setup_header_size);
+}
+
static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
+ grub_uint64_t addr_max = 0x3fffffff;
+ int load_high = 0;
grub_file_t file = 0;
struct linux_kernel_header lh;
- grub_ssize_t len, start, filelen;
- void *kernel;
+ grub_ssize_t start, filelen;
+ void *kernel = NULL;
+ int kernel_high = 0;

grub_dl_ref (my_mod);

@@ -213,77 +226,96 @@ grub_cmd_linux (grub_command_t cmd __att
if (! file)
goto fail;

- filelen = grub_file_size (file);
+ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ argv[0]);
+ goto fail;
+ }

- kernel = grub_malloc(filelen);
+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
+ goto fail;
+ }

- if (!kernel)
+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
{
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
goto fail;
}

- if (grub_file_read (file, kernel, filelen) != filelen)
+ if (lh.version < grub_cpu_to_le16 (0x020b))
{
- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
goto fail;
}

- if (! grub_linuxefi_secure_validate (kernel, filelen))
+ if (!lh.handover_offset)
{
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
- grub_free (kernel);
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
goto fail;
}

- grub_file_seek (file, 0);
+ if (lh.version > grub_cpu_to_le16 (0x020d) &&
+ lh.xloadflags & (1<<1)) /* XLF_CAN_BE_LOADED_ABOVE_4G */
+ {
+ addr_max = -1UL;
+ load_high = 1;
+ }

- grub_free(kernel);
+ filelen = grub_file_size (file);

- params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
+ kernel = grub_malloc(filelen);

- if (! params)
+ if (!kernel && !load_high)
{
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
goto fail;
}

- memset (params, 0, 16384);
-
- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+ if (!kernel)
{
- if (!grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
- goto fail;
+ kernel = grub2_efi_allocate_pages_high (addr_max, BYTES_TO_PAGES(filelen), 4096);
+ kernel_high = 1;
}

- if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+ if (!kernel)
{
- grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
goto fail;
}

- if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+ grub_file_seek (file, 0);
+ if (grub_file_read (file, kernel, filelen) != filelen)
{
- grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
goto fail;
}
+ grub_file_close(file);
+ file = 0;

- if (lh.version < grub_cpu_to_le16 (0x020b))
+ if (! grub_linuxefi_secure_validate (kernel, filelen))
{
- grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
goto fail;
}

- if (!lh.handover_offset)
+ params = grub2_efi_allocate_pages_high (addr_max, BYTES_TO_PAGES(16384), 4096);
+
+ if (! params)
{
- grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
goto fail;
}

- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
- BYTES_TO_PAGES(lh.cmdline_size + 1));
+ memset (params, 0, 16384);
+ copy_setup_header((unsigned char *) params, (unsigned char *) &lh);
+ params->type_of_loader = 0x21;
+
+ linux_cmdline = grub2_efi_allocate_pages_high (addr_max,
+ BYTES_TO_PAGES(lh.cmdline_size + 1), 4096);

if (!linux_cmdline)
{
@@ -296,19 +328,20 @@ grub_cmd_linux (grub_command_t cmd __att
linux_cmdline + sizeof (LINUX_IMAGE) - 1,
lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1));

- lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline;
+ params->cmd_line_ptr = (grub_uint32_t)(grub_uint64_t) linux_cmdline;
+ if ( load_high )
+ params->ext_cmd_line_ptr = (grub_uint64_t) linux_cmdline >> 32;

handover_offset = lh.handover_offset;

- start = (lh.setup_sects + 1) * 512;
- len = grub_file_size(file) - start;
-
- kernel_mem = grub_efi_allocate_pages(lh.pref_address,
+ kernel_mem = NULL;
+ if ( !load_high )
+ kernel_mem = grub_efi_allocate_pages(lh.pref_address,
BYTES_TO_PAGES(lh.init_size));

if (!kernel_mem)
- kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
- BYTES_TO_PAGES(lh.init_size));
+ kernel_mem = grub2_efi_allocate_pages_high (addr_max,
+ BYTES_TO_PAGES(lh.init_size), lh.kernel_alignment);

if (!kernel_mem)
{
@@ -316,31 +349,32 @@ grub_cmd_linux (grub_command_t cmd __att
goto fail;
}

- if (grub_file_seek (file, start) == (grub_off_t) -1)
- {
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
- goto fail;
- }
+ kernel_size = lh.init_size;

- if (grub_file_read (file, kernel_mem, len) != len && !grub_errno)
- {
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
- argv[0]);
- }
+ start = (lh.setup_sects + 1) * 512;
+ memcpy(kernel_mem, (unsigned char *)kernel + start, filelen - start);

if (grub_errno == GRUB_ERR_NONE)
{
grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
loaded = 1;
- lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
+ params->code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
+ if ( load_high )
+ {
+ params->ext_code32_start = (grub_uint64_t) kernel_mem >> 32;
+ /* don't not relocate down in kernel eboot.c::efi_main() */
+ params->pref_address = (grub_uint64_t) kernel_mem;
+ }
}

- memcpy(params, &lh, 2 * 512);
-
- params->type_of_loader = 0x21;
-
fail:
+ if (kernel)
+ {
+ if (!kernel_high)
+ grub_free(kernel);
+ else
+ grub_efi_free_pages((grub_efi_physical_address_t)kernel, BYTES_TO_PAGES(filelen));
+ }

if (file)
grub_file_close (file);
Index: grub/include/grub/i386/linux.h
===================================================================
--- grub.orig/include/grub/i386/linux.h
+++ grub/include/grub/i386/linux.h
@@ -140,6 +140,7 @@ struct linux_kernel_header
grub_uint64_t pref_address;
grub_uint32_t init_size;
grub_uint32_t handover_offset;
+ grub_uint32_t ext_code32_start;
} GRUB_PACKED;

/* Boot parameters for Linux based on 2.6.12. This is used by the setup
@@ -315,7 +316,8 @@ struct linux_kernel_params
grub_uint64_t pref_address;
grub_uint32_t init_size;
grub_uint32_t handover_offset;
- grub_uint8_t pad2[104]; /* 248 */
+ grub_uint32_t ext_code32_start;
+ grub_uint8_t pad2[100]; /* 24c */
struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */

} GRUB_PACKED;
Subject: [PATCH] x86, efi: enable debug print out

for debug purpose

---
grub-core/loader/i386/efi/linux.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)

Index: grub/grub-core/loader/i386/efi/linux.c
===================================================================
--- grub.orig/grub-core/loader/i386/efi/linux.c
+++ grub/grub-core/loader/i386/efi/linux.c
@@ -29,6 +29,8 @@

GRUB_MOD_LICENSE ("GPLv3+");

+#define DEBUG_PRINT 1
+
static grub_dl_t my_mod;
static int loaded;
static void *kernel_mem;
@@ -166,6 +168,12 @@ grub_cmd_initrd (grub_command_t cmd __at

ptr = initrd_mem;

+#ifdef DEBUG_PRINT
+ /* before initrd read */
+ grub_printf("initrd: [%lx,%lx]\n",
+ (unsigned long)initrd_mem, (unsigned long)initrd_mem + size - 1);
+#endif
+
for (i = 0; i < nfiles; i++)
{
grub_ssize_t cursize = grub_file_size (files[i]);
@@ -181,6 +189,11 @@ grub_cmd_initrd (grub_command_t cmd __at
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
}

+#ifdef DEBUG_PRINT
+ /* after initrd read */
+ grub_printf("initrd: read %d file%sdone\n", nfiles, nfiles==1 ? " ": "s ");
+#endif
+
fail:
for (i = 0; i < nfiles; i++)
grub_file_close (files[i]);
@@ -296,6 +309,11 @@ grub_cmd_linux (grub_command_t cmd __att
grub_file_close(file);
file = 0;

+#ifdef DEBUG_PRINT
+ /* after kernel read */
+ grub_printf("kernel: read done\n");
+#endif
+
if (! grub_linuxefi_secure_validate (kernel, filelen))
{
grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
@@ -314,6 +332,12 @@ grub_cmd_linux (grub_command_t cmd __att
copy_setup_header((unsigned char *) params, (unsigned char *) &lh);
params->type_of_loader = 0x21;

+#ifdef DEBUG_PRINT
+ /* after params */
+ grub_printf("params: [%lx,%lx]\n",
+ (unsigned long)params, (unsigned long)params + 16384 - 1);
+#endif
+
linux_cmdline = grub2_efi_allocate_pages_high (addr_max,
BYTES_TO_PAGES(lh.cmdline_size + 1), 4096);

@@ -332,6 +356,12 @@ grub_cmd_linux (grub_command_t cmd __att
if ( load_high )
params->ext_cmd_line_ptr = (grub_uint64_t) linux_cmdline >> 32;

+#ifdef DEBUG_PRINT
+ /* after cmdline */
+ grub_printf("cmdline: [%lx,%lx]\n", (unsigned long)linux_cmdline,
+ (unsigned long)linux_cmdline + lh.cmdline_size - 1);
+#endif
+
handover_offset = lh.handover_offset;

kernel_mem = NULL;
@@ -351,6 +381,12 @@ grub_cmd_linux (grub_command_t cmd __att

kernel_size = lh.init_size;

+#ifdef DEBUG_PRINT
+ /* after kernel alloc */
+ grub_printf("kernel: [%lx,%lx]\n", (unsigned long)kernel_mem,
+ (unsigned long)kernel_mem + lh.init_size - 1);
+#endif
+
start = (lh.setup_sects + 1) * 512;
memcpy(kernel_mem, (unsigned char *)kernel + start, filelen - start);