《深入理解Linux内核》-2.2. 硬件分段

声明: 以下是对原文知识点的提炼总结,并非对照翻译。因为直接翻译并不容易理解。

本节涉及的概念:

linux把内存地址粗略的分为几个区域,分别用作不同的功能,就叫分段。为什么要分段?因为linux进程对不同地址空间的初始化、申请释放、访问权限都不相同,所以要区分对待。

常见的有六种段,它们是大学课程里面就介绍过的:cs、ss、ds、es、fs、gs。我们主要关注前三种段,它们分别是代码段,堆栈段,数据段,这三种段对应了进程空间中的三块地址空间。顾名思义,代码段就是存放代码的区域,该区域对用户是只读的,堆栈段就是栈空间,主要用来存储局部变量,数据段主要用来存放静态数据和全局数据。

比段更细粒度的划分是分页,之后的章节会讲到。

段选择器

逻辑地址由段标识和偏移量组成,段标识是个16位的字段,也叫做段选择器,而偏移量的长度为32位(参考下图中逻辑地址部分)。

段寄存器

段寄存器用来存放段选择器的内容,它的作用是为了更快地获取段选择器。

前面提到常见的六种内存段cs、ss、ds、es、fs、gs,对应这六种段有六种寄存器,它们的名字和它们所对应的段一样。

段描述符

段描述符用来保存每个段的信息,它的长度为64位,其中包含了基地址信息、段属性、访问权限等信息,我们重点关注的是它内部保存的段基地址,这个基地址加上逻辑地址中的偏移就是虚拟地址(参考下图)。

段描述符存储在GDT(全局描述符表)中,或者LDT(局部描述符表)中,我们重点关注GDT。

前面提到常用的有三种段(cs、ss、ds),因此GDT中至少存储了这三个段的描述符。通过GDT可以获取到相应段的描述符,进而通过这个段描述符可以访问具体的段空间。

逻辑地址到虚拟地址的转换

看下图标注数字地箭头1、2、3、4,这就是逻辑地址到虚拟地址的转换过程。

图2-2 逻辑地址到虚拟地址的转换

这里写图片描述

转换过程主要有以下几步:

1、取出逻辑地址中的段选择器部分,根据TI(table indicator)判断段描述符是存储在GDT中还是LDT中。这里我们重点关注GDT。

2、段选择器中的index*8(左移三位)就是段描述符在GDT中的位置,加上GDT的基地址,就是段描述符的地址,从而取出段描述符。

3、段描述符中的保存了该段的基地址(base), 该地址加上逻辑地址中的offset就是虚拟地址,即虚拟地址=base+offset。虚拟地址也叫做线性地址(Linear address)。

猜你喜欢

转载自blog.csdn.net/ybxuwei/article/details/80634207