8.注册内存区,用于后面初始化内存域和结点(zone_sizes_init)

内存域数据结构的初始化工作涉及颇广。幸运的是,该任务在所有体系结构上都是相同的。虽然在2.6.19之前的内核版本必须根据不同的体系结构来建立所需的数据结构,但具体的方法随时间的推移已经越来越模块化。各个体系结构只须注册所有活动内存区的一个简单表,通用代码则据此生成主数据结构。
任何一个体系结构,如果打算利用内核提供的一般性框架,则需要设置配置选项ARCH_POPULATES_NODE_MAP。在注册所有活动内存区之后,其余的工作由通用的内核代码完成。
活动内存区就是不包含空洞的内存区。必须使用add_active_range在全局变量early_node_map中注册内存区。
 
mm/page_alloc.c
static struct node_active_region __meminitdata early_node_map[MAX_ACTIVE_REGIONS];
static int __meminitdata nr_nodemap_entries;

 

 
当前注册的内存区数目记载在nr_nodemap_entries中。不同内存区的最大数目由MAX_ACTIVE_REGIONS给出。该值可以由特定于体系结构的代码使用CONFIG_MAX_ACTIVE_REGIONS设置。如果不设
置,在默认情况下内核允许每个内存结点注册256个活动内存区(如果在超过32个结点的系统上,允许每个NUMA结点注册50个内存区)。每个内存区由下列数据结构描述:
 
<mmzone.h>
struct node_active_region {
  unsigned long start_pfn;
  unsigned long end_pfn;
  int nid;
};

 

 
start_pfn和end_pfn标记了一个连续内存区中的第一个和最后一个页帧,nid是该内存区所属结点的NUMA ID。UMA系统设置为0。活动内存区是使用add_active_range注册的:
 
mm/page_alloc.c
void __init add_active_range(unsigned int nid, unsigned long start_pfn,unsigned long end_pfn)

 

 
在注册两个毗邻的内存区时,add_active_regions会确保将它们合并为一个。此外,该函数不提供其他额外的功能特性。
该函数在IA-32系统上由zone_sizes_init调用,
除了调用add_active_range之外,zone_sizes_init函数以页帧为单位,存储了不同内存区的边界。
 
arch/x86/kernel/setup_32.c
void __init zone_sizes_init(void)
{
  unsigned long max_zone_pfns[MAX_NR_ZONES];
  memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
  max_zone_pfns[ZONE_DMA] =virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
  max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
#ifdef CONFIG_HIGHMEM
  max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
  add_active_range(0, 0, highend_pfn);
#else
  add_active_range(0, 0, max_low_pfn);
#endif
  free_area_init_nodes(max_zone_pfns);
}

 

MAX_DMA_ADDRESS是适用于DMA操作的最高内存地址。该常数声明为PAGE_OFFSET+0x1000000。物理内存页映射到从PAGE_OFFSET开始的虚拟地址空间,而物理内存的前16 MiB适合于DMA操作,十六进制表示就是前0x1000000字节。用virt_to_phys转换,可以获得物理内存地址,而右移PAGE_SHIFT位则相当于除以页大小,计算最后得到适用于DMA的页数。不出意料之外,在使用4 KiB页的IA-32系统上,结果是4 096页。
max_low_pfn和highend_pfn是全局常量,分别指定了低端(如果地址空间按3∶1划分,通常≤896 MiB)和高端内存中最高的页号。
请注意,free_area_init_nodes会合并early_mem_map和max_zone_pfns中的信息。其分别选择各个内存域中的活动内存区,并构建体系结构无关的数据结构。
posted @ 2022-03-20 16:43  while(true);;  阅读(84)  评论(0)    收藏  举报