Re: Loading initrd above 4G causes freeze on boot

From: Yinghai Lu
Date: Mon Aug 25 2014 - 14:22:42 EST


On Mon, Aug 25, 2014 at 5:53 AM, Matt Fleming <matt@xxxxxxxxxxxxxxxxx> wrote:
> On Mon, 25 Aug, at 02:08:59PM, Mantas MikulÄnas wrote:

>> [ 0.000000] RAMDISK: [mem 0xbe22e000-0xbe799fff]

that is pushed down under 4G.

>
> OK, we're out of options here. Yinghai, we're going to have to revert
> your patch, 4bf7111f5016 ("x86/efi: Support initrd loaded above 4G")
>
> We could conceivably add a boot parameter option to attempt loading
> inirds above 4G, but we can't turn the feature on by default because of
> all these buggy EFI implementations - things must work out of the box.
>
> But the boot parameter would be useful for those people that a) know
> their firmware isn't buggy and b) need to leave < 4G memory available
> for use by other things. Yinghai, can you provide some justification for
> your original commit? Do you have concrete use cases where loading
> initrds above 4G is critical? How important is it that we enable this
> functionality as opposed to reverting it?

The use case: install RHEL full will take more than 8G in the root disk.
then make initramfs image to include every file in the disk, then boot
kernel and initramfs as diskless boot.

To use this huge initramfs image, first one is kexec, second way is using
UEFI 64bit.

So the point is the initramfs is bigger than 4G.

Please check if you can apply attached one. That will keep under 2G at first,
then try any high address.

Thanks

Yinghai
---
arch/x86/boot/compressed/eboot.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

Index: linux-2.6/arch/x86/boot/compressed/eboot.c
===================================================================
--- linux-2.6.orig/arch/x86/boot/compressed/eboot.c
+++ linux-2.6/arch/x86/boot/compressed/eboot.c
@@ -1032,7 +1032,6 @@ struct boot_params *make_boot_params(str
int i;
unsigned long ramdisk_addr;
unsigned long ramdisk_size;
- unsigned long initrd_addr_max;

efi_early = c;
sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
@@ -1095,15 +1094,18 @@ struct boot_params *make_boot_params(str

memset(sdt, 0, sizeof(*sdt));

- if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G)
- initrd_addr_max = -1UL;
- else
- initrd_addr_max = hdr->initrd_addr_max;
-
status = handle_cmdline_files(sys_table, image,
(char *)(unsigned long)hdr->cmd_line_ptr,
- "initrd=", initrd_addr_max,
+ "initrd=", hdr->initrd_addr_max,
+ &ramdisk_addr, &ramdisk_size);
+
+ if (status != EFI_SUCCESS &&
+ hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G)
+ status = handle_cmdline_files(sys_table, image,
+ (char *)(unsigned long)hdr->cmd_line_ptr,
+ "initrd=", -1UL,
&ramdisk_addr, &ramdisk_size);
+
if (status != EFI_SUCCESS)
goto fail2;
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;