整理的不好,凑合着看吧
目录
1.内存及寻址
2.地址变换
3.分段机制
4.分页机制
5.保护
6.去到底部
一、内存及寻址
二、地址变换
80X86 从 逻辑地址 到 物理地址 的转换:第一阶段是使用分段机制把程序的 逻辑地址变换成处理器可寻址的内存空间(称为线性地址空间)中的地址。 第二阶段使用分页机制把线性地址转换为物理地址。 在地址变换的过程中, 第一阶段的分段变换机制总是使用,第二阶段的分页机制是可选的,如果没有启用分页机制,那么分段机制产生的线性地址空间就直接映射到处理器的物理地址空间上。物理地址空间定义为处理器在其总线上能够产生的地址范围。
三、分段机制
上图的分段机制,把处理器可寻址的地址空间划分成一些较小的称为段的受保护的地址空间区域。 用能够用来存放 程序代码、数据和堆栈,或者是系统的数据结构。运行多个程序的时候,给每个程序分配各自的段,确保各个程序不会互相干扰。 还可以对断进行分类,对不同类型的段分配不同的权限。
系统中所有使用的段都包含在处理器的线性地址空间中。 需要定位段中的某一个字节(这个就是寻址)的时候,程序必须要提供一个逻辑地址。 逻辑地址包含 一个段选择符 和一个偏移量 。
段选择符是在系统中是唯一的,在段选择符中提供了 段描述符的偏移量,段描述符是段描述符表中的一个数据结构。 每一个段都有一个段描述符,说明了 段的大小 、访问权限、 段的特权机、 段类型 和 段的基地址(段的第一个字节在星星地址空间中的位置,也叫段地址)
逻辑地址的偏移量(即偏移地址)加上段地址就可以定位到段中某一个字节的位置。 因此 段地址 + 偏移地址 就是处理器线性地址空间中的地址(线性地址)。
线性地址和物理地址具有相同的数据结构,对于两维的逻辑地址空间来说(为什么是两维? 段地址和偏移地址各算一维吗?), 它们都是一维的。
虚拟地址(逻辑地址)空间最多只能有 16k个段(2^14= 16348个段)分为两部分,前一半为全局地址空间,后一半为局部地址空间,每个段最长为 4GB ,这样虚拟地址空间最大就可以达到 64TB(2^14 ? 2^32 = 2^46)。
线性地址空间和物理地址空间都是 4GB 。 如果禁用了分页机制,那么线性地址空间就是物理地址空间。(实地址模式就是如此的吧!)
四 、 分页机制
多任务系统通常定义的线性地址空间比实际的物理内存大很多, 所以需要使用某种“虚拟化”线性地址空间的方法,即虚拟存储技术。 虚拟存储是一种内存管理技术,使用这种技术可以让编程人员产生内存空间要比实际物理内存大很多的错觉。
分页机制支持虚拟存储技术。使用小块的物理内存(RAM 或 ROM)和某些外部存储空间(如硬盘)来模拟大容量的线性地址。 把每个段划分成相同大小(通常每页为 4KB)的页,操作系统维护着一个页目录和一些页表,当程序要访问线性地址空间中的某一个位置时,处理器就会根据页目录和页表把线性地址转换成一个物理地址,然后就可以在该内存位置上进行读写操作了。 如果当前被访问的页面不在物理内存中,处理器就会产生一个页错误异常来中断程序的执行,然后操作系统就可以从硬盘上把该页面读入物理内存中,并继续执行被中断的程序。如果操作系统严格地实现了分页机制,那么对于正确 执行的程序来说页面在物理内存和硬盘之间的交换就是透明的。
分页机制使用了大小固定的内存块,而分段机制使用了大小可变的内存,不管在物理内存上还是在硬盘上,分页使用固定大小的块更为适合物理内存,分段机制使用大小可变的块更为适合处理复杂系统的逻辑分区,可以定义与逻辑块大小适合内存单元而不用受到固定大小的页面的限制,每个段都可作为一个单元来处理,简化了段的保护和共享。
五、 保护
80X86支持两类保护: 任务之间的保护 和 特权级保护。
1. 任务之间的保护:给每个任务不同的逻辑地址空间来完全隔离各个任务,通过把每个任务的逻辑地址映射到不同的物理地址来实现 。
把每个任务放在不同的虚拟地址空间中,并对每个任务设置不同的 逻辑地址到物理地址变换映射的方式,一个任务的逻辑地址被映射到物理内存的一部分区域,另一个任务的逻辑地址又被映射到物理内存的另一个区域。 一个任务的逻辑地址不会映射到 其它任务的逻辑地址 所映射的那一片物理内存区域,这样所有的任务都被隔绝开了。 只需要给每个任务各自独立的映射表,每个任务就会有不同的地址变换函数。在80X86中,每个任务都有自己的段表和页表,当处理器切换去执行一个新的任务时,任务切换的关键就是切换到新任务的变换表。
在所有任务中安排相同的虚拟地址到物理地址映射部分,并且把操作系统存储在这个公共的虚拟地址空间部分,就实现了操作系统可以被所有任务共享。这个被所有任务都具有的 相同虚拟地址空间部分叫做全局地址空间。这也是现代Linux操作系统使用虚拟地址空间的部分。
每个任务唯一的虚拟地址空间叫做局部地址空间 。局部地址空间含有需要与系统中其它任务区别开的私有的代码和数据。由于每个任务具有不同的局部地址空间,因此两个不同的任务对相同虚拟地址处的引用将转换到不同的物理地址。 这就是操作系统可以给 每个任务相同的虚拟地址,但仍然能隔绝每个任务。 另一方面,所有任务在全局地址空间中对相同虚拟地址的的引用将被转换到同一个物理地址,这就给公共代码和数据(如操作系统)的共享提供了支持。
- 特权级保护
在一个任务中,定义了 4 个执行特权级,用来 依据段中含有的数据的敏感度 和 任务中不同程序部分的 受信程度,来限制对任务中各段的访问。最敏感的数据被赋予最高特权级,它们只能被任务中最受信任的部分访问。不太敏感的数据被赋予较低的特权级,它们可以被任务中较低特权级的代码访问。
特权级用数字 0 到 3 表示, 0 具有最高特权级,而 3 则是最低特权级。每个内存段都与一个特权级相关联。 这个特权级限制了只有具有足够特权级的程序才能访问这个段。 处理器从 CS 寄存器指定的段中取得和执行指令,当前特权级即CPL 就是当前活动代码段的特权级,它定义了当前所执行程序的特权级别,确定了哪些段能够被程序访问。
每当程序企图访问一个段时,当前特权级就会与段的特权级进行比较,以确定是否有访问许可。 在给定的 CPL 级别上执行的程序 能够访问同级别或低级别的数据段, 任何对高级别段的引用都是非法的,并且会引发一个异常来通知操作系统。 每个特权级都有自己的程序栈,以避免使用共享栈带来的保护问题。当程序从一个特权级切换到另一个特权级上执行时,堆栈段也随着改变到新级别的堆栈中。