I thought Linux fixed highmem zone and low mem zone at the compile time. But, I was wrong. I even found the command line parameter named ‘highmem=’ which can set the highmem size.
Actually, this calculation is done during the initialization and following is the code which actually do the thing.
895/* 896 * Determine low and high memory ranges: 897 */ 898unsigned long __init find_max_low_pfn(void) 899{ 900 unsigned long max_low_pfn; 901 902 max_low_pfn = max_pfn; 903 if (max_low_pfn > MAXMEM_PFN) { 904 if (highmem_pages == -1) 905 highmem_pages = max_pfn - MAXMEM_PFN; 906 if (highmem_pages + MAXMEM_PFN < max_pfn) 907 max_pfn = MAXMEM_PFN + highmem_pages; 908 if (highmem_pages + MAXMEM_PFN > max_pfn) { 909 printk("only %luMB highmem pages available, ignoring highmem size of %uMB.n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages)); 910 highmem_pages = 0; 911 } 912 max_low_pfn = MAXMEM_PFN; 913#ifndef CONFIG_HIGHMEM 914 /* Maximum memory usable is what is directly addressable */ 915 printk(KERN_WARNING "Warning only %ldMB will be used.n", 916 MAXMEM>>20); 917 if (max_pfn > MAX_NONPAE_PFN) 918 printk(KERN_WARNING "Use a PAE enabled kernel.n"); 919 else 920 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.n"); 921 max_pfn = MAXMEM_PFN; 922#else /* !CONFIG_HIGHMEM */ 923#ifndef CONFIG_X86_PAE 924 if (max_pfn > MAX_NONPAE_PFN) { 925 max_pfn = MAX_NONPAE_PFN; 926 printk(KERN_WARNING "Warning only 4GB will be used.n"); 927 printk(KERN_WARNING "Use a PAE enabled kernel.n"); 928 } 929#endif /* !CONFIG_X86_PAE */ 930#endif /* !CONFIG_HIGHMEM */ 931 } else { 932 if (highmem_pages == -1) 933 highmem_pages = 0; 934#ifdef CONFIG_HIGHMEM 935 if (highmem_pages >= max_pfn) { 936 printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn)); 937 highmem_pages = 0; 938 } 939 if (highmem_pages) { 940 if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){ 941 printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.n", pages_to_mb(highmem_pages)); 942 highmem_pages = 0; 943 } 944 max_low_pfn -= highmem_pages; 945 } 946#else 947 if (highmem_pages) 948 printk(KERN_ERR "ignoring highmem size on non-highmem kernel!n"); 949#endif 950 } 951 return max_low_pfn; 952}
Leave a Reply