/* Initialize final allocator for a zone */
 void __init setup_node_zones(int nodeid)
 { 
-       unsigned long start_pfn, end_pfn; 
+       unsigned long start_pfn, end_pfn, memmapsize, limit;
        unsigned long zones[MAX_NR_ZONES];
        unsigned long holes[MAX_NR_ZONES];
 
        Dprintk(KERN_INFO "Setting up node %d %lx-%lx\n",
                nodeid, start_pfn, end_pfn);
 
+       /* Try to allocate mem_map at end to not fill up precious <4GB
+          memory. */
+       memmapsize = sizeof(struct page) * (end_pfn-start_pfn);
+       limit = end_pfn << PAGE_SHIFT;
+       NODE_DATA(nodeid)->node_mem_map = 
+               __alloc_bootmem_core(NODE_DATA(nodeid)->bdata, 
+                               memmapsize, SMP_CACHE_BYTES, 
+                               round_down(limit - memmapsize, PAGE_SIZE), 
+                               limit);
+
        size_zones(zones, holes, start_pfn, end_pfn);
        free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
                            start_pfn, holes);
 
                                              unsigned long size,
                                              unsigned long align,
                                              unsigned long goal);
+extern void * __init __alloc_bootmem_core(struct bootmem_data *bdata,
+               unsigned long size, unsigned long align, unsigned long goal,
+               unsigned long limit);
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
 #define alloc_bootmem(x) \
 
  *
  * NOTE:  This function is _not_ reentrant.
  */
-static void * __init
+void * __init
 __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
              unsigned long align, unsigned long goal, unsigned long limit)
 {