linux 内存管理

start!!!

这篇文章主要是参考《独辟蹊径品内核》一书,说是参考,实际上几乎是按照作者的思路去学习和理解,唯一不同的是这里会结合kernel3.19.2去学习。大神路过,不足之处还请多多指教!

一、内存的地址空间

1.物理内存地址

系统启动之后,detect_memory函数通过BIOS系统调用获取内存信息,而这些信息存放在boot_params。该结构体在3.19.2内核中位于bootparam.h文件中,这里我们只关注其主要俩个成员变量:

内存被分成了很多块儿,而e820_entries保存了内存块的数量,e820_map数组保存了每一个内存块描述信息的数据结构。E820MAX为128,也就是内存最多可以被分割为128块。描述每个内存块的详细信息在e820_entry数据结构中,该数据结构定义如下:

其中结构成员addr为该内存块的起始地址;size为该内存块的大小;type为该内存块的类型。

type有如下的类型:

宏E820_RAM表示内存,而E820_RESERVED表示只读存储空间。

详细内容可阅读该数的p99-100

 

 2.虚拟地址空间

  我们知道32位系统的虚拟地址空间是4GB。linux把4GB中最高的1GB划分给内核空间使用,0~3GB划分给用户空间使用。也就是说每一个用户态程序可以共享0~3GB的用户空间,共享1GB的内核空间。内核空间0~896MB的这一部分内存被映射到3GB~3GB+896MB的虚拟地址上。这个区域被称作固定映射区,因此物理地址和虚拟地址在数值上相差3GB。具体的映射关系如图所示:

 

新版内核的虚拟地址和物理地址的转换方式与作者所述不同,应该内存的映射也应该发生了变化,毕竟经过多次的迭代,架构应该跟作者当时的系统有所变化,这里主要是学习了解,不必过分深究。可以发现,这里只映射896MB的空间,那剩下的128MB去哪儿了呢。这128MB实际上时留给vmalloc的。vmalloc是啥,vmalloc主要用于设备程序和内核模块开辟连续的内存空间,这种连续是虚拟地址上的,物理上可能并不连续。

那么,1GB的内核空间又是怎么组织起来的,看下图:

high_memory指向3GB+896MB的位置。当内核所需空间大于896MB时,我们将大的那部分空间称为high memory,而小于896MB,则称为low memory。

 

二、内存管理的数据结构

 1.物理内存页描述符

   系统启动之后,根据e820entry数组建立基本的内存管理结构。内存的基本管理单位是页,从物理地址0开始,依次给每一个页面从0开始的一个编号,这个编号被称为PFN,可以看出PFN左移12位就可以得到页面的起始物理地址,同样可以根据一个物理地址计算出对应的PFN。有了PFN后,系统还要为每一个物理页面建议一个page的数据结构,它记录这一个物理页面的基本信息,该结构定义于mm_types.h文件中。该数据结构定义比较复杂,这里不复制粘贴了,建议大家自行打开源码查看。

 

 

 

 

posted @ 2015-07-10 09:57  ChangeEveryDay  阅读(208)  评论(0编辑  收藏  举报