linux内存管理之活动内存区

来源:互联网 发布:2017编程一小时 编辑:程序博客网 时间:2024/04/28 13:53

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

数据结构

struct node_active_region {unsigned long start_pfn;unsigned long end_pfn;int nid;};

初始化

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

/* Walk the e820 map and register active regions within a node */void __init e820_register_active_regions(int nid, unsigned long start_pfn, unsigned long last_pfn){unsigned long ei_startpfn;unsigned long ei_endpfn;int i;for (i = 0; i < e820.nr_map; i++)if (e820_find_active_region(&e820.map[i],/*从全局变量e820中查找活动区*/    start_pfn, last_pfn,    &ei_startpfn, &ei_endpfn))add_active_range(nid, ei_startpfn, ei_endpfn);/*加入活动区*/}
/* * Finds an active region in the address range from start_pfn to last_pfn and * returns its range in ei_startpfn and ei_endpfn for the e820 entry. */int __init e820_find_active_region(const struct e820entry *ei,  unsigned long start_pfn,  unsigned long last_pfn,  unsigned long *ei_startpfn,  unsigned long *ei_endpfn){u64 align = PAGE_SIZE;*ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;*ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;/* Skip map entries smaller than a page */if (*ei_startpfn >= *ei_endpfn)return 0;/* Skip if map is outside the node */if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||    *ei_startpfn >= last_pfn)return 0;/* Check for overlaps */if (*ei_startpfn < start_pfn)*ei_startpfn = start_pfn;if (*ei_endpfn > last_pfn)*ei_endpfn = last_pfn;return 1;}
/*添加活动区域,需要对原有的进行检查*/void __init add_active_range(unsigned int nid, unsigned long start_pfn,unsigned long end_pfn){int i;mminit_dprintk(MMINIT_TRACE, "memory_register","Entering add_active_range(%d, %#lx, %#lx) ""%d entries of %d used\n",nid, start_pfn, end_pfn,nr_nodemap_entries, MAX_ACTIVE_REGIONS);//not set macromminit_validate_memmodel_limits(&start_pfn, &end_pfn);/* Merge with existing active regions if possible */for (i = 0; i < nr_nodemap_entries; i++) {if (early_node_map[i].nid != nid)continue;/* Skip if an existing region covers this new one */if (start_pfn >= early_node_map[i].start_pfn &&end_pfn <= early_node_map[i].end_pfn)return;/* Merge forward if suitable */if (start_pfn <= early_node_map[i].end_pfn &&end_pfn > early_node_map[i].end_pfn) {early_node_map[i].end_pfn = end_pfn;return;}/* Merge backward if suitable */if (start_pfn < early_node_map[i].end_pfn &&end_pfn >= early_node_map[i].start_pfn) {early_node_map[i].start_pfn = start_pfn;return;}}/* Check that early_node_map is large enough */if (i >= MAX_ACTIVE_REGIONS) {printk(KERN_CRIT "More than %d memory regions, truncating\n",MAX_ACTIVE_REGIONS);return;}early_node_map[i].nid = nid;early_node_map[i].start_pfn = start_pfn;early_node_map[i].end_pfn = end_pfn;nr_nodemap_entries = i + 1;}
原创粉丝点击