VMALLOC_RESERVE 和 896M
时间:2006-01-16
来源:互联网
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_RESERVE 128m 就派上用场了。
也就是说如果物理内存超过896M, high_memory也只能在3G + 896地方。可寻址空间最高处要保留VMALLOC_RESREVE 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
-
- }
- }
看到。
不全面的地方我还有补充,欢迎讨论
[ 本帖最后由 albcamus 于 2007-6-14 16:36 编辑 ]
作者: 思一克 发布时间: 2006-01-16
2.4.21内核 i386 平台上的定义:
#define VMALLOC_OFFSET (8*1024*1024)
#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \
~(VMALLOC_OFFSET-1))
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#if CONFIG_HIGHMEM
# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
#else
# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
#endif
2.6.9内核 i386 平台上的定义:
#define VMALLOC_OFFSET (8*1024*1024)
#define VMALLOC_START (((unsigned long) high_memory + vmalloc_earlyreserve + \
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
可以看一下ULK 2nd(中文版) 的图7-7。 英文版就是 Figure 7-7 了

2.6内核的对应 ULK 3rd 的Figure 8-7
[ 本帖最后由 yjh777 于 2006-1-16 17:42 编辑 ]
作者: yjh777 发布时间: 2006-01-16
谢谢。我没仔细打字,所以。。。
KMALLOC_RESERVER 应该是VMALLOC_RESERVE
本帖子就是针对你的帖子和几个人的疑问写的。对你的理解是否有帮助?
作者: 思一克 发布时间: 2006-01-16
请帮助将题目改了,KMALLOC_RESERVE 应该为VMALLOC_RESERVE
谢谢
作者: 思一克 发布时间: 2006-01-16
to yjh777.
谢谢。我没仔细打字,所以。。。
KMALLOC_RESERVER 应该是VMALLOC_RESERVE
本帖子就是针对你的帖子和几个人的疑问写的。对你的理解是否有帮助?
8错, 解释的很透彻。 谢谢

还有一个问题:就是用户空间程序,可不可以使用高端内存,有几种方法。
作者: yjh777 发布时间: 2006-01-16
“
还有一个问题:就是用户空间程序,可不可以使用高端内存,有几种方法。”
作者: 思一克 发布时间: 2006-01-16
至于如何为用户进程分配高端内存则不懂, 这两天补一下VM。
to 思兄:那个公式也有笔误吗? 我不确定,还是您自个儿编辑一下吧, 我怕编辑错了

作者: albcamus 发布时间: 2006-01-16
用户在启动一个应用程序时,是需要内存的,而每个应用程序都有3G的线性地址,给这些地址映射页表时就可以直接使用高端内存。
而且还要纠正一点的是:那128M内存的功能不仅仅是用在这些地方的,如果你要加载一个设备,而这个设备需要映射内存到内核中,它也需要使用这段线性地址空间来完成,否则内核就不能访问设备上的内存空间了。
作者: snow_insky 发布时间: 2006-01-16
这个曾经在某个版本的内核代码的__VMALLOC_RESERVE宏的注释中见过,呵呵,可是现在在2.6.14找不到了
作者: albcamus 发布时间: 2006-01-16
作者: snow_insky 发布时间: 2006-01-16
标题我自己不能改吧。KMALLOC_RESERVE 应该是 VMALLOC_RESERVE
我认为应用程序可以使用高端MEM。但我机器内存太小无法实验。
作者: 思一克 发布时间: 2006-01-17
用词不当:
不是128M内存, 是128M线性地址!
而且,设备内存可以通过MMAP映射到用户地址空间直接使用.
我们还是先讨论高端内存吧.听说2.4和2.6处理有所不同,.......
[ 本帖最后由 yjh777 于 2006-1-17 08:55 编辑 ]
作者: yjh777 发布时间: 2006-01-17
The I/O shared memory is mapped into 32-bit physical addresses near the 4 GB boundary. This kind of device is much simpler to handle.
这是ULK-3rd中的原话,我想现在这部分空间还是需要用来映射设备的I/O内存的。
作者: snow_insky 发布时间: 2006-01-17
>> 那128M内存的功能不仅仅是用在这些地方的,如果你要加载一个设备,而这个设备需要映射内存到内核中,它也需要使用这段线性地址空间来完成,否则内核就不能访问设备上的内存空间了。
用词不当:
不是1 ...
这是搞笑,难道这不是那128M的线性地址空间的用途吗?
作者: snow_insky 发布时间: 2006-01-17
这是搞笑,难道这不是那128M的线性地址空间的用途吗?

我没有搞笑,是你生气了。sorry!
作者: yjh777 发布时间: 2006-01-17
谢谢你帮我改好了。 并且净化了。
作者: 思一克 发布时间: 2006-01-18
#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
in arch/i386/mm/discontig.c
system_max_low_pfn = max_low_pfn = find_max_low_pfn() - reserve_pages;
作者: guotie 发布时间: 2006-06-09
用户空间可以访问高端内存吗? 如何访问?
这也是我困惑的地方。 谢谢!
作者: rwen2012 发布时间: 2007-06-14
作者: scutan 发布时间: 2007-06-14
作者: albcamus 发布时间: 2007-06-14
内核的虚拟地址空间分三个区域: ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM,其实高端内存所指的是ZONE_HIGHMEM这个虚拟地址空间,并不是物理地址大于896的物理内存空间,所以用户太是没办法直接使用所谓的高端内存的。
以前的理解是>896M的物理地址空间,所以当然用户进程是可以使用的。
呵呵, 最近在“温故知新”,重新思考了这个问题。
作者: snow_insky 发布时间: 2007-06-14
呵呵,我发现我们对高端内存的定义是有误解的,我看了一遍这个帖子,发现我原来也有这个误解。
内核的虚拟地址空间分三个区域: ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM,其实高端内存所指的是ZONE_HIGHMEM这个 ...
我认为大家讨论的应用程序访问高端内存有一些概念上的误解。对于应用程序来说,没有高端内存的概念,它看到的就是4G的地址空间(32bit),至于kernel把地址空间中某一区域map到高端内存,那是kernel的事情,应用程序并不知道,所以就无所谓应用程序内否访问高端内存的说法。
这种问题在硬件上也有过。intel公司的处理器家族中有一类称为PAE(physical address extension),它的地址总线有36位,可以寻址64G物理地址,而寄存器仍然是32位的。我以前就问过在进程怎么访问大于4G的内存啊(因为指针仍然是32位的),答案和这里的高端内存一样。
作者: zx_wing 发布时间: 2007-06-14
用戶進程需要內存了, 內核可以分配高端內存映射給它呀!
pagefult的时候使用HIGHMEM分配内存吗
作者: rwen2012 发布时间: 2007-06-14
我认为大家讨论的应用程序访问高端内存有一些概念上的误解。对于应用程序来说,没有高端内存的概念,它看到的就是4G的地址空间(32bit),至于kernel把地址空间中某一区域map到高端内存,那是kernel的事情, ...
问一个弱弱的问题:
i386下,如果一个系统有3G的内存(NON PAE),一个进程可以使用超过2G的内存吗?
[ 本帖最后由 rwen2012 于 2007-6-14 11:49 编辑 ]
作者: rwen2012 发布时间: 2007-06-14
我认为大家讨论的应用程序访问高端内存有一些概念上的误解。对于应用程序来说,没有高端内存的概念,它看到的就是4G的地址空间(32bit),至于kernel把地址空间中某一区域map到高端内存,那是kernel的事情, ...
同意!!!!
作者: snow_insky 发布时间: 2007-06-14
作者: berniechen 发布时间: 2007-07-02
作者: berniechen 发布时间: 2007-07-02
不知道理解的对不对
作者: duanius 发布时间: 2008-01-13
呵呵,我发现我们对高端内存的定义是有误解的,我看了一遍这个帖子,发现我原来也有这个误解。
内核的虚拟地址空间分三个区域: ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM,其实高端内存所指的是ZONE_HIGHMEM这个 ...
感觉这句话说得不对
ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM都是指phyical memory
其中ZONE_DMA和ZONE_NORMAL映射在C0000000到C0000000+896M的地方
ZONE_HIGHMEM是用VMALLOC段来映射的
作者: javacool 发布时间: 2009-04-15
用户进程是没有所谓的高端内存的说法。用户进程看到的只是3个G的线性地址空间。
事实证明。用户程进是无法访问高于3G的线性地址的。
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- char *p = malloc(0xFFFFFFFF);
- p[0xC0000000-1] = 'A';
- return 0;
- }
作者: zhangsuozhu 发布时间: 2010-08-26
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28