清华操作系统课--Lab2--内存管理1(x86特权级和特权级切换过程)

~x86 特权级:操作系统+CPU实现保护机制,应用程序不能随意访问OS空间

~x86 MMU 内存管理单元:实现内存的映射,将虚拟的连续的逻辑地址空间投射到分散的物理空间。

1. x86 特权级:(关键:几种特权级/处于什么特权级,如何知道/特权级切换的实现)
    ~有0,1,2,3四个特权级,level0:kernel,level3:applications,

    Linux一般用0和3两个级别足够。

    应用程序在访问数据段,访问页表,进入中断服务例程(ISRs),检查失败会产生访问错误。

    如何进行特权级检查:

    段选择子 Segment Selector 位于段寄存器中,

    RPL 位于数据段, CPL位于代码段,结合起来与段描述符中的DPL 进行比较。

段描述符:表示一个段的特征,DPL表示了这个数据段或代码段的特权级。将RPL(CPL)和DPL进行比较,看特权级是否符合。

中断门,陷阱门和段描述符都有对应的DPL,产生中断,发生陷入或者访问内存的时候会产生对应的RPL(CPL)

RPL 位于段寄存器 DS ES FS GS

CPL 位于 段寄存器 CS SS

发出请求方:当前代码段的特权级(CPL) 要数据的特权级(RPL)

(接受)访问段:中断——访问代码段,内存访问——数据段。都有一个DPL(表示了访问目标的特权级)

访问门时: CPL <= DPL(门) &  CPL >= DPL(段)(访问门时,代码段的CPL 要小于 门,可以通过门,通过门后要访问特权级高的代码。

访问段时:MAX(CPL,RPL)<= DPL(段) 使用方 特权级要高才能访问。

~特权级的切换

基于中断实现特权级的转换:

中断:

    中断描述符表建立中断门

    产生中断(异常,外中断,软中断)后,内核栈压入了SS ES(被打断的程序堆栈信息)EFLAGS(标志位,是否溢出,+/-等) CS EIP(返回继续执行的代码地址) Error Code(错误代码)  这个栈是内核态ring0的栈。

如图:

特权级的转换:

        如何实现ring0到ring3转换?

        构造一个用户态的栈

        内核程序发生中断:将Error Code EIP CS(CPL=0)EFLAGS压入内核栈,不存在栈的转换。

运行在ring0的程序发生中断

       

     使其返回到用户空间:模仿ring3产生中断时候的现场:将CS代码段的CPL寄存器改变为3:

     

    执行指令iret,就可以跳回用户态。同时形成新的栈:   
   

~ ring3 to ring0 

正在执行的进程

      

发生中断

  通过对内核栈的修改:

     

    执行IRET指令,依然返回到ring0

_________

Q:从用户态转换到内核态执行时候,如何找到CS SS位于什么位置?

CS EIP 表明指令地址:中断描述符表中可以找到。

堆栈信息在什么地方? IDT中没有,而在TSS(task state segment)任务状态段:保存了各种特权级的堆栈信息。

保存了3个特权级的堆栈信息,CPU 根据CS SS 设置新的堆栈。

因此,当进程从用户态进入内核态后,CS EIP的值根据 IDT 设置,SS ESP的值根据TSS设置。

OS 需要设置好 IDT 和 TSS的信息。

TSS表位于内存中,获得的方式如下:
使用GDT,GDT中有TSS Descriptor:

TSS Descriptor 中保存了TSS的地址,从而可以找到TSS内容。

IDT TSS GDT 需要OS软件去填写。

在GDT表中建立好TSS Descriptor之后,设置一个特殊的寄存器 Task Register,保存段选择子,基地址等信息。

通过找Task Register 或者 GDT 表都可以找到TSS内容。

分配内存——初始化(特别是设置SS0 ESP0)——GDT中填写TSS 描述符——设置TSS selector(Task Register)

猜你喜欢

转载自blog.csdn.net/lgq0409/article/details/85340833
今日推荐