diff -urN 2.2.18pre2/arch/alpha/kernel/setup.c robust-initrd/arch/alpha/kernel/setup.c --- 2.2.18pre2/arch/alpha/kernel/setup.c Wed Aug 30 03:42:27 2000 +++ robust-initrd/arch/alpha/kernel/setup.c Thu Sep 7 16:17:06 2000 @@ -290,15 +290,35 @@ #ifdef CONFIG_BLK_DEV_INITRD initrd_start = INITRD_START; if (initrd_start) { - initrd_end = initrd_start+INITRD_SIZE; + unsigned long initrd_size = INITRD_SIZE; + initrd_end = initrd_start+initrd_size; printk("Initial ramdisk at: 0x%p (%lu bytes)\n", - (void *) initrd_start, INITRD_SIZE); + (void *) initrd_start, initrd_size); if (initrd_end > *memory_end_p) { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end, (unsigned long) memory_end_p); + initrd_end, *memory_end_p); initrd_start = initrd_end = 0; + } else { + /* move initrd from the middle of the RAM to the + start of the RAM so we won't risk to rewrite + initrd while allocating the memory at boot time */ + unsigned long memory_start; + + memory_start = *memory_start_p; + /* + * Alloc initrd in a page aligned region, + * the memory between memory_start and + * the end of the page would be wasted anyway... + */ + memory_start = PAGE_ALIGN(memory_start); + memmove((char *) memory_start, + (char *) initrd_start, initrd_size); + initrd_start = memory_start; + initrd_end = initrd_start + initrd_size; + *memory_start_p = PAGE_ALIGN(initrd_end); + initrd_below_start_ok = 1; } } #endif diff -urN 2.2.18pre2/arch/i386/mm/init.c robust-initrd/arch/i386/mm/init.c --- 2.2.18pre2/arch/i386/mm/init.c Sat Oct 23 15:31:08 1999 +++ robust-initrd/arch/i386/mm/init.c Thu Sep 7 16:06:00 2000 @@ -260,6 +260,24 @@ set_pte_phys (address,phys); } +static void __init relocate_initrd(unsigned long mem_start, + unsigned long end_mem) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long initrd_size, relocate; + + if (!initrd_start || mem_start > initrd_start) + return; + initrd_size = initrd_end - initrd_start; + relocate = (end_mem - initrd_size) & PAGE_MASK; + if (initrd_start < relocate) { + memmove((char *) relocate, (char *) initrd_start, initrd_size); + initrd_start = relocate; + initrd_end = initrd_start + initrd_size; + } +#endif +} + /* * paging_init() sets up the page tables - note that the first 4MB are * already mapped by head.S. @@ -343,6 +361,9 @@ start_mem = init_smp_mappings(start_mem); #endif local_flush_tlb(); + + /* relocate initrd as soon as we have the paging working */ + relocate_initrd(start_mem, end_mem); return free_area_init(start_mem, end_mem); }