|
@@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size)
|
|
|
|
|
|
unsigned long decompress_kernel(void)
|
|
|
{
|
|
|
- unsigned long output_addr;
|
|
|
- unsigned char *output;
|
|
|
+ void *output, *kernel_end;
|
|
|
|
|
|
- output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
|
|
|
- check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
|
|
|
- memset(&_bss, 0, &_ebss - &_bss);
|
|
|
- free_mem_ptr = (unsigned long)&_end;
|
|
|
- free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
|
|
- output = (unsigned char *) output_addr;
|
|
|
+ output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE);
|
|
|
+ kernel_end = output + SZ__bss_start;
|
|
|
+ check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
|
|
|
|
|
|
#ifdef CONFIG_BLK_DEV_INITRD
|
|
|
/*
|
|
|
* Move the initrd right behind the end of the decompressed
|
|
|
- * kernel image.
|
|
|
+ * kernel image. This also prevents initrd corruption caused by
|
|
|
+ * bss clearing since kernel_end will always be located behind the
|
|
|
+ * current bss section..
|
|
|
*/
|
|
|
- if (INITRD_START && INITRD_SIZE &&
|
|
|
- INITRD_START < (unsigned long) output + SZ__bss_start) {
|
|
|
- check_ipl_parmblock(output + SZ__bss_start,
|
|
|
- INITRD_START + INITRD_SIZE);
|
|
|
- memmove(output + SZ__bss_start,
|
|
|
- (void *) INITRD_START, INITRD_SIZE);
|
|
|
- INITRD_START = (unsigned long) output + SZ__bss_start;
|
|
|
+ if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
|
|
|
+ check_ipl_parmblock(kernel_end, INITRD_SIZE);
|
|
|
+ memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
|
|
|
+ INITRD_START = (unsigned long) kernel_end;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+ /*
|
|
|
+ * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be
|
|
|
+ * initialized afterwards since they reside in bss.
|
|
|
+ */
|
|
|
+ memset(&_bss, 0, &_ebss - &_bss);
|
|
|
+ free_mem_ptr = (unsigned long) &_end;
|
|
|
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
|
|
+
|
|
|
puts("Uncompressing Linux... ");
|
|
|
__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
|
|
|
puts("Ok, booting the kernel.\n");
|