1、memblock初始化
start_kernel setup_arch(将初始化配置memblock) memblock_reserve(__pa_symbol(_text),(unsigned long)__end_of_kernel_reserve -(unsigned long)_text);(预留代码段) memblock_add_range(将该区间的物理内存添加到memblock.reserved里) memblock_reserve(0, PAGE_SIZE);(预留第一个page size) early_reserve_initrd memblock_reserve(预留ramdisk) e820__memory_setup memory_setup e820__memory_setup_default e820__update_table(通过e820将bios传递下来的物理内存信息保存到e820_table里) e820__print_table(打印e820_table的内存信息) e820__memblock_setup memblock_add(将e820_table的内存信息保存到memblock.memory里) pagetable_init native_pagetable_init paging_init zone_sizes_init(设置每个zone的最大内存范围) free_area_init_nodes find_min_pfn_with_active_regions(先找到注册好的start_pfn) find_zone_movable_pfns_for_nodes(如果cmdline有配置movable zone,则将hotplug的内存添加到movable zone里) free_area_init_node(初始化每个node的pgdat) calculate_node_totalpages(计算node的总内存) for (i = 0; i < MAX_NR_ZONES; i++) (设置每个zone的内存区域) zone_spanned_pages_in_node(将该ndoe的内存先存放到movable zone里,其余的zone的内存初始是没有内存的,后面分配的时候才从movable里申请再填充到对应的zone里) alloc_node_mem_map(分配pgdat->node_mem_map,node_mem_map用来存放page数据结构信息的,通过pgdat->node_mem_map物理页框和page映射) free_area_init_core for (j = 0; j < MAX_NR_ZONES; j++)(对node的每个zone配置) set_pageblock_order(设置pageblock大小) memmap_init memmap_init_zone(将每个zone的物理内存划分成page管理) __init_single_page set_pageblock_migratetype(page, MIGRATE_MOVABLE); (初始化所有的内存为movable migrate type)
2、释放memblock到buddy
mm_init(memblock释放到buddy) memblock_free_all free_low_memory_core_early for_each_free_mem_range(将memblock.memory的每个内存区域释放到buddy里) __free_memory_core __free_pages_memory memblock_free_pages __free_pages_core __free_pages_ok free_one_page free_one_page(page_zone(page), page, pfn, order, migratetype); (将page添加到对应zone的migrate type里,初始化migrate type为movable) __mod_zone_freepage_state __mod_zone_page_state zone_page_state_add(更新zone->vm_stat[NR_FREE_PAGES]的free page计数信息) add_to_free_area (将物理内存添加到zone->free_area里)
3、总结:
1)、从bios里获取内存信息到e820表上;
2)、setup_arch里,初始化每个node的zone内存区域;一开始的时候,只有movable里有内存;
3)、mm_init里,将memblock的内存释放到movable zone的free_area里;