aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-07-13 13:30:43 +0100
committerMatt Fleming <matt.fleming@intel.com>2012-07-20 10:10:56 +0100
commit8947b2fb371be0838ce83fbb9e55c5e87fe72e85 (patch)
tree98bc6638a6d467394554f73ab29ed1407c01ef16
parentf72063eda407c8a617fbb5031879db5c04be783f (diff)
downloadefilinux-8947b2fb371be0838ce83fbb9e55c5e87fe72e85.tar.gz
bzimage: Limit the maximum allocation address
There are restrictions on the addresses that we pass as arguments to the kernel, mainly due to the way that the early page tables work. If we allocate addresses above the first 1GB of memory the kernel will fail to run. Cap key data structures at 0x3fffffff so that the kernel can access them with its early page tables. These limitations were discovered when running efilinux under Qemu with multiple gigabytes of RAM. Reported-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--loaders/bzimage/bzimage.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/loaders/bzimage/bzimage.c b/loaders/bzimage/bzimage.c
index 7f0c631..8789876 100644
--- a/loaders/bzimage/bzimage.c
+++ b/loaders/bzimage/bzimage.c
@@ -167,7 +167,7 @@ close_handles:
* load_kernel - Load a kernel image into memory from the boot device
*/
EFI_STATUS
-load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
+load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
{
UINTN map_size, _map_size, map_key;
EFI_PHYSICAL_ADDRESS kernel_start, addr;
@@ -183,6 +183,7 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
struct file *file;
UINTN desc_size;
EFI_STATUS err;
+ char *cmdline;
UINT64 size;
int i, j = 0;
@@ -262,6 +263,22 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
/* Don't need an allocated ID, we're a prototype */
buf->hdr.loader_id = 0x1;
+ /*
+ * The kernel expects cmdline to be allocated pretty low,
+ * Documentation/x86/boot.txt says,
+ *
+ * "The kernel command line can be located anywhere
+ * between the end of the setup heap and 0xA0000"
+ */
+ addr = 0xA0000;
+ err = allocate_pages(AllocateMaxAddress, EfiLoaderData,
+ EFI_SIZE_TO_PAGES(strlen(_cmdline) + 1),
+ &addr);
+ if (err != EFI_SUCCESS)
+ goto out;
+ cmdline = (char *)(UINTN)addr;
+ memcpy(cmdline, _cmdline, strlen(_cmdline) + 1);
+
parse_initrd(buf, cmdline);
buf->hdr.cmd_line_ptr = (UINT32)(UINTN)cmdline;
@@ -290,7 +307,9 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
if (err != EFI_SUCCESS)
goto out;
- err = emalloc(16384, 1, &addr);
+ addr = 0x3fffffff;
+ err = allocate_pages(AllocateMaxAddress, EfiLoaderData,
+ EFI_SIZE_TO_PAGES(16384), &addr);
if (err != EFI_SUCCESS)
goto out;