]> git.hungrycats.org Git - linux/commitdiff
[PATCH] alpha: initrd vs. "mem=" fix
authorIvan Kokshaysky <ink@jurassic.park.msu.ru>
Tue, 19 Nov 2002 06:18:19 +0000 (22:18 -0800)
committerRichard Henderson <rth@are.twiddle.net>
Tue, 19 Nov 2002 06:18:19 +0000 (22:18 -0800)
As the aboot always puts initrd image near the top of physical memory,
initrd is not accessible if we limit memory size with "mem=" argument.
Fixed by moving the image to the "low" memory if needed.

Also, some of these routines will be used by marvel (in non-NUMA config)
and up1500.

Ivan.

arch/alpha/kernel/setup.c
arch/alpha/mm/init.c
arch/alpha/mm/numa.c

index 7f07f5e5dad742836adeaad8b3f63435de331036..6c9e86da2a95b89a6de89c8a4c8944e3167070c2 100644 (file)
@@ -251,6 +251,27 @@ get_mem_size_limit(char *s)
         return end >> PAGE_SHIFT; /* Return the PFN of the limit. */
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+void * __init
+move_initrd(unsigned long mem_limit)
+{
+       void *start;
+       unsigned long size;
+
+       size = initrd_end - initrd_start;
+       start = __alloc_bootmem(size, PAGE_SIZE, 0);
+       if (!start || __pa(start) + size > mem_limit) {
+               initrd_start = initrd_end = 0;
+               return NULL;
+       }
+       memmove(start, (void *)initrd_start, size);
+       initrd_start = (unsigned long)start;
+       initrd_end = initrd_start + size;
+       printk("initrd moved to %p\n", start);
+       return start;
+}
+#endif
+
 #ifndef CONFIG_DISCONTIGMEM
 static void __init
 setup_memory(void *kernel_end)
@@ -379,11 +400,11 @@ setup_memory(void *kernel_end)
                       (void *) initrd_start, INITRD_SIZE);
 
                if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
-                       printk("initrd extends beyond end of memory "
-                              "(0x%08lx > 0x%p)\ndisabling initrd\n",
-                              initrd_end,
-                              phys_to_virt(PFN_PHYS(max_low_pfn)));
-                       initrd_start = initrd_end = 0;
+                       if (!move_initrd(PFN_PHYS(max_low_pfn)))
+                               printk("initrd extends beyond end of memory "
+                                      "(0x%08lx > 0x%p)\ndisabling initrd\n",
+                                      initrd_end,
+                                      phys_to_virt(PFN_PHYS(max_low_pfn)));
                } else {
                        reserve_bootmem(virt_to_phys((void *)initrd_start),
                                        INITRD_SIZE);
index 2233f32d79232c53f617509aadd643df8d5d2bbb..a33c2289db415a3e87d165f64e0a1d00c0f0c3f8 100644 (file)
@@ -357,18 +357,23 @@ mem_init(void)
 #endif /* CONFIG_DISCONTIGMEM */
 
 void
-free_initmem (void)
+free_reserved_mem(void *start, void *end)
 {
-       extern char __init_begin, __init_end;
-       unsigned long addr;
-
-       addr = (unsigned long)(&__init_begin);
-       for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               set_page_count(virt_to_page(addr), 1);
-               free_page(addr);
+       void *__start = start;
+       for (; __start < end; __start += PAGE_SIZE) {
+               ClearPageReserved(virt_to_page(__start));
+               set_page_count(virt_to_page(__start), 1);
+               free_page((long)__start);
                totalram_pages++;
        }
+}
+
+void
+free_initmem(void)
+{
+       extern char __init_begin, __init_end;
+
+       free_reserved_mem(&__init_begin, &__init_end);
        printk ("Freeing unused kernel memory: %ldk freed\n",
                (&__init_end - &__init_begin) >> 10);
 }
@@ -377,13 +382,7 @@ free_initmem (void)
 void
 free_initrd_mem(unsigned long start, unsigned long end)
 {
-       unsigned long __start = start;
-       for (; start < end; start += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(start));
-               set_page_count(virt_to_page(start), 1);
-               free_page(start);
-               totalram_pages++;
-       }
-       printk ("Freeing initrd memory: %ldk freed\n", (end - __start) >> 10);
+       free_reserved_mem((void *)start, (void *)end);
+       printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
 #endif
index 5071c14da05987d2e173bcaecca2e2c90eed7721..1375e90f809d9135d2da780fa80b769afac2be3c 100644 (file)
@@ -249,16 +249,18 @@ setup_memory(void *kernel_end)
 #ifdef CONFIG_BLK_DEV_INITRD
        initrd_start = INITRD_START;
        if (initrd_start) {
+               extern void *move_initrd(unsigned long);
+
                initrd_end = initrd_start+INITRD_SIZE;
                printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
                       (void *) initrd_start, INITRD_SIZE);
 
                if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
-                       printk("initrd extends beyond end of memory "
-                              "(0x%08lx > 0x%p)\ndisabling initrd\n",
-                              initrd_end,
-                              phys_to_virt(PFN_PHYS(max_low_pfn)));
-                       initrd_start = initrd_end = 0;
+                       if (!move_initrd(PFN_PHYS(max_low_pfn)))
+                               printk("initrd extends beyond end of memory "
+                                      "(0x%08lx > 0x%p)\ndisabling initrd\n",
+                                      initrd_end,
+                                      phys_to_virt(PFN_PHYS(max_low_pfn)));
                } else {
                        reserve_bootmem_node(NODE_DATA(KVADDR_TO_NID(initrd_start)),
                                             virt_to_phys((void *)initrd_start),