[PATCH 1/2] efilinux: Allocate boot_params before parsing initrd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>

---
 loaders/bzimage/bzimage.c |   65 ++++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 31 deletions(-)

Index: efilinux/loaders/bzimage/bzimage.c
===================================================================
--- efilinux.orig/loaders/bzimage/bzimage.c
+++ efilinux/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_IMAG
 		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_IMAG
 		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 *na
 		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 *na
 	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 *na
 		 * 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 *na
 	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;
 	}
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux