IT圈泥瓦匠一枚,混迹过国产处理器圈,从事Linux BSP开发混一软件经理职务,现漂浮在云端从事OpenStack-Nova相关设计工作。
分类: LINUX
2009-05-05 19:11:22
高端内存
高端内存:是指物理地址大于 896M 的内存。对于这样的内存,无法在“内核直接映射空间”进行映射。
内核直接映射空间最多只能从3G到4G,只能直接映射1G物理内存,对于大于 1G 的物理内存,无能为力。因此,内核为了访问大于1G的物理内存,就必须留出一点空间<128M=1024-896>用于映射大于1G的物理内存。
实际上,“内核直接映射空间”也达不到 1G,还得留点线性空间给“内核动态映射空间” 呢。
因此,Linux 规定“内核直接映射空间” 最多映射 896M 物理内存。
对于高端内存,可以通过 alloc_page() 或者其它函数获得对应的 page,但是要想访问实际物理内存,还得把 page 转为线性地址才行(为什么?想想 MMU 是如何访问物理内存的),也就是说,我们需要为高端内存对应的 page 找一个线性空间(这段线性地址就是896M~1024M<3G-4G范围>共128M),这个过程称为高端内存映射。
linux内核的pagetable swapper_pg_dir将虚拟地址0xC0000000~0xC0000000+896M映射到物理地址0x0~0x896M。除去内核代码占用的ram外,其余的物理ram都为空闲。当内核需要时,直接分配了就可以使用,而不需要再对swapper_pg_dir进行修改。而当用户空间需要的时候,内核为其分配page,并要修改应用进程的pagetable从而将刚分配的page映射到相应的应用进程地址空间。内核不需要再次映射,因为swapper_pg_dir已经将896M的地址映射到内核去了。除非内核使用HIGH_MEM,这时就要重新映射内核的高128M空间(修改swapper_pg_dir的高128项)。有上可知,只要应用进程分配的page小于896M(在内核地址空间之内),内核都可以直接访问(参见#define __copy_user(to,from,size)其中to为内核地址,使用用户page_dir的768~896项(3G~3G+896M内核空间),from使用用户地址:page_dir的0~767项(0~3G-1用户地址空间))。要是应用进程的page大于896M时,内核就不能直接访问了,需要使用swapper_pg_dir的高128项来映射应用进程的地址空间,这也是HIGH_MEM存在的原因。