aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2014-06-17 23:41:08 -0700
committerMatt Fleming <matt.fleming@intel.com>2014-06-18 15:36:41 +0100
commit2833223afc69b4d171ed7a19c622b6457cf4fb66 (patch)
tree48df2a73d9f87680d70fafc71d623d9439295855
parent668ace1207f208260711a37a5b7877101eb0cd0b (diff)
downloadefilinux-2833223afc69b4d171ed7a19c622b6457cf4fb66.tar.gz
efilinux: Allocate boot_params before parsing initrd
We need to allocate boot_params early and clear it before copy setup_header to it. So kernel will not call sanitize_boot_params() to overwrite new added parameter like ext_ramdisk_image, ext_ramdisk_size... We should modify boot_params later instead of touch temp buf too early. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--loaders/bzimage/bzimage.c65
1 files changed, 34 insertions, 31 deletions
diff --git a/loaders/bzimage/bzimage.c b/loaders/bzimage/bzimage.c
index 6c992b3..49939b8 100644
--- a/loaders/bzimage/bzimage.c
+++ b/loaders/bzimage/bzimage.c
@@ -50,21 +50,22 @@ struct initrd {
struct file *file;
};
-static void parse_initrd(EFI_LOADED_IMAGE *image, struct boot_params *buf, char *cmdline)
+static void parse_initrd(EFI_LOADED_IMAGE *image,
+ struct boot_params *boot_params, char *cmdline)
{
EFI_PHYSICAL_ADDRESS addr;
struct initrd *initrds;
int nr_initrds;
EFI_STATUS err;
- UINT64 size;
+ UINT64 size = 0;
char *initrd;
int i, j;
/*
* Has there been an initrd specified on the cmdline?
*/
- buf->hdr.ramdisk_start = 0;
- buf->hdr.ramdisk_len = 0;
+ boot_params->hdr.ramdisk_start = 0;
+ boot_params->hdr.ramdisk_len = 0;
initrd = cmdline;
for (nr_initrds = 0; *initrd; nr_initrds++) {
@@ -96,6 +97,7 @@ static void parse_initrd(EFI_LOADED_IMAGE *image, struct boot_params *buf, char
struct initrd *rd = &initrds[i];
struct file *rdfile;
char *o, *p;
+ UINT64 sz;
initrd = strstr(initrd, "initrd=");
if (!initrd)
@@ -116,26 +118,26 @@ static void parse_initrd(EFI_LOADED_IMAGE *image, struct boot_params *buf, char
if (err != EFI_SUCCESS)
goto close_handles;
- file_size(rdfile, &size);
+ file_size(rdfile, &sz);
- rd->size = size;
+ rd->size = sz;
rd->file = rdfile;
- buf->hdr.ramdisk_len += size;
+ size += sz;
}
- size = buf->hdr.ramdisk_len;
err = emalloc(size, 0x1000, &addr);
if (err != EFI_SUCCESS)
goto close_handles;
- if ((UINTN)addr > buf->hdr.ramdisk_max) {
+ if ((UINTN)addr > boot_params->hdr.ramdisk_max) {
Print(L"ramdisk address is too high!\n");
efree(addr, size);
goto close_handles;
}
- buf->hdr.ramdisk_start = (UINT32)(UINTN)addr;
+ boot_params->hdr.ramdisk_start = (UINT32)(UINTN)addr;
+ boot_params->hdr.ramdisk_len = (UINT32)size;
for (j = 0; j < nr_initrds; j++) {
struct initrd *rd = &initrds[j];
@@ -268,9 +270,6 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
init_size = size * 3;
}
- /* 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,
@@ -287,11 +286,26 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
cmdline = (char *)(UINTN)addr;
memcpy(cmdline, _cmdline, strlen(_cmdline) + 1);
- parse_initrd(info, buf, cmdline);
+ addr = 0x3fffffff;
+ err = allocate_pages(AllocateMaxAddress, EfiLoaderData,
+ EFI_SIZE_TO_PAGES(16384), &addr);
+ if (err != EFI_SUCCESS)
+ goto out;
+
+ boot_params = (struct boot_params *)(UINTN)addr;
- buf->hdr.cmd_line_ptr = (UINT32)(UINTN)cmdline;
+ memset((void *)boot_params, 0x0, 16384);
+
+ /* Copy setup_header to boot_params */
+ memcpy((char *)&boot_params->hdr, (char *)&buf->hdr,
+ sizeof(struct setup_header));
- memset((char *)&buf->screen_info, 0x0, sizeof(buf->screen_info));
+ /* Don't need an allocated ID, we're a prototype */
+ boot_params->hdr.loader_id = 0x1;
+
+ boot_params->hdr.cmd_line_ptr = (UINT32)(UINTN)cmdline;
+
+ parse_initrd(info, boot_params, cmdline);
addr = pref_address;
err = allocate_pages(AllocateAddress, EfiLoaderData,
@@ -301,7 +315,8 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
* We failed to allocate the preferred address, so
* just allocate some memory and hope for the best.
*/
- err = emalloc(init_size, buf->hdr.kernel_alignment, &addr);
+ err = emalloc(init_size, boot_params->hdr.kernel_alignment,
+ &addr);
if (err != EFI_SUCCESS)
goto out;
}
@@ -315,26 +330,14 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
if (err != EFI_SUCCESS)
goto out;
- addr = 0x3fffffff;
- err = allocate_pages(AllocateMaxAddress, EfiLoaderData,
- EFI_SIZE_TO_PAGES(16384), &addr);
- if (err != EFI_SUCCESS)
- goto out;
-
- boot_params = (struct boot_params *)(UINTN)addr;
-
- memset((void *)boot_params, 0x0, 16384);
-
- /* Copy first two sectors to boot_params */
- memcpy((char *)boot_params, (char *)buf, 2 * 512);
boot_params->hdr.code32_start = (UINT32)((UINT64)kernel_start);
/*
* Use the kernel's EFI boot stub by invoking the handover
* protocol.
*/
- if (buf->hdr.version >= 0x20b) {
- handover_jump(buf->hdr.version, image,
+ if (boot_params->hdr.version >= 0x20b) {
+ handover_jump(boot_params->hdr.version, image,
boot_params, kernel_start);
goto out;
}