OS detected 4194304k but only 3105024k is available.
The Theory:[32bit Linux]$ dmesg | grep -i mem3200MB HIGHMEM available.896MB LOWMEM available.HighMem zone: 819200 pages, LIFO batch:31ACPI: SRAT (v002 VMWARE MEMPLUG 0x06040000 VMW 0x00000001) @ 0xbfeef3e1Memory: 3105024k/4194304k available (1584k kernel code, 39372k reserved, 622k data, 168k init, 2228096k highmem)
[32bit Linux]$freetotal used free shared buffers cachedMem: 3108956 73076 3035880 0 8000 37932-/+ buffers/cache: 27144 3081812Swap: 779112 0 779112
hugemem/PAE enabled kernel is ONLY needed for RAM from 4GB up to 64GB, The generic 32bit Linux Kernel can see 4GB without hugemem/PAE enabled kernel.
The Cause:
Sometimes, why 32bit Linux can't see all the 4GB ram? The answer is from “physical RAM map” provided by BIOS.
The Analysis:
[32bit Linux]$dmesg | less
The interesting part of physical RAM map is the last line, and interesting number is 0000000100000000 which is hex value of 4GB.Linux version 2.6.16.60-0.21-default (geeko@buildhost) (gcc version 4.1.2 20070115 (SUSE Linux)) #1 Tue May 6 12:41:02 UTC 2008BIOS-provided physical RAM map:BIOS-e820: 0000000000000000 - 000000000009f800 (usable)BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)BIOS-e820: 00000000000ca000 - 00000000000cc000 (reserved)BIOS-e820: 00000000000dc000 - 00000000000e4000 (reserved)BIOS-e820: 00000000000e8000 - 0000000000100000 (reserved)BIOS-e820: 0000000000100000 - 00000000bfee0000 (usable)BIOS-e820: 00000000bfee0000 - 00000000bfeff000 (ACPI data)BIOS-e820: 00000000bfeff000 - 00000000bff00000 (ACPI NVS)BIOS-e820: 00000000bff00000 - 00000000c0000000 (usable)BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)BIOS-e820: 00000000fffe0000 - 0000000100000000 (reserved)BIOS-e820: 0000000100000000 - 0000000140000000 (usable)Warning only 4GB will be used.Use a PAE enabled kernel.3200MB HIGHMEM available.896MB LOWMEM available.
Converting them decimal values to be more readable.
[32bit Linux]$ dmesg | awk --re-interval --non-decimal-data '/[0-9a-z]{16}/ { x1=sprintf ("%d", "0x"$2) ; x2=sprintf ("%d", "0x"$4); printf "%d %s %d %s %d %s\n", x1/1024/1024, " - ", x2/1024/1024, "=", (x1-x2)/1024/1024,$NF }'0 - 0 = -0 (usable)0 - 0 = -0 (reserved)0 - 0 = -0 (reserved)0 - 0 = -0 (reserved)0 - 1 = -0 (reserved)1 - 3070 = -3069 (usable)3070 - 3070 = -0 data)3070 - 3071 = -0 NVS)3071 - 3072 = -1 (usable)3584 - 3840 = -256 (reserved)4076 - 4076 = -0 (reserved)4078 - 4078 = -0 (reserved)4095 - 4096 = -0 (reserved)4096 - 5120 = -1024 (usable)
It is clear that BIOS has too many reserved parts in lower address space and push the one trunk of 1GB over 4GB address space.
The Solution:
1)To release some reserved space and bring all usable spaces below 4GB, you might try to disable some devices in BIOS. It is the best option, but might not be achievable , consult with your hardware vendor.
2)Reinstall system with 64bit Kernel
3)Install hugemem/PAE kernel on current 32 Bit system. It is the last option because hugemem/PAE kernel hurt performance due to the “dynamic rempapping with three-level paging model. ”