mm_init分析(Zoned Buddy Allocator)
2010-09-15 21:36
69 查看
1 mm_init分析
file:init/main.cstart_kernel函数
{
...
setup_arch(&command_line);
//处理器相关的初始化代码,paging_init,详细见bootmem_init分析
mm_init_owner(&init_mm, &init_task);
setup_command_line(command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
build_all_zonelists(NULL);
page_alloc_init();
printk(KERN_NOTICE "Kernel command line: %s/n", boot_command_line);
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
pidhash_init();
vfs_caches_init_early();
sort_main_extable();
trap_init();
mm_init();
//当启动初始化完后,node_bootmem_map会被释放,系统初始化mem_map,
//利用struct page数据结构来管理所有的内存。
...
}
mem_init->free_all_bootmem_node->free_all_bootmem_core
//释放node_bootmem_map,使用mem_map管理物理内存,以页框为单位
static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
{
int aligned;
struct page *page;
unsigned long start, end, pages, count = 0;
if (!bdata->node_bootmem_map)
return 0;
start = bdata->node_min_pfn;
end = bdata->node_low_pfn;
/*
* If the start is aligned to the machines wordsize, we might
* be able to free pages in bulks of that order.
*/
aligned = !(start & (BITS_PER_LONG - 1));
bdebug("nid=%td start=%lx end=%lx aligned=%d/n",
bdata - bootmem_node_data, start, end, aligned);
while (start < end) {
unsigned long *map, idx, vec;
map = bdata->node_bootmem_map;
idx = start - bdata->node_min_pfn;
vec = ~map[idx / BITS_PER_LONG];
//查询改为是否为"0",当空闲时将page标志为PG_Reserved
if (aligned && vec == ~0UL && start + BITS_PER_LONG < end) {
int order = ilog2(BITS_PER_LONG);
__free_pages_bootmem(pfn_to_page(start), order);
count += BITS_PER_LONG;
} else {
unsigned long off = 0;
while (vec && off < BITS_PER_LONG) {
if (vec & 1) {
page = pfn_to_page(start + off);
__free_pages_bootmem(page, 0);
count++;
}
vec >>= 1;
off++;
}
}
start += BITS_PER_LONG;
}
page = virt_to_page(bdata->node_bootmem_map);
//得到node_bootmem_map的page地址
pages = bdata->node_low_pfn - bdata->node_min_pfn;
//得到物理内存的页框数
pages = bootmem_bootmap_pages(pages);
//node_bootmem_map共占了(
(pages/8)>>12 )页
count += pages;
while (pages--)
__free_pages_bootmem(page++, 0); //释放node_bootmem_map占用的页框
bdebug("nid=%td released=%lx/n", bdata - bootmem_node_data, count);
return count;
}
Author:Woodpecker <Pecker.hu@gmail.com>
相关文章推荐
- bootmem_init分析(Bootmem Allocator)
- 跟踪分析Linux内核的启动过程(start_kernel到init进程启动)
- Ubuntu init启动流程分析
- AndroidInitProcess分析心得(2)
- 分析Android 根文件系统启动过程(init守护进程分析)
- Android init.rc分析
- /etc/init.d/rcS内容分析
- etc/init.d/rcS内容分析
- Android源代码编译命令m/mm/mmm/make分析
- Linux驱动late_initcall和module_init相关分析
- Android init 启动过程分析
- android init.c 文件分析
- Android init 启动过程分析
- busybox init 分析
- MINI2440启动配置文件/etc/init.d/rcS文件分析
- 三星U-Boot-1.1.6源码分析lowlevel_init.S (board\samsung\smdk6410)
- Android系统init.rc分析
- android init.rc语法分析
- 【linux驱动分析】之dm9000驱动分析(六):dm9000_init和dm9000_probe的实现
- libev ev_init分析