首页 技术 正文
技术 2022年11月9日
0 收藏 381 点赞 2,924 浏览 2814 个字

  我们在阅读源码时,函数功能可以分为两类:1. bootmem.c 2. page_alloc.c。

  1. bootmem.c是关于bootmem allocator的,上篇文章已经简述过。

  2. page_alloc.c是关于Memory Management subsystem的。

  关于内存管理子系统的初始化调用了多个函数,我们首先分析在bootmem_init中调用的add_active_range函数。

  start_kernel –> setup_arch —> arch_mem_init —> bootmem_init —> add_active_range.

  通过上述分析,我们此时可以确认内存信息,那么我们确认的内存信息必然要告诉Memory Management subsystem,首先通过add_active_range完成。

  调用两次add_active_range:

    1. add_active_range(0, start, end);     // start = 0, end = 57344

    2. add_active_range(0, start, end);     // start = 196608, end = 262144

/**
* add_active_range - Register a range of PFNs backed by physical memory 【注册物理内存的PFN范围】
* @nid: The node ID the range resides on
* @start_pfn: The start PFN of the available physical memory
* @end_pfn: The end PFN of the available physical memory
* @id :    该物理内存所属的内存结点。由于我们是UMA系统,只用一个内存结点,所以我们在调用时,传入的参数为0.
* @start_pfn: 可用物理内存的开始PFN号
* @end_pfn: 可用屋里内存的结束PFN号
* These ranges are stored in an early_node_map[] and later used by
* free_area_init_nodes() to calculate zone sizes and holes. If the
* range spans a memory hole, it is up to the architecture to ensure
* the memory is not freed by the bootmem allocator. If possible
* the range being registered will be merged with existing ranges.
* 传入的物理内存信息存储到一个数组中:early_node_map[], 稍后会在 free_area_init_nodes() 函数中使用,用来计算 zone sizes 和 holes。
* 如果物理内存的范围包含一个 memory hole,it is up to the architecture to ensure the memory is not freed by the bootmem allocator.
* 新注册的物理内存范围会Merge到已经存在的物理内存范围中去。
*/
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); mminit_validate_memmodel_limits(&start_pfn, &end_pfn); // 对start_pfn 和 end_pfn 做某些验证,我们不Care /* Merge with existing active regions if possible */
for (i = ; 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].start_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 */ // earlay_node_map数组有上限
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 + ;
  /*
    early_node_map[0].nid = 0;
    early_node_map[0].start_pfn = 0;
    early_node_map[0].end_pfn = 57344;
    early_node_map[1].nid = 0;
    early_node_map[1].start_pfn = 196608;
    early_node_map[1].end_pfn = 262144;    很好理解,不啰嗦了!!!
  */
}

  总结:我们在从command_line中确定了屋里内存信息后,这是第一个把这个好消息告诉了buddy system。所以,一定要记住这个关键的数组——>early_node_map.

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297