diff -urN initrd-ref/arch/alpha/kernel/setup.c initrd/arch/alpha/kernel/setup.c --- initrd-ref/arch/alpha/kernel/setup.c Thu Jun 22 03:48:16 2000 +++ initrd/arch/alpha/kernel/setup.c Fri Jun 23 03:09:31 2000 @@ -291,15 +291,29 @@ #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 + end of the RAM so we won't risk to rewrite + initrd while allocating the memory at boot time */ + unsigned long relocate; + + relocate = (*memory_end_p - initrd_size) & PAGE_MASK; + if (relocate > initrd_start) { + memmove((char *) relocate, + (char *) initrd_start, initrd_size); + initrd_start = relocate; + initrd_end = initrd_start + initrd_size; + } } } #endif diff -urN initrd-ref/arch/i386/mm/init.c initrd/arch/i386/mm/init.c --- initrd-ref/arch/i386/mm/init.c Thu Jun 22 03:47:46 2000 +++ initrd/arch/i386/mm/init.c Fri Jun 23 03:05:11 2000 @@ -269,6 +269,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. @@ -352,6 +370,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); #ifndef CONFIG_BIGMEM return free_area_init(start_mem, end_mem);