Linux节点和内存管理区的初始化
Linux节点和内存管理区的初始化
节点和管理区是内存管理中所涉及的重要概念,其数据结构在前文《linux物理内存概述》中已经介绍,现在让我们来看看linux是如何完成节点和管理区的。
在内核首先通过setup_arch()-->paging_init()-->zone_sizes_init()来初始化节点和管理区的一些数据项
- static 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;
- #endif
- free_area_init_nodes(max_zone_pfns);
- }
在获取了三个管理区的页面数后,通过free_area_init_nodes()来完成后续工作
- void __init free_area_init_nodes(unsigned long *max_zone_pfn)
- {
- unsigned long nid;
- int i;
- /* Sort early_node_map as initialisation assumes it is sorted */
- sort_node_map();/*将所有节点按起始页框号排序*/
- /* Record where the zone boundaries are */
- /*记录三个管理区的边界*/
- memset(arch_zone_lowest_possible_pfn, 0,
- sizeof(arch_zone_lowest_possible_pfn));
- memset(arch_zone_highest_possible_pfn, 0,
- sizeof(arch_zone_highest_possible_pfn));
- arch_zone_lowest_possible_pfn[0] = find_min_pfn_with_active_regions();
- arch_zone_highest_possible_pfn[0] = max_zone_pfn[0];
- for (i = 1; i < MAX_NR_ZONES; i++) {
- if (i == ZONE_MOVABLE) /*不处理ZONE_MOVABLE*/
- continue;
- /*将下一个管理区的起始页框置为上一个管理区的结束页框*/
- arch_zone_lowest_possible_pfn[i] =
- arch_zone_highest_possible_pfn[i-1];
- arch_zone_highest_possible_pfn[i] =
- max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]);
- }
- arch_zone_lowest_possible_pfn[ZONE_MOVABLE] = 0;
- arch_zone_highest_possible_pfn[ZONE_MOVABLE] = 0;
- /* Find the PFNs that ZONE_MOVABLE begins at in each node */
- memset(zone_movable_pfn, 0, sizeof(zone_movable_pfn));
- find_zone_movable_pfns_for_nodes(zone_movable_pfn);
- /* Print out the zone ranges */
- printk("Zone PFN ranges:\n");
- for (i = 0; i < MAX_NR_ZONES; i++) {
- if (i == ZONE_MOVABLE)
- continue;
- printk(" %-8s %0#10lx -> %0#10lx\n",
- zone_names[i],
- arch_zone_lowest_possible_pfn[i],
- arch_zone_highest_possible_pfn[i]);
- }
- /* Print out the PFNs ZONE_MOVABLE begins at in each node */
- printk("Movable zone start PFN for each node\n");
- for (i = 0; i < MAX_NUMNODES; i++) {
- if (zone_movable_pfn[i])
- printk(" Node %d: %lu\n", i, zone_movable_pfn[i]);
- }
- /* Print out the early_node_map[] */
- printk("early_node_map[%d] active PFN ranges\n", nr_nodemap_entries);
- for (i = 0; i < nr_nodemap_entries; i++)
- printk(" %3d: %0#10lx -> %0#10lx\n", early_node_map[i].nid,
- early_node_map[i].start_pfn,
- early_node_map[i].end_pfn);
- /* Initialise every node */
- mminit_verify_pageflags_layout();
- setup_nr_node_ids();
- for_each_online_node(nid) {/*遍历每个节点*/
- pg_data_t *pgdat = NODE_DATA(nid);
- /*初始化节点*/
- free_area_init_node(nid, NULL,
- find_min_pfn_for_node(nid), NULL);
- /* Any memory on that node */
- if (pgdat->node_present_pages)
- node_set_state(nid, N_HIGH_MEMORY);
- check_for_regular_memory(pgdat);
- }
- }
|
评论暂时关闭