本帖最后由 GoldenSoldier 于 2010-05-25 13:10 编辑
看了九贱前辈的我理解的逻辑地址、线性地址、物理地址和虚拟地址(补充完整了),也看了ULK 3的MM。
为了说明我的疑问,先自己罗嗦一下Linux的内核1G的线性地址:
在理想中的计算机架构中,一个页帧(框)page frame 就是一个有着任何用途的存储单元:存储内核和用户数据、磁盘数据的缓冲等等。所有类型的数据可以无限制的存储在页帧(框)中。 但是,现实中的计算机架构对于页帧(框)的使用有自己的约束。特别是,Linux内核必须涉及80×86架构上的两个硬件约束:
1.针对传统的ISA总线,DMA处理器有个很重要的限制:它们只能寻址RAM的前16M;
2.在现代32位平台中,对于大容量的RAM,CPU不能直接访问所有的物理存储,因为线性地址空间太小了;
为了迎合上面这两种限制,Linux 2.6把物理内存每一个内存节点分为三个区。在80 x 86 UMA 架构上为:
ZONE_DMA:小于16M的内存页帧(框),包括通过DMA被传统ISA总线使用的页帧(框),
ZONE_NORMAL:16M~896M内存页帧(框);
ZONE_HIGHMEM:大于896M的内存页帧(框) 其中ZONE_DMA和ZONE_NORMAL在1G内核空间中通过映射具有线性地址,而ZONE_HIGHMEM则没有线性地址的映射,内核不能直接访问,也不能通过__get_free_pages(GFP_HIGHMEM,0)返回线性地址。这是因为在内核1G的线性地址空间中,最高的128M被内核用来非连续内存分配(vmalloc)和固定映射的线性地址Fix-Mapped LinearAddresses。所以,内核剩下的线性地址空间为1G-128M=896M。而在64位平台上就不存在这个问题,通常ZONE_HIGHMEM为空,因为64位平台有足够的地址空间。 注:32位平台的线性地址空间为2^32=4G,Linux将其分为两个部分:高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空间呢?
似乎可以,那么问题又来了,内核需不需要对此进行管理,如果需要那么如何做映射的呢?
|