对于32位的机器来说,高于896的物理内存在内核中属于高端内存,并没有对内存做一一的映射,系统保留了128M的线性地址空间来临时映射这些高于896M的高端物理内存,该线性地址为3G+768m~4G。返回页框线性地址的页分配函数对于高端内存是无效的,因为高端内存不会自动的映射到某个线性地址。例如__get_free_pages(GFP_HIGH_MEM,0)函数分配高端内存页框时,返回的是NULL;内核可以采用三种方式来使用高端物理内存:永久内核映射,临时内核映射和非连续内存分配。建立永久内核映射可能会阻塞当前进程的执行,这发生在没有高端内存没有空闲的页表项来做映射的情况下,因此在中断等不能阻塞的代码中不要使用永久内核映射。临时内核映射不会发生阻塞的情况,但必须保证没有其他的内核路径在使用同样的临时内核映射。
一、永久内存映射
永久内核映射使用的是内核主页表中的一个专门的页表,其地址存放在pkmap_page_table中,页表的页表项由宏LAST_PKMAP产生,页表中包含512或者1024项。
该页表映射的线性地址从PKMAP_BASE开始,pkmap_count数组包含了LAST_PKMAP个计数器,pkmap_page_table页表中的每项都有对应一个计数值: