Linux内存模型之bootmem分配器一

简介:bootmem分配器是系统启动初期的内存分配方式,在耳熟能详的伙伴系统,slab系统建立前内存都是利用bootmem分配器来分配的,伙伴系统框架建立起来后,bootmem会过度到伙伴系统,bootmem大致思想就是收集内存中的可用内存,然后建立bit位图,然后需要的内存从这些空闲内存中分配,分配了就标记占用,当然这种分配方式很低效,但是由于只占用启动阶段很少一部分,所以也大可接受了,好了,废话不多说,,一起看代码吧,

相关阅读:一、初始化部分init/main.c中start_kernel函数{ … setup_arch(&command_line); …}代码位于arch/arm/kernel/setup.c中,void __init setup_arch(char **cmdline_p){…paging_init(mdesc);…}

******************************************************** 继续跟进paging_init函数在arch/arm/mm/mmu.c中* *******************************************************

/** paging_init() sets up the page tables, initialises the zone memory* maps, and sets up the zero page, bad page and bad page tables.*/void __init paging_init(struct machine_desc *mdesc){ void *zero_page; memblock_set_current_limit(lowmem_limit); build_mem_type_table(); prepare_page_table(); map_lowmem(); devicemaps_init(mdesc); kmap_init(); top_pmd = pmd_off_k(0xffff0000); /* allocate the zero page. */ zero_page = early_alloc(PAGE_SIZE); bootmem_init(); empty_zero_page = virt_to_page(zero_page); __flush_dcache_page(NULL, empty_zero_page);

}

find_limits(&min, &max_low, &max_high); //arm bootmem初始化 arm_bootmem_init(min, max_low); /* * Sparsemem tries to allocate bootmem in memory_present(), * so must be done after the fixed reservations */ arm_memory_present(); /* * sparse_init() needs the bootmem allocator up and running. */ sparse_init(); /* * Now free the memory – free_area_init_node needs * the sparse mem_map arrays initialized by sparse_init() * for memmap_init_zone(), otherwise all PFNs are invalid. */ arm_bootmem_free(min, max_low, max_high); high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) – 1) + 1; /* * This doesn’t seem to be used by the Linux memory manager any * more, but is used by ll_rw_block. If we can get rid of it, we * also get rid of some of the stuff above as well. * * Note: max_low_pfn and max_pfn reflect the number of _pages_ in * the system, not the maximum PFN. */ max_low_pfn = max_low – PHYS_PFN_OFFSET; max_pfn = max_high – PHYS_PFN_OFFSET;}******************************************************** 这里的函数需要一个一个的过一下,先看这个* find_limits(&min, &max_low, &max_high)函数* 同文件夹下*******************************************************static void __init find_limits(unsigned long *min, unsigned long *max_low, unsigned long *max_high){ struct meminfo *mi = &meminfo; //内存bank的表述结构 int i; *min = -1UL; *max_low = *max_high = 0; for_each_bank (i, mi) { struct membank *bank = &mi->bank[i]; unsigned long start, end; start = bank_pfn_start(bank); end = bank_pfn_end(bank); if (*min > start) *min = start; //保证min最后是最小值 if (*max_high < end) //保证最后的max_high是最大值 *max_high = end; if (bank->highmem) //如果bank是高端内存那么不再标记max_low continue; if (*max_low < end) //如果是普通内存,那么max_low继续跟着增大 *max_low = end; }}

你可以用爱得到全世界,你也可以用恨失去全世界

Linux内存模型之bootmem分配器一

相关文章:

你感兴趣的文章:

标签云: