文章目录
高端内存出现的原因
再32位linux系统中,经典的内存分配方式就是3:1的分配方式,再虚拟地址中,0~3G是用户空间,3G~4G是内核空间,再物理地址中,刚好相反,0~1G是内核空间,剩下的是物理空间,很明显。这样设计的方便了程序员写程序,也方便了物理内存的扩充
在虚拟地址和物理地址建立映射的时候,用户空间的映射采用了段页式映射,但是内核空间并非如此,在一开始的时候,内核空间采用了固定映射的方式,也就是直接将虚拟地址-3G=物理地址,但是,这样会带来的问题是这样内核只能访问1G的空间,也就是说,无论物理地址多么大内核也之恩呢访问1G的空间(其实在本质上,除了一些特殊的系统调用,内核不会访问用户空间,并且,在64位的情况下,高端内存也不存在)
所以出现了高端内存,想要解决1G映射的问题
高端内存实现
我们可以把这1G,划分成两部分,一部分用来fix-mapping,一部分用来dynamic-mapping。以x86为例,实际中的做法是,0xC0000000-0xF7FFFFFF的896MB用作fix-mapping,0xF8000000-0xFFFFFFFF的128MB用作dynamic-mapping,前者仍然对应于物理地址的0x00000000-0x37FFFFFF,后者就是所谓的high memory。
可以看出来,high memory在使用的时候会建立临时映射,使用完毕后会进行归还,相对应的物理地址如果在没有建立映射的时候是没有用的
额外知识点
上图中PAGE_OFFSET通常为0xC000 0000,而high_memory指的是0xF7FF FFFF,在物理内存映射区和和第一个vmalloc区之间插入的8MB的内存区是一个安全区,其目的是为了“捕获”对内存的越界访问。处于同样的理由,插入其他4KB大小的安全区来隔离非连续的内存区。
Linux内核可以采用三种不同的机制将页框映射到高端内存区,分别叫做永久内核映射、临时内核映射以及非连续内存分配。