特权级初步----特权级概念与TSS
特权级初步----特权级概念与TSS
1:什么是特权级?有什么用?
从主动和被动的角度来看,整个计算机世界可以分为两个部分,即访问者和被访问者。访问者是动态的,具有能动性,它主动访问各种资源。受访问者是静态的,它就是被访问的资源。访问者的特权级别可以变,受访者的特权不能变。
建立特权机制是为了通过特权来检查合法性,整个计算机世界的特权检查,都是发生在访问者访问受访者的一刹那,实际上就是检查访问者和受访者的特权级是否匹配。
当前特权级就是指CPU的状态,特权级按照权力大小分为0,1,2,3。数字越小,权力越大。0特权级是操作系统内核所在的特权级,计算机启动之初就在0特权级运行,像MBR(主引导记录)就运行在0特权级下。内核直接控制硬件,位于0特权级,1,2特权级是一些系统程序,比如驱动程序,虚拟机,用户程序位于3特权级。
2:TSS(Task State Segment)任务状态段简介
TSS是一种数据结构(线性表),它用于存储任务的环境。是CPU在硬件上原生支持多任务的一种方式,处理器厂商原本是想让操作系统厂商用此方式来实现多任务的。只不过像linux就没有完全采用这种方式。它的内部是寄存器映像,就是很多寄存器,还有上一个任务的TSS指针,还有特权级0~2的栈选择子和esp栈指针。需要的话还可以再接上个IO位图。TSS的最小大小是104字节。
| 31~16 | 15~0 |
|---|---|
| I/O位图在TSS中的偏移地址 | 保留 |
| 保留 | ldt选择子 |
| 保留 | gs |
| 保留 | fs |
| 保留 | ds |
| 保留 | ss |
| 保留 | cs |
| 保留 | es |
| 31~0 |
|---|
| edi |
| esi |
| ebp |
| esp |
| ebx |
| edx |
| ecx |
| eax |
| eflags |
| eip |
| cr3(pdbr) |
| 31~16 | 15~0 |
|---|---|
| 保留 | ss2 |
| esp2 | esp2 |
| 保留 | SS1 |
| esp1 | esp1 |
| 保留 | ss0 |
| esp0 | esp0 |
| 保留 | 上一个任务的TSS指针 |
一个任务按照特权级来划分,实质上是被分为了0特权级的内核程序和3特权级的用户程序。因为有一些操作想要读写磁盘,使用显存这些使用硬件的操作只有0特权级的内核可以直接访问,用户程序要通过内核提供的系统调用来间接操作硬件。所以这两部分加在一起才是能让CPU完整运行的程序,也就是说完整的任务要经历这两种特权级的变换。
任务是由CPU在执行的,任务在特权级变换时,本质上是CPU的当前特权级在变换。而且CPU在不同特权级下用不同特权级的栈(每个任务的每个特权级下的栈只能有一个)。
特权级转移就两种,一种是由低特权级到高特权级。这种方式是通过使用中断门,调用门等手段。这个时候就要在TSS中去寻找目标高特权级的栈选择子和栈指针。这在TSS中是有字段的,比如刚刚讲的ss,esp 0~2. TSS中的栈指针值是固定的,要像保留上一次在高特权的栈指针(esp)就得靠手动更新了。
而当从高特权级想低特权级转移的方法就只有一个,就是使用调用返回指令,这是唯一能让处理器降低特权级的情况(像retf,iret)。而从高特权级到低特权级的转换一般都是建立在从低特权级到高特权的转移之上的。毕竟操作系统是个死循环,它是向用户进程服务的,一般都是用户进程主动向操作系统请求使用系统调用,特权级向高转换在先。而处理器的向高特权级转换指令(如int,call等)实现的机制决定的。当使用这些指令向高特权级转移的时候,CPU自动把当前低特权级的栈地址(SS和ESP)压入了转移后的高特权级所在的栈中。
处理器是如何找到TSS的呢?
TSS和GDT一样,是硬件支持的系统数据结构,是由软件填写其内容,有硬件使用。GDT要被加载到GDTR中才能被CPU找到,TSS要被加载到TR(Task Register)寄存器中才能被CPU找到。

浙公网安备 33010602011771号