您的位置:首页 > 运维架构 > Linux

Linux内存管理的基本框架

2016-06-03 11:10 225 查看
Linux内核的映射机制设计成三层,在页面目录和页面表中间增设了一层“中间目录”。

在代码中,页面目录称为PGD,中间目录称为PMD,而页面表称为PT。

PT中的表项称为PTE,PTE是“Page Table Entry”的缩写。

PGD、PMD和PT均为数组。

在逻辑上也把线性地址从高位到低位划分成4个位段。

4G字节虚存空间

Linux内核将这4G字节的空间分成两部分:

将最高的1G字节(从虚地址0xC0000000至0xFFFFFFFF)用于内核本身,称为“系统空间”。

将较低的3G字节(从虚地址0x0至0xBFFFFFFFF)用作各个进程的“用户空间”。

系统空间由所有进程共享。

每当一个进程通过系统调用进入了内核,该进程就在共享的系统空间中运行,不再有其自己的独立空间。

虽然系统空间占据了每个虚存空间中最高的1G字节,在物理的内存中却总是从最低的地址(0)开始。

对于内核来说,其地址的映射是很简单的线性映射,0xC0000000就是两者之间的位移量。

此位移称为PAGE_OFFSET,定义于文件include/asm-i386/page.h中。

PAGE_OFFSET也代表着用户空间的上限,常数TASK_SIZE就是通过它定义的。

对于系统空间而言,给定一个虚地址x,其物理地址是从x中减去PAGE_OFFSET;相对应地,给定一个物理地址x,其虚地址是x+PAGE_OFFSET。

_pa()只是为内核代码中当需要知道与一个虚地址对应的物理地址时提供方便。

例如,在切换进程的时候要将寄存器CR3设置成指向新进程的页面目录PGD,而该目录的起始地址在内核代码中是虚地址,但CR3所需要的是物理地址,这时候就要用到_pa()。

每个进程的局部段描述表LDT都作为一个独立的段而存在,在全局段描述表GDT中要有一个表项指向这个段的起始地址,并说明该段的长度以及其他一些参数。

每个进程还有一个TSS结构(任务状态段)

每个进程都要在全局段描述表GDT中占据两个表项。

段寄存器中用作GDT表下标的位段宽度是13位,所以GDT中可以有8192个描述项。

一些系统开销:(GDT中的第2项和第3项分别用于内核的代码段和数据段,第4项和第5项永远用于当前进程的代码段和数据段,第1项永远是0,等等)

有8180个表项可供使用,所以系统中最大的进程数量是4090。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: