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