一、从内存分布图看内存管理
要了解一个系统的内存管理,首先要了解这个系统的内存是如何布局的。以32位CPU为例,它最多可以拥有32根地址线,因此它最大的寻址空间为4GB。那么在这个4GB的地址空间,内核空间和用户空间究竟是怎样划分的?
ARM32处理器提供7种处理器模式:
1、用户模式:用户程序运行的模式
2、系统模式:特权模式
3、一般中断模式(irq):普通中断模式
4、快速中断模式(fiq):快速中断模式
5、管理模式(svc):操作系统的内核通常运行在这个模式下
6、数据访问终止模式(abort):当数据或者指令预取终止时进入该模式,用于虚拟存储及存储保护
7、未定义指令模式(undefined):当未定义的指令执行时进入该模式,可以用于支持硬件协处理器的软件仿真
I、linux内核保护机制
linux采用了两级的保护机制:用户模式和内核模式。linux内核把地址空间进一步做了划分,通常0-3GB这段空间留给用户模式使用,3GB-4GB留给内核模式使用,通常是按照3:1的比例进行划分,当然也可以按照2:2的比例来划分。
分页机制让每个进程都感觉自己独占了整个内存空间,因此每个进程都可以访问到全部的4GB空间,其中0-3GB是进程在用户空间时可以访问,3-4GB是进程通过系统调用进入内核空间时可以访问,这段内核空间是所有进程共享的。
II、linux内核内存分布图
Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xf0000000 - 0xff000000 ( 240 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xcf800000 ( 760MB)
[ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[ 0.000000] .text : 0xc0008000 - 0xc0658750 (6466 kB)
[ 0.000000] .init : 0xc0659000 - 0xc0782000 (1188 kB)
[ 0.000000] .data : 0xc0782000 - 0xc07b1920 ( 191kB)
[ 0.000000] .bss : 0xc07b1920 - 0xc07db378 ( 167kB)
lowmem :就是我们常说的线性映射区,所谓线性映射区就是物理线性地址映射到这段内核空间的区域中。在ARM32平台上,物理地址【0:760MB】的这一部分内存被映射到【3GB:3GB+760MB】的虚拟地址上。
内核空间只有1GB,通常实际装载的物理内存会超过内核虚拟地址空间大小。因此内核空间又将虚拟地址空间细分为高端内存和低端内存。低端内存就是映射低于760MB的物理内存,这一部分是直接映射的,可以提高运行速度。而高于760MB的高端物理内存需要通过vmalloc借用一段虚拟地址空间来建立临时映射。
高端内存的基本思想:借用一段虚拟地址空间,建立临时地址映射 (页表), 使用完之后就释放,以此达到这段地址空间可以循环使用,访问所有的物理内存。
ARM32系统内存分布图: