LINUX 内核虚拟地址空间到物理地址空间一般是固定连续影射的。
假定机器内存为512M,
从3G开始,到3G 512M 为连续固定影射区。zone_dma, zone_normal为这个区域的。固定影射的VADDR能够直接使用(get a free page, then use pfn_to_virt()等宏定义转换得到vaddr)或用kmalloc等分配. 这样的vaddr的物理页是连续的。得到的地址也一定在固定影射区域内。
假如内存紧张,连续区域无法满足,调用vmalloc分配是必须的,因为他能够将物理不连续的空间组合后分配,所以更能满足分配需要。
但vmalloc分配的vaddr一定不能和固定影射区域的vaddr重合。因为vaddr到物理页的影射同时只能唯一。所以vmalloc得到的vaddr要在3G 512m 以上才能够。也就是从VMALLOC_START开始分配。 VMALLOC_START比连续固定影射区大最大vaddr地址还多8-16M(2*VMALLOC_OFFSET)--有个鬼公式在
#define VMALLOC_OFFSET 8*1024
#define VMALLOC_START (high_memory - 2*VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)
high_memory 就是固定影射区域最高处。
空开8-16M做什么? 为了捕获越界的mm_fault.
同样,vmalloc每次得到的VADDR空间中间要留一个PAGE的空(空洞),目的和上面的空开相同。您vmalloc(100)2次,得到的2个地址中间相距8K。
假如连续分配无空洞,那么比如
p1=vmalloc(4096);
p2=vmalloc(4096);
假如p1使用越界到p2中了,也不会mm_falut. 那不容易debug.
下面说明VMALLOC_RESERVE和896M的问题。
上面假设机器物理512M的case. 假如机器有1G物理内存如何是好?那vmalloc()的vaddr是不是要在3G 1G 8M 空洞以上分配?超过寻址空间了吗。
这时,4G 下面保留的VMALLOC_RESERVER 128m 就派上用场了。
也就是说假如物理内存超过896M, high_memory也只能在3G 896地方。可寻址空间最高处要保留VMALLOC_RESREVER 128M给vmalloc用。
所以这128M的VADDR空间是为了vmalloc在物理超过了896M时候使用。假如物理仅仅有512M, 一般使用不到。因为VMALLOC_START很低了。假如vmalloc太多了才会用到。
high_memory在arch/i386/kernel, mm的初始化中配置。根据物理内存大小和VMALLOC_RESERVE得到数值.
所以说那128M仅仅是为了影射1G以上的物理内存的不对的。假如物理内存2G,1G以下的vmalloc也用那空间影射。
看vmalloc分配的东西能够用
show_vmalloc()
{
struct vm_struct **p, *tmp;
for(p = &vmlist; (tmp = *p); p = &tmp->next) {
printk("%p %p %d\n", tmp, tmp->addr, tmp->size
}
}
看到。
不全面的地方我更有补充,欢迎讨论
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



