内存寻址和管理一直都是理解kernel的重点和难点, 邮件列表中很多人(包括我)对于这部分的理解总是不那么透彻, 经常一个问题提出来, 几封邮件之后就乱了, 除非大牛过来救火, 一群人晕晕乎乎半天也搞不清楚.

几个月前列表里有人问过高端内存的问题, 当时借着那个问题我又好好把这块儿看了一遍, 还记了点笔记, 今天拿出来再复习总结一遍.

Linux把物理内存划分为了三个管理区, 分别为0-16MB的ZONE_DMA, 16-896MB的ZONE_NORMAL和高于896MB的ZONE_HIGHMEM也就是高端内存.

至于为什么这么划分, ZONE_DMA好理解, 因为ISA总线只能对前16MB进行DMA寻址, 这块要分出来不能乱用. 而ZONE_NORMAL和ZONE_HIGHMEM为什么从896MB区分呢? 这还得从物理地址和虚拟地址说起.

默认情况下, 内核空间是指3GB-4GB的虚拟地址, 用户空间则是0-3GB. 内核进程和用户进程分别活动在自己的空间内. 这里重点说内核空间, 3G-(3G+896MB)这块是直接映射, 减去PAGE_OFFSET(0xC000000)就是真实物理地址, 剩下那128MB(4G-3G-896MB)是用来做各种映射的, 包括整个高端内存的映射, 如果不留出这么一段做映射, 内核就只能管理1G的物理内存, 余下部分就只能浪费了.

这里有个小难点. 有人会问, “如果剩下那些映射给用户空间, 内核不就可以不管了么, 高端内存也就不需要了吧?” 此言差矣, 点出来也就是一句话的事儿: 用户空间的内存使用也是内核分配的, 内核当然要有能力控制所有硬件资源.

PS: 以上都是基于x86架构, x86_64没有高端内存, 有的MIPS32处理器的高端内存则默认从256MB开始.