X86汇编语言-从实模式到保护模式—笔记(37)-第14章 任务和特权级保护(3)
本帖最后由 兰陵月 于 2017-12-15 12:21 编辑14.1.3特权级保护概述引入LDT和TSS只相当于构建了可靠的硬件设施,但规章制度还没建立起来。为此,在分段机制的基础上,处理器引入了特权级,并由固件负责实施特权级保护。特权级(Privilege Level),也叫特权级别,是存在于描述符及其选择子中的一个数值,当这些描述符或者选择子所指向的对象要进行某种操作,或者被别的对象访问时,该数值用于控制它们所能进行的操作,或者限制它们的可访问性。Intel处理器可以识别4个特权级别,分别是0到3,较大的数值意味着较低的特权级别,反之亦然。图14-004为Intel处理器提供的4级环状保护结构示意图。
通常,因为操作系统是为所有程序服务的,可靠性最高,而且必须对软硬件有完全的控制权,所以它的主体部分必须拥有特权级0,并处于整个环形结构的中心。也正是因为这样,操作系统的主体部分通常又被称做内核(Kernel、Core)。特权级1和2通常赋予那些可靠性不如内核的系统服务程序,比较典型的就是设备驱动程序。当然,在很多比较流行的操作系统中,驱动程序与内核的特权级别相同,都是0。应用程序的可靠性被视为是最低的,而且通常不需要直接访问硬件和一些敏感的系统资源,调用设备驱动程序或者操作系统例程就能完成绝大多数工作,故赋予他们最低的特权级别3。实施特权级保护的第一步,是为所有可管理的对象赋予一个特权级,以决定谁能访问它们。每个描述符都有一个两比特的DPL字段,可以取值为00、01、10、11,分别对应特权级0、1、2和3。DPL是每个描述符都有的字段,故又称为描述符特权级(Descriptor Privilege Level)。描述符总是指向它所描述的目标对象,代表着该对象,因此,该字段实际上是目标对象的特权级。比如,对于数据段来说,DPL决定了访问它们所应当具备的最低特权级别。如果有一个数据段,其描述符的DPL字段为2,那么,只有特权级0、1、2的程序才能访问它。当一个特权级为3的程序也试图去读写该段时,将会被处理器阻止,并引发异常中断。对任何段的访问都要先把它的描述符加载到段寄存器,所以这种保护手段很容易实现。在实模式下,段寄存器存放的是段地址;而在保护模式下,段寄存器存放的是段选择子,段地址则位于描述符高速缓存器中。当处理器正在一个代码段中取指令和执行指令时,那个代码段的特权级叫做当前特权级(Current Privilege Level,CPL)。正在执行的这个代码段,其选择子位于段寄存器CS中,其最低两位就是当前特权级的数值。【知识点复习:选择子的最低两位叫做RPL,RPL是请求特权级,表示给出当前选择子的那个程序的特权级别,正是该程序要求访问这个内存段。】比如,在当前代码段code中,有一句指令mov ax,0x000B mov ds,ax从选择子可以看出其最低两位值为11,即3,也就是说RPL=3。这个选择子是由code段给出的,因此code段的特权级别是3。code段的CPL在CS寄存器中,其肯定也是3。一般来说,操作系统是最先从BIOS那里接收处理器控制权的,进入保护模式的工作也是由它做的,而且,最重要的是,它还肩负着整个计算机系统的管理工作,所以,它必须工作在0特权级别上,当操作系统的代码正在执行时,当前特权级CPL就是0。相反,普通的应用程序则工作在特权级别3上。没有人愿意将自己的程序放在特权级3上,但是,只要你在某个操作系统上面写程序,这就由不得你。应用程序编写时,不需要考虑GDT、LDT、分段、描述符这些东西,它们是在程序加载时,由操作系统负责创建的,应用程序的编写者只负责具体的功能就可以了。应用程序的加载和开始执行,也是由操作系统所主导的,而操作系统一定会把它放在特权级3上。当应用程序开始执行时,当前特权级CPL自然就会是3。这实际上就是把一个任务分成特权级截然不同的两个部分,全局部分是特权级0的,而局部空间则是特权级3的。这种划分是有好处的,全局空间是为所有任务服务的,其重要性不言而喻。为了保证它的安全性,并能够访问所有软硬件资源,应该使它拥有最高的特权级别。当任务在自己的局部空间内执行时,当前特权级CPL是3;当它通过调用系统服务,进入操作系统内核,在全局空间还行是时,当前特权级CPL就变成了0。总之,很重要的一点,不能僵化地看待任务和任务的特权级别。不同特权级别的程序,所担负的职责以及在系统中扮演的角色是不一样的。计算机系统的脆弱性在于一条指令就能改变它的整体运行状态,比如停机指令hlt和对控制寄存器CR0的写操作,像这样的指令只能由最高特权级别的程序来做。因此,那些只有在当前特权级CPL为0时才能执行的指令,称为特权指令(PrivilegedInstructions)。典型的特权指令包括加载全局描述符表的指令ldgt(它在实模式下也可执行)、加载局部描述符表的指令lldt、加载任务寄存器的指令ltr、读写控制寄存器的mov指令、停机指令hlt等十几条。除了那些特权级敏感的指令外,处理器还允许对各个特权级别所能执行的I/O操作进行控制。通常,这指的是端口访问的许可权,因为对设备的访问都是通过端口进行的。在处理器的标志寄存器EFLAGS中,位13、位12是IOPL位,也就是输入/输出特权级(I/O Privilege Level),它代表着当前任务的I/O特权级别。任务是由操作系统加载和创建的,与任务相关的信息都在它自己的任务状态段(TSS)中,其中就包括一个EFLAGS寄存器的副本,用于指示与当前任务相关的机器状态,比如它自己的I/O特权级IOPL。在多任务系统中,随着任务的切换,前一个任务的所有状态被保存到它自己的TSS中,新任务的各种状态从其TSS中恢复,包括EFLAGS寄存器的值。处理器不限制0特权级程序的I/O访问,它总是允许的。但是,可以限制低特权级程序的I/O访问权限。操作系统不希望应用程序拥有私自访问外设的能力。
页:
[1]