Linux arm64 bootmem_init 初始化详细分析之-sparse_init

linux内核版本:linux-4.4.y  基于arm64分析

start_kernel -> setup_arch -> paging_init -> bootmem_init -> sparse_init

推荐文章:https://blog.youkuaiyun.com/bin_linux96/article/details/83343420 Linux内存初始化之sparse内存模型(二)

                  https://blog.youkuaiyun.com/liuhangtiant/article/details/80795080 bootmem_init函数解析

 

void __init sparse_init(void)                                                                                                           
{                                                                                                                                       
    unsigned long pnum;                                                                                                                 
    struct page *map;                                                                                                                   
    unsigned long *usemap;                                                                                                              
    unsigned long **usemap_map;                                                                                                         
    int size;                                                                                                                           
#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER                                                                                          
    int size2;                                                                                                                          
    struct page **map_map;                                                                                                              
#endif                                                                                                                                  
                                                                                                                                        
    /* see include/linux/mmzone.h 'struct mem_section' definition */                                                                    
    BUILD_BUG_ON(!is_power_of_2(sizeof(struct mem_section)));                                                                           
                                                                                                                                        
    /* Setup pageblock_order for HUGETLB_PAGE_SIZE_VARIABLE */                                                                          
    set_pageblock_order();                                                                                                              
                                                                                                                                        
    /*                                                                                                                                  
     * map is using big page (aka 2M in x86 64 bit)                                                                                     
     * usemap is less one page (aka 24 bytes)                                                                                           
     * so alloc 2M (with 2M align) and 24 bytes in turn will                                                                            
     * make next 2M slip to one more 2M later.                                                                                          
     * then in big system, the memory will have a lot of holes...                                                                       
     * here try to allocate 2M pages continuously.                                                                                      
     *                                                                                                                                  
     * powerpc need to call sparse_init_one_section right after each                                                                    
     * sparse_early_mem_map_alloc, so allocate usemap_map at first.                                                                     
     */                                                                                                                                 
    size = sizeof(unsigned long *) * NR_MEM_SECTIONS;                                                                                   
    usemap_map = memblock_virt_alloc(size, 0);                                                                                          
    if (!usemap_map)                                                                                                                    
        panic("can not allocate usemap_map\n");                                                                                         
    alloc_usemap_and_memmap(sparse_early_usemaps_alloc_node,                                                                            
                            (void *)usemap_map);                                                                                        
                                                                                                                                        
#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER                                                                                          
    size2 = sizeof(struct page *) * NR_MEM_SECTIONS;                                                                                    
    map_map = memblock_virt_alloc(size2, 0);                                                                                            
    if (!map_map)                                                                                                                       
        panic("can not allocate map_map\n");                                                                                            
    alloc_usemap_and_memmap(sparse_early_mem_maps_alloc_node,                                                                           
                            (void *)map_map);                                                                                           
#endif                                                                                                                                  
                                                                                                                                        
    for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {                                                                                    
        if (!present_section_nr(pnum))                                                                                                  
            continue;                                                                                                                   
                                                                                                                                        
        usemap = usemap_map[pnum];                                                                                                      
        if (!usemap)                                                                                                                    
            continue;                                                                                                                   
                                                                                                                                        
#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER                                                                                          
        map = map_map[pnum];                                                                                                            
#else                                                                                                                                   
        map = sparse_early_mem_map_alloc(pnum);                                                                                         
#endif                                                                                                                                  
        if (!map)                                                                                                                       
            continue;                                                                                                                   
                                                                                                                                        
        sparse_init_one_section(__nr_to_section(pnum), pnum, map,                                                                       
                                usemap);                                                                                                
    }                                                                                                                                   
                                                                                                                                        
    vmemmap_populate_print_last();                                                                                                      
                                                                                                                                        
#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER                                                                                          
    memblock_free_early(__pa(map_map), size2);                                                                                          
#endif                                                                                                                                  
    memblock_free_early(__pa(usemap_map), size);                                                                                        
}                                                                                                                                       

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科技之光666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值