![e445bef5c5b66e10f7001d7e3a4f12b2.png](https://img-blog.csdnimg.cn/img_convert/e445bef5c5b66e10f7001d7e3a4f12b2.png)
序:ICS(袁春风)教材相比csapp在虚拟存储上多出了IA32+Linux的地址转换案例。本文作为csapp的补充复习资料。
在机器开机过程中,系统总是先进入实地址模式,首先进行初始化,之后转入保护模式。IA-32采用段页式虚拟存储管理方式。
![5f9fc908092d84c353e5d61ba94378cf.png](https://img-blog.csdnimg.cn/img_convert/5f9fc908092d84c353e5d61ba94378cf.png)
这里48位逻辑地址为: 段选择符(16位)+ 有效地址(32位)
逻辑地址到线性地址的转换为分段机制,线性地址到物理地址的转换为分页机制。
分段机制
这里首先复习硬件层面如何分段的:
IA-32为实现分段机制(以及中断异常处理)增添如下两类寄存器组:
- 段寄存器:CS(code)、SS(stack)、DS(data)、ES、FS、GS
- 一些用户不可见寄存器:描述符cache、TR(任务寄存器)、LDTR(局部描述符表寄存器)、(GDTR)全局描述符表寄存器、IDTR(中断描述符表寄存器)
IA-32对段页以及中断异常处理所涉及到的地址转换均采用一种利用表索引的方法。抽象来说具有如下几个概念:
- 描述符:一种数据结构。不同描述符号符有不同定义,但通常有地址项权限项。
- 描述符表:描述符组成的表项。
- 选择符:一种数据结构,其中最关键的数据为描述符的索引。因此可以通过选择符找到对应的描述符。
- 描述符表寄存器:存放描述符表的首地址,可能是线性地址也可能是物理地址。
对于分段机制而言,有自己独特的描述符,描述符表和选择符。
1.段选择符 | [15:3]索引 | [2]TI | [1:0] RPL |
- TI:0表示选择全局描述符表(GDT),1表示选择局部描述符表(LDT)。
- RPL:特权级,00表示内核态,11表示用户态。
段选择符存放在段寄存器中,其中CS段寄存器的RPL为CPL,即Current Privilege Level。今后比较用户代码是否越权都是拿CPL进行比较。
2.段描述符
是分段下的段表项,具有如下数据结构:
![c134890069e4197ca9157d8333a880a6.png](https://img-blog.csdnimg.cn/img_convert/c134890069e4197ca9157d8333a880a6.png)
- G:粒度。1表示段以4KB为基本单位,0表示以字节为基本单位。
- 限界依据G的值来定。G=0 最大1MB,G=1最大4GB。
- S:指出了段表述符的类型,0表示是系统控制段描述符,1表示普通的段描述符。
- DPL:访问段的最低权限,需要和CPL比较,当CPL>DPL时,说明当前特权级比所要求的最低等级更低,故访问越级。
- A:该段是否被访问过。D:数据位宽。32位置1。
3.段描述符表
分为全局描述符表(GDT),局部描述符表(LDT)和中断描述符表(IDT)。GDT系统中唯一,存放各种描述符,LDT存放用户进程专用的描述符。在IA-32的设计中,LDT的寻找也是通过GDT来的,GDT表项中有一个LDT描述符,存放了LDT首地址,访问权限等信息,因此IDTR(16位寄存器)存放的应该位LDT选择符。不同的是GDTR存放了GDT首地址以及限界。
有了上述硬件的实现,逻辑地址到线性地址的转换就很简单了。线性地址=有效地址+段基址。
![af2247908514e75a8a7afb725098b97e.png](https://img-blog.csdnimg.cn/img_convert/af2247908514e75a8a7afb725098b97e.png)
Linux分段机制
采用扁平模式,所有段的基址均为0,所以其有效地址的值就是线性地址。并对代码段和数据段进行了划分。
![5f25819377c25a27ff708fdac4ecb03a.png](https://img-blog.csdnimg.cn/img_convert/5f25819377c25a27ff708fdac4ecb03a.png)
分页机制
IA-32为实现段页机制添加如下控制寄存器:
CR0控制寄存器:
- PE:0表示在实地址模式,1表示在保护模式。
- PG:分页允许位。
- TS:任务切换位。
- AM:对齐屏蔽位。
- NW,CD:cache功能控制位。(均为0时cache才能工作)
CR2页故障线性地址寄存器,存放缺页异常的线性地址。
CR3页目录基址寄存器,存放页目录表在内存的起始地址。
采用两级页表分页机制
![8a4a4ed81368a247ef0a95ca73c18505.png](https://img-blog.csdnimg.cn/img_convert/8a4a4ed81368a247ef0a95ca73c18505.png)
每个页目录项和页表项格式一样,有32位。
![f0d5df04ac3b92bc816d8eea4f155d59.png](https://img-blog.csdnimg.cn/img_convert/f0d5df04ac3b92bc816d8eea4f155d59.png)
- P:1表示页表或页在主存中;P=0表示页表或页不在主存,即缺页,此时需将页故障线性地址保存到CR2。
- R/W:0表示页表或页只能读不能写;1表示可读可写。
- U/S:0表示用户进程不能访问;1表示允许访问。
- PWT:控制页表或页的cache写策略是全写还是回写。
- PCD:控制页表或页能否被缓存到cache中。
- A:1表示指定页表或页被访问过,初始化时操作系统将其清0。利用该标志,操作系统可清楚了解哪些页表或页正在使用,一般选择长期未用的页或近来最少使用的页调出主存。由MMU在进行地址转换时将该位置1。
- D:修改位(脏位)。页目录项中无意义,只在页表项中有意义。初始化时操作系统将其清0,由MMU在进行写操作的地址转换时将该位置1。
- 高20位是页表或页在主存中的首地址对应的页框号,即首地址的高20位。每个页表的起始位置都按4KB对齐。