Index: linux-2.6.15-rc1/arch/arm/mm/init.c
===================================================================
--- linux-2.6.15-rc1.orig/arch/arm/mm/init.c	2005-11-20 10:49:24.000000000 +0000
+++ linux-2.6.15-rc1/arch/arm/mm/init.c	2005-11-20 17:38:19.000000000 +0000
@@ -96,6 +96,12 @@
 	return pmd_off(pgd_offset_k(virt), virt);
 }
 
+struct node_info {
+	unsigned int start;
+	unsigned int end;
+	int bootmap_pages;
+};
+
 #define for_each_nodebank(iter,mi,no)			\
 	for (iter = 0; iter < mi->nr_banks; iter++)	\
 		if (mi->bank[iter].node == no)
@@ -236,7 +242,7 @@
 void __init create_mapping(struct map_desc *md);
 
 static unsigned long __init
-bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
+bootmem_init_node(int node, int initrd_node, struct meminfo *mi, unsigned long memend_pfn, struct node_info *np)	
 {
 	unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
 	unsigned long start_pfn, end_pfn, boot_pfn;
@@ -244,6 +250,11 @@
 	pg_data_t *pgdat;
 	int i;
 
+	struct bootmem_data *bdata;
+	unsigned int bootmem_pages = 0, bootmap_pfn, map_pg;
+
+for_each_node(node) {
+
 	start_pfn = -1UL;
 	end_pfn = 0;
 
@@ -270,17 +281,41 @@
 		create_mapping(&map);
 	}
 
+
 	/*
 	 * If there is no memory in this node, ignore it.
 	 */
 	if (end_pfn == 0)
-		return end_pfn;
+		continue;
+		//return end_pfn;
 
 	/*
 	 * Allocate the bootmem bitmap page.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
 	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+//	if node_online(node) {
+//		np[node].bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+//		bootmem_pages += boot_pages;
+//	}
+//}
+	bootmap_pfn = find_bootmap_pfn(0, mi, bootmem_pages);
+	map_pg = bootmap_pfn;
+
+	/*
+	 * Initialise the bootmem nodes.
+	 */
+//	np += num_online_nodes() - 1;
+//	for (node = num_online_nodes() - 1; node >= 0; node--, np--) {
+//		/*
+//		 * If there are no pages in this node, ignore it.
+//		 * Note that node 0 must always have some pages.
+//		 */
+//		if (np->end == 0 || !node_online(node)) {
+//			if (node == 0)
+//				BUG();
+//			continue;
+//		}
 
 	/*
 	 * Initialise the bootmem allocator for this node, handing the
@@ -289,6 +324,7 @@
 	node_set_online(node);
 	pgdat = NODE_DATA(node);
 	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+//	init_bootmem_node(pgdat, map_pg, np->start, np->end);
 
 	for_each_nodebank(i, mi, node)
 		free_bootmem_node(pgdat, mi->bank[i].start, mi->bank[i].size);
@@ -299,6 +335,8 @@
 	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
 			     boot_pages << PAGE_SHIFT);
 
+//	map_pg += np->bootmap_pages;
+
 #ifdef CONFIG_BLK_DEV_INITRD
 	/*
 	 * If the initrd is in this node, reserve its memory.
@@ -314,8 +352,19 @@
 	/*
 	 * Finally, reserve any node zero regions.
 	 */
-	if (node == 0)
+	if (node == 0) {
 		reserve_node_zero(pgdat);
+		//reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT, bootmem_pages << PAGE_SHIFT);
+	}
+
+	}
+
+//	BUG_ON(map_pg != bootmap_pfn + bootmem_pages);
+
+	/*
+	 * initialise the zones within this node
+	 */
+	for_each_online_node(node) {
 
 	/*
 	 * initialise the zones within this node.
@@ -323,12 +372,22 @@
 	memset(zone_size, 0, sizeof(zone_size));
 	memset(zhole_size, 0, sizeof(zhole_size));
 
+	pgdat = NODE_DATA(node);
+	bdata = pgdat->bdata;
+
 	/*
 	 * The size of this node has already been determined.  If we need
 	 * to do anything fancy with the allocation of this memory to the
 	 * zones, now is the time to do it.
 	 */
-	zone_size[0] = end_pfn - start_pfn;
+	zone_size[0] = bdata->node_low_pfn -
+			(bdata->node_boot_start >> PAGE_SHIFT);
+
+	/*
+	 * If this zone has zero size, skip it.
+	 */
+	if (!zone_size[0])
+		continue;
 
 	/*
 	 * For each bank in this node, calculate the size of the holes.
@@ -344,7 +403,9 @@
 	 */
 	arch_adjust_zones(node, zone_size, zhole_size);
 
-	free_area_init_node(node, pgdat, zone_size, start_pfn, zhole_size);
+	free_area_init_node(node, pgdat, zone_size,
+			bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
+	}
 
 	return end_pfn;
 }
