1、CPU特权级
CPU特权级用于定义处理器执行代码时可访问的系统资源的级别。例如,CPU如果跑的是应用程序的代码,就会限制访问一些资源,如果CPU跑的是操作系统内核的代码,就不会有限制。
程序员在用户程序开发过程中会遇到用户态和内核态两个基本概念,这其实就是CPU特权级。在大多数现代CPU架构中,特别是在X86和X86_64架构中,特权级通常被分为四个级别:
Ring 0: 最高特权级,通常是操作系统的内核代码运行,允许执行所有的CPU指令,并可以直接访问所有的硬件资源。
Ring 1:早期设计中用于操作系统服务或其它特权代码,在现代操作系统中很少使用。
Ring 2:早期设计中用于特定操作系统服务,现代很少使用。
Ring 3:最低特权级,通常由用户程序运行,限制了对某些CPU执行和硬件资源的访问,以防止应用程序破坏系统的稳定性和安全性。
虽然X86架构理论上存在四个特权级别,但大多数操作系统只使用Ring0(内核模式)和Ring3(用户模式)。当一个程序在Ring 3级别运行并尝试执行一个更高权限的操作时,就会触发一个中断,并将控制权交给操作系统的内核,这通常通过系统调用(syscalls)。
特权级的变化通常通过以下机制实现:软件中断、硬件中断、任务切换
CPU特权级分类:
CPL(当前特权级):CS段寄存器的bit0 和 bit1,指明当前进程的特权级
DPL(描述符特权级):段描述符的第二个双字的bit13和bit14,确定该段的特权级。
RPL(请求特权级):段选择子的bit 0和bit 1,确定一个段选择符的请求特权级
如果CPL高于或等于DPL,才可以访问该段,否则不可以。
只有RPL高于DPL才能访问该段描述符,以及只有RPL高于请求资源的特权级才能访问请求资源
2、特权级检验
为了访问数据段中的操作数,就必须将该数据段的段选择符装载入数据段寄存器(DS、ES、FS)或者装载入堆栈寄存器(SS)。处理器将段选择符装载入段寄存器前,它要进行特权级检验,比较当前运行的进程或任务的特权级(CPL),段选择符的(RPL)还有段描述符的DRL。如果DPL的特权值在数值上比CPL和RPL都大或相等,处理器会将段选择符装载入段寄存器。否则,处理器会产生一个通用保护错,并且不会装载寄存器。
即:处理器正在处理的任务或程序有一个特权级CPL存储在段寄存器中,段选择子有一个请求特权级RPL,存储在段寄存器中,段描述符有一个段特权级(描述符特权级)DPL,只有CPL和RPL的特权级高于DPL才能访问所对应的内存段。
3、计算资源特权级
有时计算机资源特权级跟CPU特权级是同样的概念。
每个计算机资源都被贴上了标签,即计算机资源特权级,只有CPU特权级比这个计算资源特权级高或同等的时候,才能访问这个计算机资源。计算机资源的特权级被分为内存特权级和IO设备特权级,内存特权级又分为内存段特权级和核心数据结构特权级。
开发人员编写的用户程序通常会进行系统调用,因此一个完整的应用程序,既包含应用程序代码也包含内核的代码和数据。如果应用程序请求其它特权级下的计算资源,势必会调用其它特权级下的代码段、数据段、栈,将其它特权级下的代码段、数据段、栈段链接进来。因此,每个用户程序下的每个特权级下有各自的代码段、数据段、栈段。
内核代码段、数据段、栈段在计算机启动的时候,由内核自己设置为特权级0,其它特权级下计算机资源加载到内存,由操作系统决定它们的特权级。计算机资源的特权级储存在描述符里。
每个描述符有8个字节,分为段描述符和门描述符:
- 描述符 (Descriptor)
- 段描述符 (Segment Descriptor)
- 门描述符 (Gate Descriptor)
- 任务门描述符 (Task Gate Descriptor)
- 中断门描述符 (Interrupt Gate Descriptor)
- 陷阱门描述符 (Trap Gate Descriptor)
- 调用门描述符 (Call Gate Descriptor)
描述符存储在描述符表中,每个描述符表可以存储8192个描述符,占用的空间为8192*8=65536字节=64kb
由寄存器中的段描述符表的地址和索引(选择子或中断向量)就可以在描述符表中找到相应的描述符了。
段描述符的简化格式:
段特权级由操作系统根据程序类型分配。
门描述符的简化格式: