Vmalloc

vmalloc(见mm/vmalloc.c文件)的目的是供内核分配在虚拟空间必须是连续的大块内存(物理地址不要求连续),其所占用的地址范围是特定于平台的常数VMALLOC_START和VMALLOC_END定义的(x86-64架构是0xffffc20000000000至0xffffe1ffffffffff之间的32TB,IA-64架构则开始于0xa000000200000000)。因为32位平台的虚拟内存只有4G,资源比较紧张(和64位平台相比),所以一般没有专门划出一个区段(区段的概念来自IA-64的8个区段)供vmalloc使用。落实到i386上,VMALLOC_START一般紧接着物理内存在内核一对一映射段(也就是3G--3G+物理内存)的后面(两者间有个8M的空洞,由VMALLOC_OFFSET变量表示。

在i386平台,VMALLOC_START和VMALLOC_END的值随着内核是否配置成支持高位空间而有所不同。arch/i386/mm/init.c

594 #ifdef CONFIG_HIGHMEM
595 high_memory = (void *) __va(highstart_pfn * PAGE_SIZE);
596 #else
597 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);//与实际物理内存大小有关
598 #endif
include/asm-i386/pgtable.h
79 #define VMALLOC_OFFSET (8*1024*1024)
80 #define VMALLOC_START (((unsigned long) high_memory + vmalloc_earlyreserve + /
81 2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))//8M对齐,且有8M空洞
82 #ifdef CONFIG_HIGHMEM
83 # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
84 #else
85 # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
86 #endif

如果物理内存大于1G,必须打开选项:“高位内存”,此时high_memory为3G+896M,不考虑vmalloc_earlyreserve的话,VMALLOC_START从内核空间的896M(一对一映射段)+8M =904M地址开始,VMALLOC_END则与kmap段的首地址相差2页PAGE_SIZE(也就是说此时vmalloc所能分配的虚拟空间不足128M,要扣除4个空洞+kmap段(4M或者2M)+Fix段的大小)

4K空洞
FIXADDR_TOP
fixed_addresses
FIXADDR_START
temp fixed addresses
FIXADDR_BOOT_START
PAGE_SIZE空洞
Persistent kmap area
PKMAP_BASE
2*PAGE_SIZE空洞
VMALLOC_END
Vmalloc area
VMALLOC_START
8M+vmalloc_earlyreserve空洞
high_memory

否则,high_memory等于实际的物理内存大小,VMALLOC_START从内核空间的high_memory(一对一映射段)+8M地址开始,VMALLOC_END则与Fix段的首地址相差2页PAGE_SIZE(也不够128M,因为此时没有kmap段,所以只扣除3个空洞+Fix段的大小)。

你可能感兴趣的:(Vmalloc)