保护模式-内存寻址

好久以前就想系统的学习一下linux源码了,由于懒得一直没有执行,最近终于下定决定开始学习了。

 

首先从保护模式开始吧。

 

1、系统标志寄存器EFLAGS

系统标志寄存器EFLAGS控制这I/O,可屏蔽中断,调试,任务切换以及保护模式和多任务环境下虚拟8086程序的执行。其中系统标志:VM-虚拟8086模式,RF恢复标志;NT-嵌套标志;IOPL-I/O特权标志;IF-中断允许标志。

 

2、控制寄存器

80386共有4个控制寄存器,分别是CR0,CR1,CR2,CR3。

其中控制寄存器CR0含有系统整体的控制标志。其中:

PE - 保护模式开启位(0bit位)。如果设置了该比特位,就会使处理器开始在保护模式下运行。

MP - 协处理器存在标志(1bit位)。用于控制WAIT指令的功能,以配合协处理的运行。

EM - 仿真控制(2bit位)。指示是否需要仿真协处理器的功能。

TS - 任务切换(3bit位)。每当任务切换时处理器就会设置该比特位,并且在解释协处理器指令之前测试该位。

ET - 扩展类型(4bit位)。该位指出了系统中所含有的协处理器类型。

PG - 分页操作(31bit位)。该位指示出是否使用页表将线性地址变换成物理地址。

 

控制寄存器CR1为保留位,暂时不做任何事情。

控制寄存器CR2用于发生页异常时报告出错信息。当发生页异常时,处理器把引起页异常的线性地址保存在CR2中。操作系统中的页异常处理程序可以检查CR2的内容,从而查出线性地址空间中的哪一页引起的本次异常。

控制寄存器CR3用户保存页目录表页面的物理地址,因此被称为PDBR。由于目录是页对齐的,所以仅高20位有效,低12位保留供更加高级的处理器使用。向CR3中装入一个新值,低12位必须为0;但从CR3中取值时,低12位被忽略。每当用MOV指令重置CR3的时候,会导致分页机制高速缓冲区的内容无效,用此方法,可以在启动分页机制之前,即把PG位置1之前,预先刷新分页机制的高速缓存。

 

3、内存管理

内存管理主要涉及处理器的内存寻址机制。80x86使用两步将一个分段形式的逻辑地址转换为实际物理内存地址。

段变换,将一个由段选择符和段内偏移构成的逻辑地址转换为一个线性地址;

页变换,将线性地址转换为对应的物理地址。

在分页机制开启的时候,通过将前面所述的段转换和页转换组合在一起,即实现了从逻辑地址到物理地址的转换。

 

4、段变换

段变换指的是在保护模式下把逻辑地址转换成线性地址的过程。

逻辑地址中的选择符部分是用于指定一描述符的,它是通过指定一描述符表并且索引其中的一个描述符项完成的。选择符中的索引值(3bit位-15bit位)用于选择指定描述符中8192个描述符中的一个。处理器将该值乘以8,并加上描述符表的基地址即可访问表中指定的段描述符。表指示器(TI,2bit位)用于指定选择符所引用的描述符表。0为GDT表,1为LDT表。请求特权级(RPL,0-1bit位)用于保护机制。

所谓的描述符表分为两类:

GDT(全局描述符表)- 通过GDTR寄存器定位的,指令lgdt和sgdt用于访问GDTR寄存器,lgdt使用内存中一个6字节操作数来加载GDTR寄存器。头两个字节代表描述符长度, 后4字节是描述符表的基地址。

LDT(局部描述符表) - 通过LDTR寄存器定位的,指令lldt和sldt用于访问LDTR寄存器,用法基本与GDTR相同,不过lldt指令所使用的操作数却是一个2字节的操作数,表示全 局描述符表GDT中的一个描述符项的选择符。该选择符所对应的GDT表中的描述符项应该对应一个局部描述符表。

在描述符表中存放的是段描述符,段描述符有两种一般格式。取出描述符表中的基地址部分加上逻辑地址中的偏移值的结果,就是我们所需要的线性地址。

 

5、页变换

页变换指的是将段变换形成的线性地址转化成内存中的物理地址。

首先32位的线性地址被分为页目录项(22-31bit位),页表项(12-21bit位),页内偏移值(0-11bit位)。

我们从CR3中获取页目录的基地址加上线性地址中的页目录项,从中获取到页表项的基地址再加上线性地址中的页表项就是我们所需要的页表项。页表项共32位,其中12-31bit位为页框地址,我们把页框地址左移12bit位再加上页内偏移值,就得到该线性地址对应的逻辑地址了。

你可能感兴趣的:(linux)