Chapter3:MemoryManagement
Two pre-processor symbols are important in this context:__VMALLOC_RESERVEsets the size of thevmalloc
area, andMAXMEMdenotes the maximum possible amount of physical RAM that can be directly addressed
by the kernel.
The splitting of memory into the individual areas is controlled by means of the constants shown in Figure
3-15. The constants may have different values depending on the kernel and system configuration. The
bound of the direct mappings is specified byhigh_memory.
arch/x86/kernel/setup_32.c
static unsigned long __init setup_memory(void)
{
...
#ifdef CONFIG_HIGHMEM
high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
#else
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
#endif
...
}
max_low_pfnspecifies the number of memory pages present on systems with less than 896 MiB. The
value is also limited upwards to the maximum number of pages that fit in 896 MiB (the exact calculation is
given infind_max_low_pfn). If highmem support is enabled,high_memoryindicates the bound between
two memory areas, which is always at 896 MiB.
There is a gap with a minimum size ofVMALLOC_OFFSETbetween the direct mapping of all RAM pages
and the area for non-contiguous allocations.
include/asm-x86/pgtable_32.h
#define VMALLOC_OFFSET (8*1024*1024)
This gap acts as a safeguard against any kernel faults. Ifout of boundaddresses are accessed (these are
unintentional accesses to memory areas that are no longer physically present), access fails and an excep-
tion is generated to report the error. If the vmalloc area were to immediately follow the direct mappings,
access would be successful and the error would not be noticed. There should be no need for this addi-
tional safeguard in stable operation, but it is useful when developing new kernel features that are not yet
mature.
VMALLOC_STARTandVMALLOC_ENDdefine the start and end of the vmalloc area used for physically non-
contiguous kernel mappings. The values are not defined directly as constants but depend on several
parameters.
include/asm-x86/pgtable_32.h
#define VMALLOC_START (((unsigned long) high_memory + \
2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))
#ifdef CONFIG_HIGHMEM
# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
#else
# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
#endif