ARM32内存空间分配

Linux内核一般将处理器的虚拟地址空间分成两部分,在32系统上,地址空间在用户进程和内核之间划分的典型比例为3:1,在给出的4GB的虚拟地址空间中,0 ~ 3GB将用于用户空间而3GB ~ 4GB将用于内核空间,内核提供了相关的配置项来修改该比例,也就是说最多寻址1GB的虚拟地址空间 。
当CPU启动MMU后,CPU访问的时虚拟地址空间,然后由MMU根据页表转换成物理地址,页表是由维护的,所以可以决定1GB的虚拟地址空间具体映射到什么物理地址 。但是不管怎么映射,最多也只能映射1G的物理内存,所以如果一个系统有超过1G的物理内存,在某一时刻,必然有一部分空间是内核无法访问到的,对于该问题内核借助于高端内存()方法来管理多余的内存,本章的主要讲解以下内容
什么是高端内存及其作用
ARM32 Linux的内存布局
1. 什么是高端内存
对于32系统,内核使用3G ~ 4G的虚拟地址空间,那么只有1G的地址空间可以用来映射物理空间 。但是,如果我们使用的内存大于1G的情况,是不是超过1G的内存就无法使用了呢?为此内核引入了一个高端内存的概念,把1G的虚拟地址空间分成两部分
低端内存空间:小于的物理地址空间,这部分的内存物理地址和3G开始的线性地址是一一映射的,也就是说内核使用的线性地址空间3G ~ (3G + )和物
理地址空间0 ~ 一一映射
高端内存空间:剩下的128M的线性空间用来映射剩下的大于的物理地址空间
对于以上,我们可以知道以下问题
对于高端内存,现在一般是896M,当我们只有512M的内存的时候,就没有高端内存一说了,因为512MB的物理内存已经被直接映射
64位系统下不会有high ,因为64位虚拟地址空间非常大(分给的也很大),完全能够直接映射全部物理内存 。
在32位系统上,没有任何进程能够有效地使用超过3GB的内存 。这意味着购买超过4GB的从理论上是发挥不出其优势
对于我们使用的IMX6U,由于使用了CMA,所以其高端内存的地址空间范围为 0000 ~FFFF(512 MB ~ ) 。那么内核如何借助512M高端内存地址空间实现访问访问所有4GB的物理内存 。比如当内核项访问高于的物理地址时,可以从( 0000 + ) ~FFFF地址空间范围内找一段相应大小的空闲虚拟地址,建立映射到想访问的那段物理内存,用完后归还 。这样就所有的人都可以借用这段地址空间访问物理地址,访问所有物理内容如下图所示:
【ARM32内存空间分配】我们可以知道高端内存的最基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存 。万一有内核进程或模块一直占用某段逻辑地址空间不释放,怎么办?若真的出现的这种情况,则内核的高端内存地址空间越来越紧张,若都被占用不释放,则没有建立映射到物理内存都无法访问了 。
2. Linux内核高端内存的划分
对于高端内存,一般划分如下:
动态内存映射区:虚拟内存中连续,但物理内存不连续的内存,可以在区域分配 。该机制通常用于用户空间,内核自身会试图尽力避免非连续的物理内存 。
永久内存映射区:该区域可访问高端内存,访问方法是使用()分配高端内存页或使用kmap函数将分配到高端内存映射到该区域
固定映射区:固定映射是与物理内存空间中的固定页关联的虚拟地址空间项,该区域和4GB的顶端只有4K的隔离带,其每个地址项都服务于特定的用途 。
对于高端内存的划分,其中fixed 主要用在boot阶段用来永久性映射一些物理地址固定的数据结构或者硬件地址(比如ACPI表,APIC地址,等等) 。kmap area是用来临时建立映射来访问物理页用的,可用的地址空间也比较小 。绝大部分了给 area,和返回的都是这个空间里的地址 。