浅析Linux系统中的内存管理

描述

当使用Inter 80x86微处理器时,必须区分三种地址:

逻辑地址:有段基址和段偏移量组成。

线性地址:32位无符号整数。

物理地址

CPU通过分段单元将逻辑地址转换为线性地址,再通过分页单元将线性地址转化为物理地址

硬件的分段单元

从80386CPU开始,Intel微处理器能执行两种不同的地址转换模式,分别称为实模式(为了与早期OS兼容)和保护模式,这里重点放在保护模式上。

段寄存器

一个逻辑地址由两部分组成,一个段标识符(16位)和一个相对地址的偏移量(32位),段寄存器是用来存放段选则符的,包括cs,ss,ds,es,fs,gs。

cs:代码段寄存器,用于存放程序指令的段。

ss:栈段寄存器,指向当前存放程序栈的段;什么是程序栈空间,即主要用来 存放函数和数组等。

ds:数据段寄存器,指向存放静态数据(永久性不变的数据)或者外部数据的段。

其它三个寄存器做一般用途,可以用来访问任意段。

 cs寄存器还有一个两位域,用来指明cpu的特权级,linux中只有0和3级,分别为内核态和用户态。

段描述符

占8字节,段描述符被放在全局描述符表(GDT)或者局部描述符表(LDT)。

系统通常只定义一个GDT(其地址被存放在GDTR寄存器中),每个进程可以有自己的LDT(其地址被存放在LDTR寄存器中)。

其中,系统段存储内核数据结构,任务状态段用于保存处理器寄存器的内容。
 

cpu

段选择符

为了加速逻辑地址到线性地址的转换,Intel处理器提供一种附加的非编程的寄存器(不能被程序员设置),这样在访问段寄存器中段选择符时,就不能(不需要)访问GDT或LDT了。

cpu

段单元

逻辑地址转化为线性地址总览:

cpu

Linux中的段

Linux更喜欢分页的方式,当所有的进程使用相同的段寄存器值时,内存管理变得更简单,它们能共享相同的线性地址。而且许多RISC处理器不支持段功能,Linux不好做移植。

硬件的分页单元

分页单元认为所有的RAM被分成固定长度的页框,每一个页框包含一页。在Intel处理器中,通过设置CR0寄存器的PG标志启动分页。当PG=0时,线性地址就被解释成物理地址。

常规分页

从i80386起,Intel处理器的分页单元处理4KB的页。32位线性地址被分成三个域:目录(10),页表(10),偏移量(12)。

正在使用的页目录表的物理地址存放在处理器的CR3寄存器中。

cpu

这里要说明下,在页目录和页表表项中由Page Size标志为1,页目录项指的是4MB的页框。如果Present为0,分页单元就把这个线性地址存放在处理器的CR2寄存器中,并产生14号缺页异常。

扩展分页

从奔腾处理器开始,Intel 80x86微处理器引进了扩展分页,它允许页框大小为4KB或4MB(页目录10位,偏移量22位)。

cpu

之后就是引入cache和TLB(计算机组成原理内容),就不详细说了。

Linux的分页

Linux采用三级分页,页全局目录(10),页中间目录(10),页表(10),偏移量(13)。

cpu

保留的页框

内核代码和数据结构存放在一组保留的页框中,这些页框所含的页从不动态分配或者交换到内存中。

作为一条常规,Linux内核被安装在RAM物理地址0x00100000开始的地方,为什么从这个地方开始?

因为页框0由BIOS使用,存放硬件配置。

物理地址0x000a0000到0x000fffff被BIO程序使用同时映射ISA上的显存。

前1MB的其它页框可能被保留用作特定的计算机模式。

为了避免把内核装入一组不连续的页框,Linux更愿跳过第1MB的RAM。(内核小于1MB _text---_etext)

cpu



审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分