获得总页面数

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_pagesmax_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}

 

你可能感兴趣的:(struct)