--- linux/arch/i386/mm/init.c.bigmem	Mon Oct  4 19:51:28 1999
+++ linux/arch/i386/mm/init.c	Mon Oct  4 20:26:37 1999
@@ -34,6 +34,40 @@
 extern void show_net_buffers(void);
 extern unsigned long init_smp_mappings(unsigned long);
 
+#ifdef CONFIG_BLK_DEV_INITRD
+
+extern unsigned long initrd_end,initrd_start;
+
+static void __init relocate_initrd(unsigned long mem_start,unsigned long mem_end)
+{
+        unsigned long initrd_size = initrd_end - initrd_start;
+        unsigned long dest;
+
+        if(!initrd_start || initrd_start >= initrd_end)
+                return;
+        if(mem_start > initrd_start) {
+                printk(KERN_CRIT "initrd already destroyed by paging_init!\n");
+                return;
+        }
+
+        dest = ((mem_end - initrd_size) & PAGE_MASK);
+        printk(KERN_WARNING "relocating initrd image:\n");
+        printk(KERN_WARNING "    initrd_start:0x%08lx    initrd_end:0x%08lx\n",
+                initrd_start, initrd_end);
+        printk(KERN_WARNING "    mem_start:0x%08lx    mem_end:0x%08lx\n",
+                mem_start, mem_end);
+        printk(KERN_WARNING "    initrd_size:0x%08lx     dest:0x%08lx\n",
+                initrd_size, dest);
+
+        if((initrd_end < dest) &&
+           (initrd_start > mem_start)) {
+                __memcpy((void *)dest,(void *)initrd_start,initrd_size);
+                initrd_start = dest;
+                initrd_end = initrd_start + initrd_size;
+        }
+}
+#endif
+
 void __bad_pte_kernel(pmd_t *pmd)
 {
 	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
@@ -326,8 +360,11 @@
 #ifndef CONFIG_BIGMEM
 	return free_area_init(start_mem, end_mem);
 #else
-	kmap_init(); /* run after fixmap_init */
-	return free_area_init(start_mem, bigmem_end + PAGE_OFFSET);
+#ifdef CONFIG_BLK_DEV_INITRD
+	relocate_initrd(start_mem,end_mem);
+#endif
+	kmap_init();
+	return(free_area_init(start_mem,bigmem_end + PAGE_OFFSET));
 #endif
 }
 
