Messages in this thread Patch in this message | | | Date | Thu, 24 Nov 2011 17:58:12 +0100 | From | Maarten Lankhorst <> | Subject | Re: [PATCH v5 10/10] x86, efi: EFI boot stub support |
| |
Hey Matt,
On 11/24/2011 03:43 PM, Maarten Lankhorst wrote: > Hey Matt, > > On 11/23/2011 08:27 PM, Matt Fleming wrote: > >> On Wed, 2011-11-23 at 01:44 +0100, Maarten Lankhorst wrote: >>> When I tested this with v3.2-rc2 it didn't boot, it hung before it >>> initialized the kernel. >>> Without initrd it works fine, though. >> Bah, so this change actually makes booting worse? You said before that >> you almost made it to userspace but this seems to hang much earlier now. >> Is that correct? >> >> ... back to the drawing board. > I was looking at why grub2 could boot, seems to be it reads in chunks of > 256 kilobytes. I seem to be able to get it to boot with chunks of 4 mb > as well, but didn't test beyond that. > > So the fix is to simply read the file in parts, otherwise efi hangs.. > As a nice side effect, short reads are also handled, but the efi > firmware seems to choke over huge reads and dies. So after I was encouraged by mjg59 to find out the limit, I put this patch to test maximum file size with together..
Turns out that it pukes on 4 mb, my printf was fucked, in the patch below I corrected it, so I don't know for sure if that included 4 mb being bad or not. I suppose writing a test for read(fd, addr, 5 * 1024 * 1024) was too hard for efi to pass. ;)
Just make a file with dd if=/dev/urandom of=initrd.img bs=1M count=99 to find out when/if YOUR efi implementation will die! :D
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 8627a56..415b875 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -30,6 +30,19 @@ #define PIXEL_BLT_ONLY 3 #define PIXEL_FORMAT_MAX 4 +typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { + void* Reset; + void *OutputString; + void *TestString; + void *QueryMode; + void *SetMode; + void *SetAttribute; + void *ClearScreen; + void *SetCursorPosition; + void *EnableCursor; + void *Mode; +} __attribute__((packed)) EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; + typedef struct { u32 red_mask; u32 green_mask; @@ -692,17 +705,27 @@ grow: addr = initrd_addr; for (j = 0; j < nr_initrds; j++) { - u64 size; - - size = initrds[j].size; - status = efi_call_phys3(fh->read, initrds[j].handle, - &size, addr); - if (status != EFI_SUCCESS) - goto free_initrd_total; - + u64 size, chunksize; + uint16_t str[] = { 'S', 'i', 'z', 'e', ':', ' ', ' ',' ', ' ', '\r', '\n', 0 }; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *output = (void*)sys_table->stderr; + + for (chunksize = 1024 * 1024; chunksize < initrds[j].size; chunksize += 1024 * 1024) { + str[5] = ((chunksize / 1024 / 1024) / 10) + '0'; + str[6] = ((chunksize / 1024 / 1024) % 10) + '0'; + efi_call_phys2(output->OutputString, sys_table->stderr_handle, str); + size = initrds[j].size; + efi_call_phys2(fh->set_position, initrds[j].handle, 0); + while (size) { + u64 toread = size > chunksize ? chunksize : size; + status = efi_call_phys3(fh->read, initrds[j].handle, + &toread, addr); + if (status != EFI_SUCCESS) + goto free_initrd_total; + size -= toread; + addr += toread; + } + } efi_call_phys1(fh->close, initrds[j].handle); - - addr += size; } }
| |