5.2.2 获得总页面数
回到setup_arch()中,接下来,继续走,891行调用e820_end_of_ram_pfn()函数根据e820的数据来获得32位可用物理内存地址的最大值并右移PAGE_SHIFT,也就是12位,最后由函数e820_end_pfn返回这个20位的值,保存在内部变量max_pfn中,作为总的页面数量:
855static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) 856{ 857 int i; 858 unsigned long last_pfn = 0; 859 unsigned long max_arch_pfn = MAX_ARCH_PFN; 860 861 for (i = 0; i < e820.nr_map; i++) { 862 struct e820entry *ei = &e820.map[i]; 863 unsigned long start_pfn; 864 unsigned long end_pfn; 865 866 if (ei->type != type) 867 continue; 868 869 start_pfn = ei->addr >> PAGE_SHIFT; 870 end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; 871 872 if (start_pfn >= limit_pfn) 873 continue; 874 if (end_pfn > limit_pfn) { 875 last_pfn = limit_pfn; 876 break; 877 } 878 if (end_pfn > last_pfn) 879 last_pfn = end_pfn; 880 } 881 882 if (last_pfn > max_arch_pfn) 883 last_pfn = max_arch_pfn; 884 885 printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx/n", 886 last_pfn, max_arch_pfn); 887 return last_pfn; 888} 889unsigned long __init e820_end_of_ram_pfn(void) 890{ 891 return e820_end_pfn(MAX_ARCH_PFN, E820_RAM); 892} |
紧接着,setup_arch的第902行调用find_low_pfn_range(),它根据max_pfn是否大于MAXMEM_PFN来判断是否启用了高端内存区。这个MAXMEM_PFN值等于多少,大家自己去查,不是很复杂,只是这个值跟max_pfn一样,也是除去低12位的20位的一个数值。如果启用了,就调用highmem_pfn_init()函数将全局变量max_low_pfn设置为MAXMEM_PFN;并设置全局变量highmem_pages为max_pfn - MAXMEM_PFN,作为高端页面的数量:
660void __init highmem_pfn_init(void) 661{ 662 max_low_pfn = MAXMEM_PFN; 663 664 if (highmem_pages == -1) 665 highmem_pages = max_pfn - MAXMEM_PFN; 666 667 if (highmem_pages + MAXMEM_PFN < max_pfn) 668 max_pfn = MAXMEM_PFN + highmem_pages; 669 670 if (highmem_pages + MAXMEM_PFN > max_pfn) { 671 printk(KERN_WARNING MSG_HIGHMEM_TOO_SMALL, 672 pages_to_mb(max_pfn - MAXMEM_PFN), 673 pages_to_mb(highmem_pages)); 674 highmem_pages = 0; 675 } …… 692} |