免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6099 | 回复: 9
打印 上一主题 下一主题

关于Linux内存使用和映射的疑问——涉及到物理地址、线性地址-看完精华贴还是不明白 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-24 10:38 |只看该作者 |倒序浏览
本帖最后由 GoldenSoldier 于 2010-05-25 13:10 编辑

看了九贱前辈我理解的逻辑地址、线性地址、物理地址和虚拟地址(补充完整了),也看了ULK 3的MM。
为了说明我的疑问,先自己罗嗦一下Linux的内核1G的线性地址:

在理想中的计算机架构中,一个页帧(框)page frame 就是一个有着任何用途的存储单元:存储内核和用户数据、磁盘数据的缓冲等等。所有类型的数据可以无限制的存储在页帧(框)中。

但是,现实中的计算机架构对于页帧(框)的使用有自己的约束。特别是,Linux内核必须涉及80×86架构上的两个硬件约束:
1.针对传统的ISA总线,DMA处理器有个很重要的限制:它们只能寻址RAM的前16M
2.在现代32位平台中,对于大容量的RAMCPU不能直接访问所有的物理存储,因为线性地址空间太小了;


为了迎合上面这两种限制,Linux 2.6把物理内存每一个内存节点分为三个区。在80 x 86 UMA 架构上为:
         ZONE_DMA:小于16M的内存页帧(框),包括通过DMA被传统ISA总线使用的页帧(框),
         ZONE_NORMAL16M896M内存页帧(框);
         ZONE_HIGHMEM:大于896M的内存页帧(框)

其中ZONE_DMAZONE_NORMAL1G内核空间中通过映射具有线性地址,而ZONE_HIGHMEM则没有线性地址的映射,内核不能直接访问,也不能通过__get_free_pages(GFP_HIGHMEM,0)返回线性地址。这是因为在内核1G的线性地址空间中,最高的128M被内核用来非连续内存分配(vmalloc)和固定映射的线性地址Fix-Mapped LinearAddresses。所以,内核剩下的线性地址空间为1G-128M=896M。而在64位平台上就不存在这个问题,通常ZONE_HIGHMEM为空,因为64位平台有足够的地址空间。

注:32位平台的线性地址空间为2^32=4GLinux将其分为两个部分:高1G的为内核空间,低3G的为用户空间。


这是为自己对ULK一段的翻译,可能不太准确,但大意就是下图:

高位内存的页由于没有线性地址而无法被内核访问。因此,内核线性地址空间最高128M的一部分就被用于映射高位内存的页。

内核线性地址对于高位内存的访问主要有三种映射方式:
永久内核映射Permanent kernel mappings临时内核映射Temporary kernel mappings非连续物理地址分配(vmalloc)。如下图:



但还是对于Linux内存的使用存在以下的问题。
1.如果物理内存小于896M,那么vmalloc映射的物理地址是什么,还有意义么?如果有,那么vmalloc映射的是那部分的物理地址?
在论坛里看到,有位大侠说“
同一个物理地址可以有N个虚虚拟地址,而一个虚拟地址只能对应一个物理地址”,照此看来,vmalloc映射的物理地址似乎应该在”normal“区了。

2。如果物理内存很大,比如2G,那么将有1G多的空间在
ZONE_HIGHMEM,那么仅仅凭vmalloc的120多M就可以映射到1G多的空间么?
还有,
vmalloc申请的空间可以大于128M的,论坛里白金大侠写过这样的模块,不过是在虚拟机中,不知道在真实的情况下又如何呢?

3.
如果物理内存很大,比如2G,用户空间是否可以使用
ZONE_HIGHMEM空间呢?
似乎可以,那么问题又来了,内核需不需要对此进行管理,如果需要那么如何做映射的呢?

论坛徽章:
0
2 [报告]
发表于 2010-05-24 10:57 |只看该作者
1.如果物理内存小于896M,那么vmalloc映射的物理地址是什么,还有意义么?如果有,那么vmalloc映射的是那部分的物理地址?
——这个问题没有理解到,vmalloc映射物理地址?什么意思?你是说分配到的虚拟地址对应的物理地址吗?vmalloc是由内存管理子系统提供的一种相对高层的分配抽像,是从虚拟页表中分配连续的虚拟地址空间而已。所以,你说的“映射”究竟指什么,不明白。

2。如果物理内存很大,比如2G,那么将有1G多的空间在ZONE_HIGHMEM,那么仅仅凭vmalloc的120多M就可以映射到1G多的空间么?
——拆东墙补西墙呀,或者公共汽车原理呀,类似。内核使用页表对所有内存进行统一的管理,高端内存临时映射可以拆东墙补西墙地解决这个问题!

论坛徽章:
0
3 [报告]
发表于 2010-05-24 11:06 |只看该作者
1.如果物理内存小于896M,那么vmalloc映射的物理地址是什么,还有意义么?如果有,那么vmalloc映射的是那部 ...
独孤九贱 发表于 2010-05-24 10:57


感谢九贱大侠的关注。

