在32位系统里,Linux内核地址空间是指0xCxC0000000开始到0xFFFFFFFF总数为1G的高档显存地址空间,而用户空间是0x00000000至0xBFFFFFFF的3G虚拟储存空间。操作系统和驱动程序运行在内核空间,应用程序运行在用户空间。
内核地址映射有下几种模式
1、直接映射区:内核将内核空间前896M和数学空间的前896M进行直接映射。即对于内核空间前896M显存有:Vaddr=0xCxC0000000+Paddr。高档显存是指896M开始到1G的虚拟地址空间。引入高档显存映射这样一个概念的主要诱因就是我们所安装的显存小于1G时,内核的1G线性地址空间难以构建一个完全的直接映射来触碰整个数学显存空间,而对于80x86开启PAE的情况下,容许的最大化学显存可达到64G,因而内核将自己的最后128M的线性地址空间腾下来,用以完成对高档显存的暂时性映射。而在64位的系统上就不存在这样的问题了,由于可用的线性地址空间远小于可安装的显存。
2、动态显存映射区:该区域由内核函数vmalloc来分配,特征是:线性空间连续,并且对应的数学空间不一定连续。vmalloc分配的线性地址所对应的数学页可能处于高端显存,也可能处于高档显存。
3、永久显存映射区:内核专门因此留出一块线性空间,从PKMAP_BASE到FIXADDR_START,用于映射高档显存。在2.6内核上linux内核地址空间,这个地址范围是4G-8M到4G-4M之间,称作”永久内核映射空间”。这个空间和其它空间使用同样的页目录表,对于内核来说,就是swapper_pg_dir,对普通进程来说,通过CR3寄存器指向。一般情况下,这个空间是4M大小,因而仅仅须要一个页表即可linux内核地址空间,内核通过来pkmap_page_table找寻这个页表。通过kmap(),可以把一个page映射到这个空间来。因为这个空间是4M大小,最多能同时映射1024个page。因而,对于不使用的的page,及应当时从这个空间释放掉(也就是解除映射关系)linux虚拟主机,通过kunmap(),可以把一个page对应的线性地址从这个空间释放下来。
4、固定显存映射区:内核在FIXADDR_START到FIXADDR_TOP之间保留了一些线性空间用于特殊需求。这个空间称为”固定映射空间”在这个空间中,有一部份用于高档显存的临时映射。这块空间具有如下特征:
(1)每位CPU占用一块空间
(2)在每位CPU占用的那块空间中,又分为多个小空间,每位小空间大小是1个page,每位小空间用于一个目的linux makefile,这种目的定义在kmap_types.h中的km_type中。
当要进行一次临时映射的时侯,须要指定映射的目的,依据映射目的,可以找到对应的小空间,之后把这个空间的地址作为映射地址。这意味着一次临时映射会造成先前的映射被覆盖。通过kmap_atomic()可实现临时映射。