@@ -354,6 +415,8 @@
 	unsigned long addr, memend_pfn = 0;
 	int node, initrd_node, i;
 
+	struct node_info node_info[MAX_NUMNODES], *np = node_info;
+
 	/*
 	 * Invalidate the node number for empty or invalid memory banks
 	 */
@@ -382,6 +445,12 @@
 	for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
 	     addr < VMALLOC_END; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
+	
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		np[i].start = -1U;
+		np[i].end = 0;
+		np[i].bootmap_pages = 0;
+	}
 
 	/*
 	 * Locate which node contains the ramdisk image, if any.
@@ -394,15 +463,51 @@
 	for_each_node(node) {
 		unsigned long end_pfn;
 
-		end_pfn = bootmem_init_node(node, initrd_node, mi);
+//		end_pfn = bootmem_init_node(node, initrd_node, mi);
 
 		/*
 		 * Remember the highest memory PFN.
 		 */
-		if (end_pfn > memend_pfn)
-			memend_pfn = end_pfn;
+//		if (end_pfn > memend_pfn)
+//			memend_pfn = end_pfn;
 	}
 
+	for (i = 0; i < mi->nr_banks; i++) {
+		unsigned long start, end;
+		int node;
+
+		if (mi->bank[i].node == -1) 
+			continue;
+
+		node = mi->bank[i].node;
+
+		/*
+		 * Make sure we haven't exceeded the maximum number of nodes
+		 * that we have in this configuration.  If we have, we're in
+		 * trouble.  (maybe we ought to limit, instead of bugging?)
+		 */
+		if (node >= MAX_NUMNODES)
+			BUG();
+		node_set_online(node);
+
+		/*
+		 * Get the start and end pfns for this bank
+		 */
+		start = (mi->bank[i].start) >> PAGE_SHIFT;
+		end   = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
+
+		if (np[node].start > start)
+			np[node].start = start;
+
+		if (np[node].end < end)
+			np[node].end = end;
+
+		if (memend_pfn < end)
+			memend_pfn = end;
+	}
+
+	bootmem_init_node(node, initrd_node, mi, memend_pfn, np);
+
 	high_memory = __va(memend_pfn << PAGE_SHIFT);
 
 	/*
@@ -496,6 +601,7 @@
 	 * draining.  After this point, we can start to touch devices
 	 * again.
 	 */
+	flush_cache_all();
 	local_flush_tlb_all();
 }
 
@@ -579,7 +685,8 @@
 	 * information on the command line.
 	 */
 	for_each_nodebank(i, mi, node) {
-		bank_start = mi->bank[i].start >> PAGE_SHIFT;
+
+		bank_start = __phys_to_pfn(mi->bank[i].start) >> PAGE_SHIFT;
 		if (bank_start < prev_bank_end) {
 			printk(KERN_ERR "MEM: unordered memory banks.  "
 				"Not freeing memmap.\n");
@@ -593,7 +700,7 @@
 		if (prev_bank_end && prev_bank_end != bank_start)
 			free_memmap(node, prev_bank_end, bank_start);
 
-		prev_bank_end = (mi->bank[i].start +
+		prev_bank_end = (__phys_to_pfn(mi->bank[i].start) +
 				 mi->bank[i].size) >> PAGE_SHIFT;
 	}
 }

