节点和管理区是内存管理中所涉及的重要概念,其数据结构在前文《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:
");
- for (i = 0; i < MAX_NR_ZONES; i++) {
- if (i == ZONE_MOVABLE)
- continue;
- printk(" %-8s %0#10lx -> %0#10lx
",
- 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
");
- for (i = 0; i < MAX_NUMNODES; i++) {
- if (zone_movable_pfn[i])
- printk(" Node %d: %lu
", i, zone_movable_pfn[i]);
- }
-
- /* Print out the early_node_map[] */
- printk("early_node_map[%d] active PFN ranges
", nr_nodemap_entries);
- for (i = 0; i < nr_nodemap_entries; i++)
- printk(" %3d: %0#10lx -> %0#10lx
", 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);
- }
- }
关于 Ubuntu 设置静态IP的问题Ubuntu下安装JDK/JRE及问题的解决相关资讯 Linux入门教程
- Linux入门教程:/var/spool/ (02月01日)
- Linux入门教程:如何使用终端安装 (09/16/2015 19:26:13)
- Linux入门教程:Ubuntu笔记本屏幕 (03/16/2015 21:39:15)
| - Linux操作系统入门教程 PDF (12/20/2015 15:38:25)
- Linux操作系统入门教程 (07/31/2015 06:59:53)
- Linux入门教程:如何检查Linux系统 (09/12/2014 11:57:54)
|
本文评论 查看全部评论 (0)