/* * Function: smp_dump_qct() * * Description: gets memory layout from the quad config table. This * function also updates node_online_map with the nodes (quads) present. */ static void __init smp_dump_qct(void) { int node; struct eachquadmem *eq; struct sys_cfg_data *scd = (struct sys_cfg_data *)__va(SYS_CFG_DATA_PRIV_ADDR); nodes_clear(node_online_map); for_each_node(node) { if (scd->quads_present31_0 & (1 << node)) { node_set_online(node); eq = &scd->eq[node]; /* Convert to pages */ node_start_pfn[node] = MB_TO_PAGES( eq->hi_shrd_mem_start - eq->priv_mem_size); node_end_pfn[node] = MB_TO_PAGES( eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); memory_present(node, node_start_pfn[node], node_end_pfn[node]); node_remap_size[node] = node_memmap_size_bytes(node, node_start_pfn[node], node_end_pfn[node]); } } }
void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; max_zone_pfns[ZONE_NORMAL] = end_pfn; memory_present(0, 0, end_pfn); sparse_init(); free_area_init_nodes(max_zone_pfns); }
void __init do_init_bootmem(void) { unsigned long i; unsigned long start, bootmap_pages; unsigned long total_pages; int boot_mapsize; max_pfn = total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; #ifdef CONFIG_HIGHMEM total_pages = total_lowmem >> PAGE_SHIFT; #endif /* * Find an area to use for the bootmem bitmap. Calculate the size of * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. * Add 1 additional page in case the address isn't page-aligned. */ bootmap_pages = bootmem_bootmap_pages(total_pages); start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); BUG_ON(!start); boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); /* Add all physical memory to the bootmem map, mark each area * present. */ for (i = 0; i < lmb.memory.cnt; i++) { unsigned long base = lmb.memory.region[i].base; unsigned long size = lmb_size_bytes(&lmb.memory, i); #ifdef CONFIG_HIGHMEM if (base >= total_lowmem) continue; if (base + size > total_lowmem) size = total_lowmem - base; #endif free_bootmem(base, size); } /* reserve the sections we're already using */ for (i = 0; i < lmb.reserved.cnt; i++) reserve_bootmem(lmb.reserved.region[i].base, lmb_size_bytes(&lmb.reserved, i)); /* XXX need to clip this if using highmem? */ for (i = 0; i < lmb.memory.cnt; i++) memory_present(0, lmb_start_pfn(&lmb.memory, i), lmb_end_pfn(&lmb.memory, i)); init_bootmem_done = 1; }
static void __init bootmem_init(void) { unsigned long start_pfn, bootmap_size; unsigned long size = initrd_end - initrd_start; start_pfn = PFN_UP(__pa(&_end)); min_low_pfn = PFN_UP(MEMORY_START); max_low_pfn = PFN_UP(MEMORY_START + MEMORY_SIZE); /* Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, min_low_pfn, max_low_pfn); add_active_range(0, min_low_pfn, max_low_pfn); free_bootmem(PFN_PHYS(start_pfn), (max_low_pfn - start_pfn) << PAGE_SHIFT); memory_present(0, start_pfn, max_low_pfn); /* Reserve space for the bootmem bitmap. */ reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size, BOOTMEM_DEFAULT); if (size == 0) { printk(KERN_INFO "Initrd not found or empty"); goto disable; } if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { printk(KERN_ERR "Initrd extends beyond end of memory"); goto disable; } /* Reserve space for the initrd bitmap. */ reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT); initrd_below_start_ok = 1; pr_info("Initial ramdisk at: 0x%lx (%lu bytes)\n", initrd_start, size); return; disable: printk(KERN_CONT " - disabling initrd\n"); initrd_start = 0; initrd_end = 0; }
static inline void numaq_register_node(int node, struct sys_cfg_data *scd) { struct eachquadmem *eq = scd->eq + node; node_set_online(node); /* Convert to pages */ node_start_pfn[node] = MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size); node_end_pfn[node] = MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); e820_register_active_regions(node, node_start_pfn[node], node_end_pfn[node]); memory_present(node, node_start_pfn[node], node_end_pfn[node]); node_remap_size[node] = node_memmap_size_bytes(node, node_start_pfn[node], node_end_pfn[node]); }
static void __init bootmem_init(void) { unsigned long reserved_end; unsigned long mapstart = ~0UL; unsigned long bootmap_size; int i; /* * Init any data related to initrd. It's a nop if INITRD is * not selected. Once that done we can determine the low bound * of usable memory. */ reserved_end = max(init_initrd(), (unsigned long) PFN_UP(__pa_symbol(&_end))); /* * max_low_pfn is not a number of pages. The number of pages * of the system is given by 'max_low_pfn - min_low_pfn'. */ min_low_pfn = ~0UL; max_low_pfn = 0; /* * Find the highest page frame number we have available. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); if (end > max_low_pfn) max_low_pfn = end; if (start < min_low_pfn) min_low_pfn = start; if (end <= reserved_end) continue; if (start >= mapstart) continue; mapstart = max(reserved_end, start); } if (min_low_pfn >= max_low_pfn) panic("Incorrect memory mapping !!!"); if (min_low_pfn > ARCH_PFN_OFFSET) { pr_info("Wasting %lu bytes for tracking %lu unused pages\n", (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page), min_low_pfn - ARCH_PFN_OFFSET); } else if (min_low_pfn < ARCH_PFN_OFFSET) { pr_info("%lu free pages won't be used\n", ARCH_PFN_OFFSET - min_low_pfn); } min_low_pfn = ARCH_PFN_OFFSET; /* * Determine low and high memory ranges */ max_pfn = max_low_pfn; if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { #ifdef CONFIG_HIGHMEM highstart_pfn = PFN_DOWN(HIGHMEM_START); highend_pfn = max_low_pfn; #endif max_low_pfn = PFN_DOWN(HIGHMEM_START); } /* * Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart, min_low_pfn, max_low_pfn); for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); if (start <= min_low_pfn) start = min_low_pfn; if (start >= end) continue; #ifndef CONFIG_HIGHMEM if (end > max_low_pfn) end = max_low_pfn; /* * ... finally, is the area going away? */ if (end <= start) continue; #endif add_active_range(0, start, end); } /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end, size; /* * Reserve usable memory. */ if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); /* * We are rounding up the start address of usable memory * and at the end of the usable range downwards. */ if (start >= max_low_pfn) continue; if (start < reserved_end) start = reserved_end; if (end > max_low_pfn) end = max_low_pfn; /* * ... finally, is the area going away? */ if (end <= start) continue; size = end - start; /* Register lowmem ranges */ #ifdef CONFIG_BRCMSTB /* carve out space for bmem */ brcm_free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); #else free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); #endif } /* * Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT); /* * Reserve initrd memory if needed. */ finalize_initrd(); /* * Call memory_present() on all valid ranges, for SPARSEMEM. * This must be done after setting up bootmem, since memory_present() * may allocate bootmem. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); memory_present(0, start, end); } }
int __init get_memcfg_from_srat(void) { int i, j, nid; if (srat_disabled()) goto out_fail; if (acpi_numa_init() < 0) goto out_fail; if (num_memory_chunks == 0) { printk(KERN_DEBUG "could not find any ACPI SRAT memory areas.\n"); goto out_fail; } /* Calculate total number of nodes in system from PXM bitmap and create * a set of sequential node IDs starting at zero. (ACPI doesn't seem * to specify the range of _PXM values.) */ /* * MCD - we no longer HAVE to number nodes sequentially. PXM domain * numbers could go as high as 256, and MAX_NUMNODES for i386 is typically * 32, so we will continue numbering them in this manner until MAX_NUMNODES * approaches MAX_PXM_DOMAINS for i386. */ nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (BMAP_TEST(pxm_bitmap, i)) { int nid = acpi_map_pxm_to_node(i); node_set_online(nid); } } BUG_ON(num_online_nodes() == 0); /* set cnode id in memory chunk structure */ for (i = 0; i < num_memory_chunks; i++) node_memory_chunk[i].nid = pxm_to_node(node_memory_chunk[i].pxm); printk(KERN_DEBUG "pxm bitmap: "); for (i = 0; i < sizeof(pxm_bitmap); i++) { printk(KERN_CONT "%02x ", pxm_bitmap[i]); } printk(KERN_CONT "\n"); printk(KERN_DEBUG "Number of logical nodes in system = %d\n", num_online_nodes()); printk(KERN_DEBUG "Number of memory chunks in system = %d\n", num_memory_chunks); for (i = 0; i < MAX_LOCAL_APIC; i++) set_apicid_to_node(i, pxm_to_node(apicid_to_pxm[i])); for (j = 0; j < num_memory_chunks; j++){ struct node_memory_chunk_s * chunk = &node_memory_chunk[j]; printk(KERN_DEBUG "chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", j, chunk->nid, chunk->start_pfn, chunk->end_pfn); if (node_read_chunk(chunk->nid, chunk)) continue; memblock_x86_register_active_regions(chunk->nid, chunk->start_pfn, min(chunk->end_pfn, max_pfn)); } /* for out of order entries in SRAT */ sort_node_map(); for_each_online_node(nid) { unsigned long start = node_start_pfn[nid]; unsigned long end = min(node_end_pfn[nid], max_pfn); memory_present(nid, start, end); node_remap_size[nid] = node_memmap_size_bytes(nid, start, end); } return 1; out_fail: printk(KERN_DEBUG "failed to get NUMA memory information from SRAT" " table\n"); return 0; }
/* Parse the ACPI Static Resource Affinity Table */ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) { u8 *start, *end, *p; int i, j, nid; start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ p = start; end = (u8 *)sratp + sratp->header.length; memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */ memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); num_memory_chunks = 0; while (p < end) { switch (*p) { case ACPI_SRAT_TYPE_CPU_AFFINITY: parse_cpu_affinity_structure(p); break; case ACPI_SRAT_TYPE_MEMORY_AFFINITY: parse_memory_affinity_structure(p); break; default: printk("ACPI 2.0 SRAT: unknown entry skipped: type=0x%02X, len=%d\n", p[0], p[1]); break; } p += p[1]; if (p[1] == 0) { printk("acpi20_parse_srat: Entry length value is zero;" " can't parse any further!\n"); break; } } if (num_memory_chunks == 0) { printk("could not finy any ACPI SRAT memory areas.\n"); goto out_fail; } /* Calculate total number of nodes in system from PXM bitmap and create * a set of sequential node IDs starting at zero. (ACPI doesn't seem * to specify the range of _PXM values.) */ /* * MCD - we no longer HAVE to number nodes sequentially. PXM domain * numbers could go as high as 256, and MAX_NUMNODES for i386 is typically * 32, so we will continue numbering them in this manner until MAX_NUMNODES * approaches MAX_PXM_DOMAINS for i386. */ nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (BMAP_TEST(pxm_bitmap, i)) { int nid = acpi_map_pxm_to_node(i); node_set_online(nid); } } BUG_ON(num_online_nodes() == 0); /* set cnode id in memory chunk structure */ for (i = 0; i < num_memory_chunks; i++) node_memory_chunk[i].nid = pxm_to_node(node_memory_chunk[i].pxm); printk("pxm bitmap: "); for (i = 0; i < sizeof(pxm_bitmap); i++) { printk("%02X ", pxm_bitmap[i]); } printk("\n"); printk("Number of logical nodes in system = %d\n", num_online_nodes()); printk("Number of memory chunks in system = %d\n", num_memory_chunks); for (i = 0; i < MAX_APICID; i++) apicid_2_node[i] = pxm_to_node(apicid_to_pxm[i]); for (j = 0; j < num_memory_chunks; j++){ struct node_memory_chunk_s * chunk = &node_memory_chunk[j]; printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", j, chunk->nid, chunk->start_pfn, chunk->end_pfn); node_read_chunk(chunk->nid, chunk); add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn); } for_each_online_node(nid) { unsigned long start = node_start_pfn[nid]; unsigned long end = node_end_pfn[nid]; memory_present(nid, start, end); node_remap_size[nid] = node_memmap_size_bytes(nid, start, end); } return 1; out_fail: return 0; }
for_each_memblock(memory, reg) { int nid = memblock_get_region_node(reg); memory_present(nid, memblock_region_memory_base_pfn(reg), memblock_region_memory_end_pfn(reg)); }
static void __init bootmem_init(void) { unsigned long reserved_end; unsigned long highest = 0; unsigned long mapstart = -1UL; unsigned long bootmap_size; int i; /* * Init any data related to initrd. It's a nop if INITRD is * not selected. Once that done we can determine the low bound * of usable memory. */ reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end))); /* * Find the highest page frame number we have available. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); if (end > highest) highest = end; if (end <= reserved_end) continue; if (start >= mapstart) continue; mapstart = max(reserved_end, start); } /* * Determine low and high memory ranges */ if (highest > PFN_DOWN(HIGHMEM_START)) { #ifdef CONFIG_HIGHMEM highstart_pfn = PFN_DOWN(HIGHMEM_START); highend_pfn = highest; #endif highest = PFN_DOWN(HIGHMEM_START); } /* * Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem(mapstart, highest); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end, size; /* * Reserve usable memory. */ if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); /* * We are rounding up the start address of usable memory * and at the end of the usable range downwards. */ if (start >= max_low_pfn) continue; if (start < reserved_end) start = reserved_end; if (end > max_low_pfn) end = max_low_pfn; /* * ... finally, is the area going away? */ if (end <= start) continue; size = end - start; /* Register lowmem ranges */ free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); memory_present(0, start, end); } /* * Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(mapstart), bootmap_size); /* * Reserve initrd memory if needed. */ finalize_initrd(); }
static void __init bootmem_init(void) { unsigned long reserved_end; unsigned long mapstart = ~0UL; unsigned long bootmap_size; int i; /* * Sanity check any INITRD first. We don't take it into account * for bootmem setup initially, rely on the end-of-kernel-code * as our memory range starting point. Once bootmem is inited we * will reserve the area used for the initrd. */ init_initrd(); reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end)); /* * max_low_pfn is not a number of pages. The number of pages * of the system is given by 'max_low_pfn - min_low_pfn'. */ min_low_pfn = ~0UL; max_low_pfn = 0; /* * Find the highest page frame number we have available. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); if (end > max_low_pfn) max_low_pfn = end; if (start < min_low_pfn) min_low_pfn = start; if (end <= reserved_end) continue; if (start >= mapstart) continue; mapstart = max(reserved_end, start); } if (min_low_pfn >= max_low_pfn) panic("Incorrect memory mapping !!!"); if (min_low_pfn > ARCH_PFN_OFFSET) { printk(KERN_INFO "Wasting %lu bytes for tracking %lu unused pages\n", (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page), min_low_pfn - ARCH_PFN_OFFSET); } else if (min_low_pfn < ARCH_PFN_OFFSET) { printk(KERN_INFO "%lu free pages won't be used\n", ARCH_PFN_OFFSET - min_low_pfn); } min_low_pfn = ARCH_PFN_OFFSET; /* * Determine low and high memory ranges */ max_pfn = max_low_pfn; if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { #ifdef CONFIG_HIGHMEM highstart_pfn = PFN_DOWN(HIGHMEM_START); highend_pfn = max_low_pfn; #endif max_low_pfn = PFN_DOWN(HIGHMEM_START); } /* * Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart, min_low_pfn, max_low_pfn); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end, size; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); /* * Reserve usable memory. */ switch (boot_mem_map.map[i].type) { case BOOT_MEM_RAM: break; case BOOT_MEM_INIT_RAM: memory_present(0, start, end); continue; default: /* Not usable memory */ continue; } /* * We are rounding up the start address of usable memory * and at the end of the usable range downwards. */ if (start >= max_low_pfn) continue; if (start < reserved_end) start = reserved_end; if (end > max_low_pfn) end = max_low_pfn; /* * ... finally, is the area going away? */ if (end <= start) continue; size = end - start; /* Register lowmem ranges */ free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); memory_present(0, start, end); } /* * Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(mapstart), bootmap_size); /* * Reserve initrd memory if needed. */ finalize_initrd(); }
static void __init bootmem_init(void) { unsigned long reserved_end; unsigned long mapstart = ~0UL; unsigned long bootmap_size; int i; /* * Init any data related to initrd. It's a nop if INITRD is * not selected. Once that done we can determine the low bound * of usable memory. */ #ifdef CONFIG_XEN reserved_end = max(init_initrd(), (unsigned long) PFN_UP(__pa_symbol(&_end) + PAGE_SIZE)); #else reserved_end = max(init_initrd(), (unsigned long) PFN_UP(__pa_symbol(&_end))); #endif /* * max_low_pfn is not a number of pages. The number of pages * of the system is given by 'max_low_pfn - min_low_pfn'. */ min_low_pfn = ~0UL; max_low_pfn = 0; /* * Find the highest page frame number we have available. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; /* Changing the math in several places below to add -1. If a region * ends exactly on a boundary where there is no DRAM, the last PFN * will be incorrect (one page of memory will have no DRAM backing). * By subtracting one here, this problem is eliminated. */ start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1); if (end > max_low_pfn) max_low_pfn = end; if (start < min_low_pfn) min_low_pfn = start; if (end <= reserved_end) continue; if (start >= mapstart) continue; mapstart = max(reserved_end, start); } if (min_low_pfn >= max_low_pfn) panic("Incorrect memory mapping !!!"); if (min_low_pfn > ARCH_PFN_OFFSET) { pr_info("Wasting %lu bytes for tracking %lu unused pages\n", (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page), min_low_pfn - ARCH_PFN_OFFSET); } else if (min_low_pfn < ARCH_PFN_OFFSET) { pr_info("%lu free pages won't be used\n", ARCH_PFN_OFFSET - min_low_pfn); } min_low_pfn = ARCH_PFN_OFFSET; /* * Determine low and high memory ranges */ max_pfn = max_low_pfn; if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { #ifdef CONFIG_HIGHMEM highstart_pfn = PFN_DOWN(HIGHMEM_START); highend_pfn = max_low_pfn; #endif max_low_pfn = PFN_DOWN(HIGHMEM_START); } max_low_pfn = recalculate_max_low_pfn(max_low_pfn); #ifdef DEBUG_MAPPED_KERNEL printk("max_low_pfn = 0x%lx\n", max_low_pfn); #endif /* * Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart, min_low_pfn, max_low_pfn); for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1); if (start <= min_low_pfn) start = min_low_pfn; if (start >= end) continue; #ifndef CONFIG_HIGHMEM if (end > max_low_pfn) end = max_low_pfn; /* * ... finally, is the area going away? */ if (end <= start) continue; #endif add_active_range(0, start, end); } /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end, size; /* * Reserve usable memory. */ if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1); /* * We are rounding up the start address of usable memory * and at the end of the usable range downwards. */ if (start >= max_low_pfn) continue; if (start < reserved_end) start = reserved_end; if (end > max_low_pfn) end = max_low_pfn; /* * ... finally, is the area going away? */ if (end <= start) continue; size = end - start; /* Register lowmem ranges */ free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); memory_present(0, start, end); } /* * Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT); /* * Reserve initrd memory if needed. */ finalize_initrd(); }