zoukankan      html  css  js  c++  java
  • linux内存管理之活动内存区

    Linux内存活动区域其实就是全局变量e820中的内存块做了相关的检查和对其处理后的区域。在管理区初始化等地方有用到。

    数据结构

    1. struct node_active_region {  
    2.     unsigned long start_pfn;  
    3.     unsigned long end_pfn;  
    4.     int nid;  
    5. };  

    初始化

    活动内存的初始化工作在setup_arch()->initmem_init()->e820_register_active_regions()

    1. /* Walk the e820 map and register active regions within a node */  
    2. void __init e820_register_active_regions(int nid, unsigned long start_pfn,  
    3.                      unsigned long last_pfn)  
    4. {  
    5.     unsigned long ei_startpfn;  
    6.     unsigned long ei_endpfn;  
    7.     int i;  
    8.   
    9.     for (i = 0; i < e820.nr_map; i++)  
    10.         if (e820_find_active_region(&e820.map[i],/*从全局变量e820中查找活动区*/  
    11.                         start_pfn, last_pfn,  
    12.                         &ei_startpfn, &ei_endpfn))  
    13.             add_active_range(nid, ei_startpfn, ei_endpfn);/*加入活动区*/  
    14. }  
    1. /* 
    2.  * Finds an active region in the address range from start_pfn to last_pfn and 
    3.  * returns its range in ei_startpfn and ei_endpfn for the e820 entry. 
    4.  */  
    5. int __init e820_find_active_region(const struct e820entry *ei,  
    6.                   unsigned long start_pfn,  
    7.                   unsigned long last_pfn,  
    8.                   unsigned long *ei_startpfn,  
    9.                   unsigned long *ei_endpfn)  
    10. {  
    11.     u64 align = PAGE_SIZE;  
    12.   
    13.     *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;  
    14.     *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;  
    15.   
    16.     /* Skip map entries smaller than a page */  
    17.     if (*ei_startpfn >= *ei_endpfn)  
    18.         return 0;  
    19.   
    20.     /* Skip if map is outside the node */  
    21.     if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||  
    22.                     *ei_startpfn >= last_pfn)  
    23.         return 0;  
    24.   
    25.     /* Check for overlaps */  
    26.     if (*ei_startpfn < start_pfn)  
    27.         *ei_startpfn = start_pfn;  
    28.     if (*ei_endpfn > last_pfn)  
    29.         *ei_endpfn = last_pfn;  
    30.   
    31.     return 1;  
    32. }  
    1. /*添加活动区域,需要对原有的进行检查*/  
    2. void __init add_active_range(unsigned int nid, unsigned long start_pfn,  
    3.                         unsigned long end_pfn)  
    4. {  
    5.     int i;  
    6.   
    7.     mminit_dprintk(MMINIT_TRACE, "memory_register",  
    8.             "Entering add_active_range(%d, %#lx, %#lx) "  
    9.             "%d entries of %d used\n",  
    10.             nid, start_pfn, end_pfn,  
    11.             nr_nodemap_entries, MAX_ACTIVE_REGIONS);  
    12. //not set macro   
    13.     mminit_validate_memmodel_limits(&start_pfn, &end_pfn);  
    14.   
    15.     /* Merge with existing active regions if possible */  
    16.     for (i = 0; i < nr_nodemap_entries; i++) {  
    17.         if (early_node_map[i].nid != nid)  
    18.             continue;  
    19.   
    20.         /* Skip if an existing region covers this new one */  
    21.         if (start_pfn >= early_node_map[i].start_pfn &&  
    22.                 end_pfn <= early_node_map[i].end_pfn)  
    23.             return;  
    24.   
    25.         /* Merge forward if suitable */  
    26.         if (start_pfn <= early_node_map[i].end_pfn &&  
    27.                 end_pfn > early_node_map[i].end_pfn) {  
    28.             early_node_map[i].end_pfn = end_pfn;  
    29.             return;  
    30.         }  
    31.   
    32.         /* Merge backward if suitable */  
    33.         if (start_pfn < early_node_map[i].end_pfn &&  
    34.                 end_pfn >= early_node_map[i].start_pfn) {  
    35.             early_node_map[i].start_pfn = start_pfn;  
    36.             return;  
    37.         }  
    38.     }  
    39.   
    40.     /* Check that early_node_map is large enough */  
    41.     if (i >= MAX_ACTIVE_REGIONS) {  
    42.         printk(KERN_CRIT "More than %d memory regions, truncating\n",  
    43.                             MAX_ACTIVE_REGIONS);  
    44.         return;  
    45.     }  
    46.   
    47.     early_node_map[i].nid = nid;  
    48.     early_node_map[i].start_pfn = start_pfn;  
    49.     early_node_map[i].end_pfn = end_pfn;  
    50.     nr_nodemap_entries = i + 1;  
    51. }  
  • 相关阅读:
    Your branch and 'origin/master' have diverged, and have # and # different commits each, respectively
    testng dataprovider 的几种用法以及Java中的二维数组
    python 类属性 实例属性 类方法 实例方法 静态方法(转载)
    Webdriver中PageFactory的正确用法
    Selenium webdriver在最开始打开的时候浏览器的地址栏会出现data的解决方法
    Selenium webdriver如何处理confirm对话框的问题
    SoapUI 引用第三方jar包和引用Groovy脚本
    git rebase -i 合并commit
    Git 撤销commit的注意事项
    单进程执行
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6332941.html
Copyright © 2011-2022 走看看