昨天咱们对内核模块进行了简单的分析,今天为了让咱们从此的分析没有太多障碍,咱们今天先简单的分析一下linux的内存管理子系统,linux的内存管理子系统至关的庞大,因此咱们今天只是初识,只要对其进行简单的了解就行了,不会去追究代码,可是在后面咱们还会对内存管理子系统进行一次深度的分析。linux
在分析今天的内容以前,咱们先来看出自http://bbs.chinaunix.net/thread-2018659-2-1.html的一位大神作的内存管理图,真心佩服大神。其实这张图能够分为两个部分,一部分是地址映射,另外一部分就是内存分配。spa
因此今天咱们会分析到如下内容:.net
1. Linux地址映射3d
2. Linux内存分配unix
下面的分析咱们依据上图进行分析,首先咱们来看其最右边的地址分布图(固然这是虚拟空间)。其地址分布总的能够分为两个部分咱们下面慢慢分析(基于32位处理器)。htm
1. 用户空间(0~3G)blog
a) 空间简介进程
其从0x00000000到0xBFFFFFFF共3GB的线性地址空间,每一个进程都有一个独立的3GB用户空间,固然这是虚拟的空间。
b) 如何转换为物理空间
这一部分虚拟空间到物理空间的转换方法是咱们之前在http://www.cnblogs.com/wrjvszq/p/4246634.html一文中分析过的MMU地址转换。
2. 内核空间(3~4G)
其从0xC0000000到0xFFFFFFFF共1GB大小,内核空间又能够根据映射方式的不一样分为下面四块,咱们一一分析
a) 内核逻辑地址空间
l 空间简介
其从0xC0000000到high_memory(图中896MB的地方)最大为896MB(也就是说这块空间有可能不满,但最大为896MB),固然是虚拟空间。
注:在此注意一下896MB咱们一会在分析。
l 如何转换为物理空间
这一部分虚拟地址与物理内存中对应的地址只差一个固定偏移量(3G),若是内存物理地址空间从0x00000000地址编址,那么这个固定偏移量就是PAGE_OFFSET(如上图)。
b) Vmalloc空间
l 空间简介
其地址没有严格的界限,这段空间既能够访问到咱们的高端内存,也能够访问到低端内存。(高端和低端一会解释)
l 如何转换为物理空间
不是经过简单的线性关系映射,在此不研究。
c) 永久内核映射
l 空间简介
其固定用来访问高端内存。
l 如何转换为物理空间
不是经过简单的线性关系映射,在此不研究。
d) 固定映射
l 空间简介
其在系统初始化期间永久映射I/O地址空间,或者特殊的寄存器。
3. 遗留知识
在刚才咱们前面的分析中咱们留下了一些问题下面进行解释。
a) 低端内存
内核逻辑地址空间所映射的物理内存就是低端内存(实际物理内存的大小,可是小于896MB)
b) 高端内存
低端内存地址之上的物理内存是高端内存(物理内存896MB之上)。
c) 896MB来由
Linux将内存分为内核空间和用户空间,其中内核空间中的0xC0000000~high_memory部分用来映射物理内存,可是咱们还须要映射I/O空间和固定的寄存器,因此留出了high_memory~0xFFFFFFFF之间的地址来映射I/O空间和固定的寄存器,而在X86平台根据经验设定了这个high_memory为896MB。
l Linux内存分配
经过上面的介绍咱们对linux对内存的管理,以及地址的映射有了一个了解,下面咱们来分析linux是如何进行内存分配的。
经过上图咱们能够分析出内存的分配过程
1. 由malloc、fork等系统调用和kmalloc、vmalloc申请获得虚拟内存。
2. 在咱们使用该内存的时候,产生请页异常(kmalloc除外)
3. 从空闲的页框分配物理内存,和虚拟地址创建映射。
注:kmalloc申请空间是不用通过请页异常的,返回的虚拟地址已经对应了物理内存。Kmalloc能够分配到连续的物理内存,vmalloc分配的是非连续的物理内存。