1.vmalloc为了把物理上不连续的页转为虚拟地址空间连续的页。那么在内存<896M的情况下,就没有ZONE_HIGHMEM,那么vmalloc转换的物理页又是哪个区的?

2.我还是不明白,VMALLOC_START~VMALLOC_END显然小于128M,如果vmalloc申请200M的空间,从哪里来的线性地址来补?

论坛徽章:
0
4 [报告]
发表于 2010-05-24 12:33 |只看该作者
物理地址空间不等于物理内存空间

论坛徽章:
0
5 [报告]
发表于 2010-05-24 13:15 |只看该作者
物理地址空间不等于物理内存空间
snail_314 发表于 2010-05-24 12:33



  愿闻赐教!
比如512M的RAM,就是机器上插的内存条,那么其:
物理地址空间?
物理内存空间?

论坛徽章:
0
6 [报告]
发表于 2010-05-25 08:54 |只看该作者
>3.如果物理内存很大,比如2G,用户空间是否可以使用
ZONE_HIGHMEM空间呢?
似乎可以,那么问题又来了,内核需不需要对此进行管理,如果需要那么如何做映射的呢?

引Professional Linux Kernel Architecture在内存管理的原话:
The use of highmem pages is problematic only for the kernel itself. The kernel
must first invoke the kmap and kunmap functions discussed below to map the
highmem pages into its virtual address space before it can use them — this is not
necessary with normal memory pages. However, for userspace processes, it makes
absolutely no difference if the pages are highmem or normal pages because they are
always accessed via page tables and never directly.


由此可见,用户空间没有ZONE_NORMAL和ZONE_HIGHMEM的概念,反正都是3G的虚拟地址。

论坛徽章:
0
7 [报告]
发表于 2010-05-25 11:36 |只看该作者
本帖最后由 lliubbo 于 2010-05-25 11:37 编辑

1.如果物理内存小于896M,那么vmalloc映射的物理地址是什么,还有意义么?如果有,那么vmalloc映射的是那部分的物理地址?
在论坛里看到,有位大侠说“同一个物理地址可以有N个虚虚拟地址,而一个虚拟地址只能对应一个物理地址”,照此看来,vmalloc映射的物理地址似乎应该在”normal“区了。

> 这个应该是这样,如果内存没有896M, vmalloc只是从normal区分配。手头不方便看代码,你可以查下确认下。

2。如果物理内存很大,比如2G,那么将有1G多的空间在ZONE_HIGHMEM,那么仅仅凭vmalloc的120多M就可以映射到1G多的空间么?

> 除了vmalloc,还kmap之类的。一般kmap用的多。 这里如果高端内存实在太多容易造成瓶颈。好像有些优化模块,不过每加入内核。因为有那么大的内存话肯定要考虑64位机器或打开pae.

还有,vmalloc申请的空间可以大于128M的,论坛里白金大侠写过这样的模块,不过是在虚拟机中,不知道在真实的情况下又如何呢?

> 这个标准内核里应该不支持吧.要扩展得自己写写实践试试.

3.如果物理内存很大,比如2G,用户空间是否可以使用
ZONE_HIGHMEM空间呢?
似乎可以,那么问题又来了,内核需不需要对此进行管理,如果需要那么如何做映射的呢?

> 用户空间不关心是high,normal之类的.只管调malloc之类的. 内核再决定具体分配哪块空间,所有内存当然都是由内核进行管理。映射时直接改进程的用户空间页表就可以.

论坛徽章:
0
8 [报告]
发表于 2010-05-25 13:04 |只看该作者
本帖最后由 GoldenSoldier 于 2010-05-25 13:13 编辑

回复 7# lliubbo

感谢ls的解答。
关于1,现在在看源代码

关于2、3,深表赞同.

也在实践2中。
白金兄的例子测试ingget_free_pages申请大内存(17楼)

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
9 [报告]
发表于 2010-05-25 13:59 |只看该作者
LZ可以看看那篇帖子的25楼回帖:
回复 #22 platinum 的帖子
在386机器上,如果物理内存超过1G的话,default的vmalloc区间只有128M左右。同过vmalloc=XX参数的话,是减少了kernel线性映射空间为代价的。

在x86_64的机子上就没有这个问题,vmalloc的区间可以很大。

论坛徽章:
0
10 [报告]
发表于 2010-07-03 18:50 |只看该作者
回复 2# 独孤九贱


    拆东墙补西墙?九贱大侠能举个例子吗?
    不管用不用页表,相同容量的物理内存也必然需要相同容量的线性地址来映射啊。120多兆的线性地址怎么做到去映射远大于本身的物理内存呢?
    即使“拆东墙补西墙”,打个比方,内核现在需要使用240兆内存,第一次120兆的线性空间先映射120兆ZONE_HIGHMEM中的内存,第二次内核去映射剩下的120兆内存的时候,必然需要释放原来用掉的120兆线性空间,那第一次映射来的物理内存不是丢失了吗?
    学习内核好几个月了,对这个问题一直百思不得其解,忘牛人指点,小弟愿闻其详,谢谢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP