歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux節點和內存管理區的初始化

Linux節點和內存管理區的初始化

日期:2017/2/28 15:51:36   编辑:Linux教程

節點和管理區是內存管理中所涉及的重要概念,其數據結構在前文《linux物理內存概述》中已經介紹,現在讓我們來看看linux是如何完成節點和管理區的。

在內核首先通過setup_arch()-->paging_init()-->zone_sizes_init()來初始化節點和管理區的一些數據項

  1. static void __init zone_sizes_init(void)
  2. {
  3. unsigned long max_zone_pfns[MAX_NR_ZONES];
  4. memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
  5. /*分別獲取三個管理區的頁面數*/
  6. max_zone_pfns[ZONE_DMA] =
  7. virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
  8. max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
  9. #ifdef CONFIG_HIGHMEM
  10. max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
  11. #endif
  12. free_area_init_nodes(max_zone_pfns);
  13. }

在獲取了三個管理區的頁面數後,通過free_area_init_nodes()來完成後續工作

  1. void __init free_area_init_nodes(unsigned long *max_zone_pfn)
  2. {
  3. unsigned long nid;
  4. int i;
  5. /* Sort early_node_map as initialisation assumes it is sorted */
  6. sort_node_map();/*將所有節點按起始頁框號排序*/
  7. /* Record where the zone boundaries are */
  8. /*記錄三個管理區的邊界*/
  9. memset(arch_zone_lowest_possible_pfn, 0,
  10. sizeof(arch_zone_lowest_possible_pfn));
  11. memset(arch_zone_highest_possible_pfn, 0,
  12. sizeof(arch_zone_highest_possible_pfn));
  13. arch_zone_lowest_possible_pfn[0] = find_min_pfn_with_active_regions();
  14. arch_zone_highest_possible_pfn[0] = max_zone_pfn[0];
  15. for (i = 1; i < MAX_NR_ZONES; i++) {
  16. if (i == ZONE_MOVABLE) /*不處理ZONE_MOVABLE*/
  17. continue;
  18. /*將下一個管理區的起始頁框置為上一個管理區的結束頁框*/
  19. arch_zone_lowest_possible_pfn[i] =
  20. arch_zone_highest_possible_pfn[i-1];
  21. arch_zone_highest_possible_pfn[i] =
  22. max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]);
  23. }
  24. arch_zone_lowest_possible_pfn[ZONE_MOVABLE] = 0;
  25. arch_zone_highest_possible_pfn[ZONE_MOVABLE] = 0;
  26. /* Find the PFNs that ZONE_MOVABLE begins at in each node */
  27. memset(zone_movable_pfn, 0, sizeof(zone_movable_pfn));
  28. find_zone_movable_pfns_for_nodes(zone_movable_pfn);
  29. /* Print out the zone ranges */
  30. printk("Zone PFN ranges:\n");
  31. for (i = 0; i < MAX_NR_ZONES; i++) {
  32. if (i == ZONE_MOVABLE)
  33. continue;
  34. printk(" %-8s %0#10lx -> %0#10lx\n",
  35. zone_names[i],
  36. arch_zone_lowest_possible_pfn[i],
  37. arch_zone_highest_possible_pfn[i]);
  38. }
  39. /* Print out the PFNs ZONE_MOVABLE begins at in each node */
  40. printk("Movable zone start PFN for each node\n");
  41. for (i = 0; i < MAX_NUMNODES; i++) {
  42. if (zone_movable_pfn[i])
  43. printk(" Node %d: %lu\n", i, zone_movable_pfn[i]);
  44. }
  45. /* Print out the early_node_map[] */
  46. printk("early_node_map[%d] active PFN ranges\n", nr_nodemap_entries);
  47. for (i = 0; i < nr_nodemap_entries; i++)
  48. printk(" %3d: %0#10lx -> %0#10lx\n", early_node_map[i].nid,
  49. early_node_map[i].start_pfn,
  50. early_node_map[i].end_pfn);
  51. /* Initialise every node */
  52. mminit_verify_pageflags_layout();
  53. setup_nr_node_ids();
  54. for_each_online_node(nid) {/*遍歷每個節點*/
  55. pg_data_t *pgdat = NODE_DATA(nid);
  56. /*初始化節點*/
  57. free_area_init_node(nid, NULL,
  58. find_min_pfn_for_node(nid), NULL);
  59. /* Any memory on that node */
  60. if (pgdat->node_present_pages)
  61. node_set_state(nid, N_HIGH_MEMORY);
  62. check_for_regular_memory(pgdat);
  63. }
  64. }
Copyright © Linux教程網 All Rights Reserved