深入理解linux内核——内存寻址(1)

内存地址

逻辑地址:包含在机器语言指令中用来指定一个操作数据或一条指令的地址。每一个逻辑地址都由一个段(segment)和偏移量(offset或displacement)组成,偏移量指明了从段开始的地方到实际地址之间的距离。

线性地址:也称虚拟地址。

物理地址:用于内存芯片级内存单元寻址。它们与从微处理器的地址引脚发送到内存总线上的电信号相对应。

内存控制单元通过一种称为分段单元的硬件电路把一个逻辑地址转换成线性地址;接着第二个称为分页单元的硬件电路把线性地址转换成一个物理地址。

深入理解linux内核——内存寻址(1)

硬件中的分段

从80286模型开始,intel处理器以两种不同的方执行地址转换,这两种方式分别称为实模式(read mode)和保护模式(protected mode)。

一个逻辑地址由两部分组成:一个段标志符一个指定段内相对地址的偏移量。段标志符是一个16位长的字段,称为段选择符。而偏移量是一个32位长的字段。

为了方便快速找到段选择符,处理器提供段寄存器,段寄存器的唯一目的是存放段选择符。尽管只有6个段寄存器,但程序可以把同一个段寄存器用于不同的目的,方法是先将其值保存在内存中,用完后再恢复。

深入理解linux内核——内存寻址(1)

每个段由一个8字节的段描述符表示,它描述了段的特征。段描述符放在全局描述符表(GDT)或局部描述符表(LDT)中。

通常只定义一个GDT中,而每个进程除了存放在GDT中的段之外如果还需要创建附加的段,就可以有自己的LDT。GDT在主体中的地址和大小存在gdtr控制寄存器中,当前正在被使用的LDT地址和大小放在ldtr控制寄存器中。

为了加快逻辑地址到线性地址的转换,80x86处理器提供一种附加的非编程的寄存器供6个可编程的段寄存器使用。每当一个段选择符被装入段寄存器时,相应的段描述符就由内存装入到对应的非编程CPU寄存器中。

从那时起,针对那个段的逻辑地址就可以不访问主存中的GDT或LDT

,处理器只需直接引用存放段描述符的CPU寄存器即可。仅当段寄存器的内容改变时,才有必须访问GDT或LDT。

深入理解linux内核——内存寻址(1)

由于段描述符是8字节长,因此它在GDT或LDT内的相对地址是由段选择符的最高13位的值乘8得到的。

逻辑地址是怎么样转换成相应的线性地址的:

1。先检查段选择符的TI字段,以决定段描述符保存在

哪一个描述符表中。TI字段指明描述符是在GDT中(在这种情况下, 分段单元从gdtr寄存器中得到GDT的线性基地址)还是在激活的LDT中(在这种情况下, 分段单元从ldtr寄存器中得到ldt的线性基地址)。

2。从段选择符的index字段计算段描述符的地址,index字段的值乘8(一个段描述符的大小),这个结果与gdtr或ldtr寄存器中的内容相加

3。把逻辑地址的偏移量与段描述base字段的值相加得到了线性地址。

(后面的明天再说,掌握前面很重要)

linux中的分段

硬件中的分页

linux中的分页


分享到:


相關文章: