void __init setup_physmem(unsigned long start, unsigned long reserve_end, unsigned long len, unsigned long long highmem) { unsigned long reserve = reserve_end - start; int pfn = PFN_UP(__pa(reserve_end)); int delta = (len - reserve) >> PAGE_SHIFT; int err, offset, bootmap_size; physmem_fd = create_mem_file(len + highmem); offset = uml_reserved - uml_physmem; err = os_map_memory((void *) uml_reserved, physmem_fd, offset, len - offset, 1, 1, 1); if (err < 0) { printf("setup_physmem - mapping %ld bytes of memory at 0x%p " "failed - errno = %d\n", len - offset, (void *) uml_reserved, err); exit(1); } /* * Special kludge - This page will be mapped in to userspace processes * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, len - bootmap_size - reserve); }
void __init bootmem_init(void) { struct memblock_region *reg; unsigned long bootmap_size; unsigned long free_pfn, end_pfn, start_pfn; init_mm.start_code = (unsigned long)_stext; init_mm.end_code = (unsigned long)_etext; init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)_end; memblock_init(); memblock_add(memory_start, memory_end); if(((unsigned long)__pa(_end) < memory_start) || ((unsigned long)__pa(_end) > memory_end)) printk("BUG: your kernel is not located in the ddr sdram"); start_pfn = PFN_UP(memory_start); free_pfn = PFN_UP(__pa((unsigned long)_end)); end_pfn = PFN_DOWN(memory_end); //memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(free_pfn - start_pfn)); memblock_reserve(__pa(_stext), _end - _stext); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && initrd_end && initrd_start < initrd_end) { memblock_reserve(initrd_start, initrd_end - initrd_start); } #endif bootmap_size = init_bootmem(free_pfn, end_pfn); memblock_reserve(PFN_PHYS(free_pfn), bootmap_size); free_bootmem(PFN_PHYS(free_pfn), PFN_PHYS(end_pfn - free_pfn)); for_each_memblock(reserved, reg) reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); memory_start += PAGE_OFFSET; memory_end += PAGE_OFFSET; memblock_analyze(); memblock_dump_all(); }
static unsigned long __init setup_memory(void) { unsigned long bootmap_size, start_pfn, max_low_pfn; #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define PFN_PHYS(x) ((x) << PAGE_SHIFT) #ifndef CONFIG_FB_OC_SHMEM_SIZE #define CONFIG_FB_OC_SHMEM_SIZE 0 #endif /* CONFIG_FB_OC_SHMEM_SIZE */ /* min_low_pfn points to the start of DRAM, start_pfn points * to the first DRAM pages after the kernel, and max_low_pfn * to the end of DRAM. Partial pages are not useful, so round it * down. */ start_pfn = PFN_UP(__pa(&_end)); max_low_pfn = PFN_DOWN(CONFIG_OR32_MEMORY_SIZE -CONFIG_FB_OC_SHMEM_SIZE -CONFIG_OR32_RESERVED_MEM_SIZE); min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT; #undef CONFIG_FB_OC_SHMEM_SIZE /* * set the beginning of frame buffer */ fb_mem_start = PFN_PHYS(max_low_pfn); /* * initialize the boot-time allocator (with low memory only) */ bootmap_size = init_bootmem(start_pfn, max_low_pfn); free_bootmem(PFN_PHYS(start_pfn), PFN_PHYS(max_low_pfn - start_pfn)); reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); return(max_low_pfn); }
static void __init setup_memory(void) { unsigned long bootmap_size; unsigned long start_pfn, end_pfn; int i; /* * partially used pages are not usable - thus * we are rounding upwards: */ start_pfn = PFN_UP(__pa(&_end)); end_pfn = max_pfn = PFN_DOWN(memory_end); #ifdef CONFIG_BLK_DEV_INITRD /* * Move the initrd in case the bitmap of the bootmem allocater * would overwrite it. */ if (INITRD_START && INITRD_SIZE) { unsigned long bmap_size; unsigned long start; bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1); bmap_size = PFN_PHYS(bmap_size); if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) { start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE; if (start + INITRD_SIZE > memory_end) { pr_err("initrd extends beyond end of " "memory (0x%08lx > 0x%08lx) " "disabling initrd\n", start + INITRD_SIZE, memory_end); INITRD_START = INITRD_SIZE = 0; } else { pr_info("Moving initrd (0x%08lx -> " "0x%08lx, size: %ld)\n", INITRD_START, start, INITRD_SIZE); memmove((void *) start, (void *) INITRD_START, INITRD_SIZE); INITRD_START = start; } } } #endif /* * Initialize the boot-time allocator */ bootmap_size = init_bootmem(start_pfn, end_pfn); /* * Register RAM areas with the bootmem allocator. */ for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { unsigned long start_chunk, end_chunk, pfn; if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; start_chunk = PFN_DOWN(memory_chunk[i].addr); end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size); end_chunk = min(end_chunk, end_pfn); if (start_chunk >= end_chunk) continue; add_active_range(0, start_chunk, end_chunk); pfn = max(start_chunk, start_pfn); for (; pfn < end_chunk; pfn++) page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY, 0); } psw_set_key(PAGE_DEFAULT_KEY); free_bootmem_with_active_regions(0, max_pfn); /* * Reserve memory used for lowcore/command line/kernel image. */ reserve_bootmem(0, (unsigned long)_ehead, BOOTMEM_DEFAULT); reserve_bootmem((unsigned long)_stext, PFN_PHYS(start_pfn) - (unsigned long)_stext, BOOTMEM_DEFAULT); /* * Reserve the bootmem bitmap itself as well. We do this in two * steps (first step was init_bootmem()) because this catches * the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size, BOOTMEM_DEFAULT); #ifdef CONFIG_BLK_DEV_INITRD if (INITRD_START && INITRD_SIZE) { if (INITRD_START + INITRD_SIZE <= memory_end) { reserve_bootmem(INITRD_START, INITRD_SIZE, BOOTMEM_DEFAULT); initrd_start = INITRD_START; initrd_end = initrd_start + INITRD_SIZE; } else { pr_err("initrd extends beyond end of " "memory (0x%08lx > 0x%08lx) " "disabling initrd\n", initrd_start + INITRD_SIZE, memory_end); initrd_start = initrd_end = 0; } } #endif }
static inline void bootmem_init(void) { #ifdef CONFIG_BLK_DEV_INITRD unsigned long tmp; unsigned long *initrd_header; #endif unsigned long bootmap_size; unsigned long start_pfn, max_pfn; int i; #ifdef CONFIG_BLK_DEV_INITRD tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; if (tmp < (unsigned long)&_end) tmp += PAGE_SIZE; initrd_header = (unsigned long *)tmp; if (initrd_header[0] == 0x494E5244) { initrd_start = (unsigned long)&initrd_header[2]; initrd_end = initrd_start + initrd_header[1]; } start_pfn = PFN_UP(CPHYSADDR((&_end)+(initrd_end - initrd_start) + PAGE_SIZE)); #else /* * Partially used pages are not usable - thus * we are rounding upwards. */ start_pfn = PFN_UP(CPHYSADDR(&_end)); #endif /* CONFIG_BLK_DEV_INITRD */ #ifndef CONFIG_SGI_IP27 /* Find the highest page frame number we have available. */ max_pfn = 0; 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 (start >= end) continue; if (end > max_pfn) max_pfn = end; } /* Initialize the boot-time allocator. */ bootmap_size = init_bootmem(start_pfn, max_pfn); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long curr_pfn, last_pfn, size; /* * Reserve usable memory. */ if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; /* * We are rounding up the start address of usable memory: */ curr_pfn = PFN_UP(boot_mem_map.map[i].addr); if (curr_pfn >= max_pfn) continue; if (curr_pfn < start_pfn) curr_pfn = start_pfn; /* * ... and at the end of the usable range downwards: */ last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); if (last_pfn > max_pfn) last_pfn = max_pfn; /* * ... finally, did all the rounding and playing * around just make the area go away? */ if (last_pfn <= curr_pfn) continue; size = last_pfn - curr_pfn; free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); } /* Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); #endif #ifdef CONFIG_BLK_DEV_INITRD /* Board specific code should have set up initrd_start and initrd_end */ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); if (&__rd_start != &__rd_end) { initrd_start = (unsigned long)&__rd_start; initrd_end = (unsigned long)&__rd_end; } initrd_below_start_ok = 1; if (initrd_start) { unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); printk("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *)initrd_start, initrd_size); /* FIXME: is this right? */ #ifndef CONFIG_SGI_IP27 if (CPHYSADDR(initrd_end) > PFN_PHYS(max_pfn)) { printk("initrd extends beyond end of memory " "(0x%p > 0x%p)\ndisabling initrd\n", (void *)CPHYSADDR(initrd_end), (void *)PFN_PHYS(max_pfn)); initrd_start = 0; } #endif /* !CONFIG_SGI_IP27 */ } #endif }
void bootmem_init(void) { #ifdef CONFIG_BLK_DEV_INITRD unsigned long tmp; unsigned long *initrd_header; #endif unsigned long bootmap_size; unsigned long start_pfn, max_pfn; int i; extern int _end; #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define PFN_PHYS(x) ((x) << PAGE_SHIFT) /* * Partially used pages are not usable - thus * we are rounding upwards. * start_pfn = PFN_UP(__pa(&_end)); */ start_pfn = PFN_UP((unsigned long)&_end - KSEG0); /* Find the highest page frame number we have available. */ max_pfn = 0; 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 (start >= end) continue; if (end > max_pfn) max_pfn = end; } /* Initialize the boot-time allocator. */ bootmap_size = init_bootmem(start_pfn, max_pfn); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long curr_pfn, last_pfn, size; /* * Reserve usable memory. */ if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; /* * We are rounding up the start address of usable memory: */ curr_pfn = PFN_UP(boot_mem_map.map[i].addr); if (curr_pfn >= max_pfn) continue; if (curr_pfn < start_pfn) curr_pfn = start_pfn; /* * ... and at the end of the usable range downwards: */ last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); if (last_pfn > max_pfn) last_pfn = max_pfn; /* * ... finally, did all the rounding and playing * around just make the area go away? */ if (last_pfn <= curr_pfn) continue; size = last_pfn - curr_pfn; free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); } /* Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); #ifdef CONFIG_BLK_DEV_INITRD #error "Initrd is broken, please fit it." tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; if (tmp < (unsigned long)&_end) tmp += PAGE_SIZE; initrd_header = (unsigned long *)tmp; if (initrd_header[0] == 0x494E5244) { initrd_start = (unsigned long)&initrd_header[2]; initrd_end = initrd_start + initrd_header[1]; initrd_below_start_ok = 1; if (initrd_end > memory_end) { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", initrd_end,memory_end); initrd_start = 0; } else *memory_start_p = initrd_end; } #endif #undef PFN_UP #undef PFN_DOWN #undef PFN_PHYS }
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(); }