buddy初始化

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内存区域;
3)、mm_init里,将memblock的内存释放到zone的free_area里,初始化的时候,所有内存的migrate type默认设置为movable;
4)、当其它类型的migrate type分配时会fallback到movable里,然后迁移一部分内存过去;

posted @ 2022-11-17 08:19  叫什么昵称合适  阅读(57)  评论(0)    收藏  举报