Intel CPU的保护模式 来龙去脉
1为什么要使用cpu的保护模式呢?
经常有不懂的人会问我这个问题,第一次我也被问住了,只是在看cpu是如何实现的,可却从来没有真正的跳出来思考过,cpu的保护模式带给我们什么好处?
答:我非常总结的说一下。保护模式主要目的保护多任务之间代码访问的完全隔离(使用虚拟地址),单任务的用户代码和系统代码的访问格式(使用cpu的privilege环)。当然虚拟地址也给内存管理带来了其他的好处,更细节的看下面的文章转载。
2 为什么一定要从实模式切换到保护模式,而不是开机就是保护模式?
最主要的原因是:兼容以前的软件,不兼容以前的软件就会失去市场,所以intel处理器发展到今天回如此的复杂。
+++++++++++++++++++++++++++++++++++++++++++++++++++
转载于:http://blog.sina.com.cn/s/blog_511703010100m1yp.html
已经比较了解intel cpu保护模式的人,会觉得下面这篇文章写得确实不错。
Intel CPU的保护模式简介(一)
保护模式
x86有三种工作方式:实模式,保护模式和虚拟x86模式。尽管实方式下x86的功能要大大超过其先前的处理器(8086/8088,80186,80286),但只有在保护方式下, x86才能真正发挥更大的作用。在保护方式下,全部32条地址线有效,可寻址高达4G字节的物理地址空间;扩充的存储器分段管理机制和可选的存储器分页管理机制,不仅为存储器共享和保护提供了硬件支持,而且为实现虚拟存储器提供了硬件支持;支持多任务,能够快速地进行任务切换和保护任务环境;4个特权级和完善的特权检查机制,既能实现资源共享又能保证代码和数据的安全和保密及任务的隔离;支持虚拟8086方式,便于执行8086程序。
(1)存储管理机制
为了对存储器中的程序及数据实现保护和共享提供硬件支持,为了对实现虚拟存储器提供硬件支持,在保护方式下, x86不仅采用扩充的存储器分段管理机制,而且提供可选的存储器分页管理机制。这些存储管理机制由x86存储管理部件MMU实现。
1.目标
x86有32根地址线,在保护方式下,它们都能发挥作用,所以可寻址的物理地址空间高达4G字节。在以x86及其以上处理器为CPU的PC兼容机系统中,把地址在1M以下的内存称为常规内存,把地址在1M 以上的内存称为扩展内存。
x86还要对实现虚拟存储器提供支持。虽然与8086可寻址的1M字节物理地址空间相比,x86可寻址的物理地址空间可谓很大,但实际的微机系统不可能安装如此达的物理内存。所以,为了运行大型程序和真正实现多任务,必须采用虚拟存储器。虚拟存储器是一种软硬件结合的技术,用于提供比在计算机系统中实际可以使用的物理主存储器大得多的存储空间。这样,程序员在编写程序时不用考虑计算机中物理存储器的实际容量。
x86还要对存放在存储器中的代码及数据的共享和保护提供支持。任务甲和任务乙并存,任务甲和任务乙必须隔离,以免相互影响。但它们又可能要共享部分代码和数据。所以,80386既要支持任务隔离,又要支持可共享代码和数据的共享,还要支持特权保护。
2.地址空间和地址转换
保护方式下的虚拟存储器由大小可变的存储块构成,这样的存储块称为段。x86采用称为描述符的数据来描述段的位置、大小和使用情况。虚拟存储器的地址(逻辑地址)由指示描述符的段选择子和段内偏移两部分构成,这样的地址集合称为虚拟地址空间。程序员编写程序时使用的存储地址空间是虚拟地址空间,所以,他们可认为有足够大的存储空间可供使用。
显然,只有在物理存储器中的程序才能运行,只有在物理存储器中的数据才能访问。 因此,虚拟地址空间必须映射到物理地址空间,二维的虚拟地址必须转化成一维的物理地址。由于物理地址空间远小于虚拟地址空间,所以只有虚拟地址空间中的部 分可以映射到物理地址空间。由于物理存储器的大小要远小于物理地址空间,所以只有上述部分中的部分才能真正映射到物理存储器。
每一个任务有一个虚拟地址空间。为了避免多个并行任务的多个虚拟地址空间直接映射到同一个物理地址空间,采用线性地址空间隔离虚拟地址空间和物理地址空间。线性地址空间由一维的线性地址构成,线性地址空间和物理地址空间对等。线性地址32位长,线性地址空间容量为4G字节。
x86分两步实现虚拟地址空间到物理地址空间到物理地址空间的映射,也就是分两步实现虚拟地址到物理地址的转换,但第二步(分管理机制)是可选的。
通过段描述符表和段描述符,分段管理机制实现虚拟地址空间到线性地址空间的映射,实现把二维的虚拟地址转换为一维的线性地址。这一步总是存在的(分段管理机制)。
分页管理机制把线性地址空间和物理地址空间分别划分为大小相同的块,这样的块称为页(一般为4KB)。通过在线性地址空间的页与物理地址空间的页之间建立的映射表,分页管理机制实现线性地址空间到物理地址空间的映射,实现线性地址到物理地址的转换。分页管理机制是可选的,在不采用分页管理机制时,线性地址空间就等同于物理地址空间,线性地址就等于物理地址。
分段管理机制所使用的可变大小的块,分段管理机制比较适宜处理复杂系统的逻辑分段。存储块的大小可以根据适当的逻辑含义进行定义,而不用考虑固定大小的页 的人为限制。每个段可作为独立的单位进行处理,以简化段的保护及共享。分页机制使用的固定大小的块最适合于管理物理存储器,无论是管理内存还是外存都同样 有效。分页管理机制能够有效地支持实现虚拟存储器。
段及分页这两种机制是两种不同的转换机制,是整个地址转换函数的不同的转换级。虽然两种机制都利用存储在主存储器中的转换表,但这些表具有独立的结构。事实上,段表存储在线性地址空间,而页表存储在物理地址空间(物 理存储器)。段转换机制把虚拟地址转换为线性地址,并在线性地址中访问段转换机制的表格,而不会觉察分页机制已把线性地址转换为物理地址。类似地,分页管 理机制只是直接地把线性地址转换为物理地址,并且在物理地址中访问转换表格,并不知道虚拟地址空间的存在,甚至不知道段转换机制的存在。
3.虚拟存储器概念
虚拟存储器是一种设计技术,用于提供比在计算机系统中实际可以使用的物理主存储器大得多的存储空间。使用者会产生一种错觉,好象在程序中可以使用非常大的物理存储空间。使用虚拟存储器的好处是:一个程序可以很容易地在物理存储器容量大不一样的、配置范围很广的计算机上运行;编程人员使用虚拟存储器可以写出比任何实际配置的物理存储器都大得多的程序。虚 拟存储器由存储管理机制及一个大容量的快速硬盘存储器支持。在程序运行的任何时刻,只把虚拟地址空间的一小部分映射到主存储器,其余部分则存储在磁盘上。 因为只有存储在主存储器中的部分虚拟存储器可由处理器使用,这种虚拟存储技术将依赖程序内部访问存储器的局部化特性,在程序执行中只需整个虚拟存储器中的 少量存储内容在主存储器中驻留。而当访问存储器的范围发生变化时,有必要把虚拟存储器的某些部分从磁盘调入主存储器,虚拟存储器的另外的部分,也能从主存 储器传送回磁盘上。
地址转换机制以两种方式支持虚拟存储器。
第一,把实际驻留在主存储器中的那部分虚拟存储器标记为无效,并建立起虚拟存储器驻留部分的虚拟-- 物理映射关系,把驻留部分的相应虚拟存储器地址,转换为对应物理存储器的地址。如果程序访问的虚拟地址对应于虚拟存储器未驻留的部分,将由于无效映射信息而引起异常。操作系统通过把未驻留部分从磁盘上读入到主存储器中,来处理这种异常,并根据需要更新地址转换表。在引起异常的原因排除以后,异常处理程序完成异常事件的处理,并返回原来的程序恢复执行。在后面的文章中将会看到,从异常处理程序返回后,这时要重新执行一次原来引起异常的指令,而该指令在后一次执行时自然会成功地完成。
第二,地址转换机制通过收集驻留在主存储器中的虚拟存储器部分的使用统计信息来支持虚拟存储器,这些使用统计信息,在主存储器空间紧缺时,帮助操作系统决定可以将哪些部分传送回磁盘。Intel CPU的保护模式简介(二)
(2)保护机制
为了支持多任务,对各任务实施保护是必需的。从80286开始,处理器就具备了保护机制。保护机制能有效地实现不同任务之间的保护和同一任务内的保护。
1.不同任务之间的保护
保护的一个重要方面是应用程序之间的保护。虚拟地址到物理地址的映射函数在每个任务中进行定义,随着任务切换,映射函数也切换。任务A的虚拟地址空间映射到物理地址空间的某个区域,而任务B的虚拟地址空间映射到物理地址空间的另外区域,彼此独立,互不相干。因此,两个不同的任务,尽管虚拟存储单元地址相同,但实际的物理存储单元地址可以不同。
每个任务各有一组独立的映射表,即具有不同的地址转换函数。在x86上, 每个任务都有自己的段表及页表。当处理器进行切换并执行新的任务时,这种任务切换的一个重要部分,就是为新任务切换任务的转换表。为了使操作系统与所有的 应用程序相隔离,可以把操作系统存储在一个单一的任务中。然而,我们即将看到,在一个任务内操作的保护机制,更适合于保护操作系统,使其不被应用程序破 坏。这种机制,使操作系统由所有任务共享,并且可在每一任务中对其进行访问,而且仍然保护了操作系统,使其不被应用程序破坏。这种保护操作系统的方法,是 把操作系统存储在虚拟地址空间的一个公共区域,然后,再使每一任务按此区域分配一个同样的虚拟地址空间,并进行同样的虚拟--物理地址映射。各个任务公用的这部分虚拟地址空间,被称为全局地址空间。
仅由一个任务占有的虚拟地址空间部分,即不被任何其它任务共享的虚拟地址部分,称为局部地址空间。局部地址空间包含的代码和数据,是任务私有的,需要与系统中的其它任务相隔离。
每个任务中有不同的局部地址空间。因此,两个不同的任务中,对同一虚拟地址的访问,实际上转换为不同的物理地址。这就使操作系统对每个任务的存储器,可以赋予相同的虚拟地址,仍然保证任务的隔离。另一方面,对全局地址空间中同一虚拟地址的访问,在所有任务中都转换为同样的物理地址,从而支持公共的代码及数据的共享,例如对操作系统的共享。
2.同一任务内的保护
在一个任务之内,定义有四种执行特权级别,用于限制对任务中的段进行访问。按照包含在段中的数据的重要性和代码的可信程度,给段指定特权级别。把最高的特 权级别分配给最重要的数据段和最可信任的代码段。具有最高特权级别的数据,只能由最可信任的代码访问。给不重要的数据段和一般代码段分配较低的特权级别。 具有最低特权级别的数据,可被具有任何特权级别的代码访问。
特权级别用数字0、1、2和3表示,数字0表示最高特权级别,而数字3表示最低特权级别,即数字较大的级别具有较低的特权。为了避免模糊和混淆,在比较特权级别时,不使用“大于”或“小于”这样的术语,而使用“里面”或“内层”这样的术语表示较高特权级,级别的数字较小;使用“外面”或“外层”这样的术语表示较低特权级别,级别的数字较大。0级为最内层的特权级别,3级为最外层的特权级别。
每一特权级都有各自独立的程序堆栈,以避免与共享栈区有关的保护问题。当一个程序从一个特权级切换到另一个特权级执行时,程序使用的堆栈,从原特权级的栈段改变为新特权级的栈段。对于堆栈段寄存器 SS来说,描述符特权级(DPL)必须等于当前代码段的特权级(CPL)。从一个特权级切换到另一特权级的方法将在控制转移方法一文中描述。
每个存储器段都与一个特权级别相联系。特权级别限制是指,只有足够级别的程序,才可对相应的段进行访问。在任何时候,一个任务总是在四个特权级之一下运行,任务在特定时刻的特权级称为当前特权级 (Current Privilege level),标记为CPL,即当前运行程序的特权级。每当一个程序试图访问一个段时,就把CPL与要访问的段的特权级进行比较,以决定是否允许这一访问。对给定CPL执行的程序,允许访问同一级别或外层级别的数据段。
虽然应用程序都在最外层,但由于各个不同的应用程序存储在不同的虚拟地址空间中,所以各应用程序被隔离保护。