堆栈切换和任务切换 CISR RISR

堆栈切换和任务切换

堆栈切换
中断发生时,从用户堆栈切换到内核堆栈是硬件完成的是吗?需要软件上哪些支持呢?
x86处理器是由硬件完成的。
但很多RISC(reduced instruction set computer,精简指令集计算机,例如:MIPS R3000、HP—PA8000系列,Motorola M88000等均属于RISC微处理器 处理器必须由软件来实现用户态与核态之间的堆栈切换
X86是CISC处理器(复杂指令集计算机(Complex Instruction Set Computer, CISC ))
X86处理器的SP切换过程是这样的:

当中断或异常发生时,处理器会检查是否有CPU运行级别的改变,如果有的话,则进行堆栈切换。切换的过程如下:

1。 读取TR寄存器以便访问当前进程的TSS段,因为TSS段中保存着当前进程在核心态下的堆栈指针。
2。 从TSS段中加载相应的堆栈地址到SS和ESP寄存器中。
3。 在核态堆栈中,保存用户态下的SS寄存器和ESP寄存器值。

由于linux内核仅使用了一个TSS段,因此当发生进程切换时,内核必须将新进程的核态堆栈更新到TSS段中。

而 对于RISC处理器而言, 本着“简洁”的设计原则,当发生中断或异常时,CPU仅仅只是跳转到某个TRAP向量地址去执行(当然,硬件还是会自动设置处理器状态寄存器PSR中的核 心态标志位,同时保存trap发生前的处理器运行级别),而其余的工作就都统统留给软件去完成了。

因此,RISC处理器的trap handler通常都做这样的一些工作:

1。根据trap发生前的处理器运行级别判断是否需要进行堆栈切换。 如果trap发生之前就是处在核心态下,那显然就不要切换堆栈。而是直接去做SAVE_ALL好了。

2。 如果之前是用户态,那么从内核的某个固定的地址加载当前进程的核态SP指针。然后进行SAVE_ALL保存中断现场。

#####
我们知道每个进程都有一个用户堆栈与系统堆栈,那么此外是否还有一个操作系统内核专用的堆栈呢?
BTW:内核代码都是运行在当前进程的核心态堆栈中的,并不需要专门的堆栈
########
那么当系统初始化时,系统中第一个进程还没有生成的时候,用的是哪个堆栈呢?
从head.s程序起,系统开始正式在保护模式下运行。此时堆栈段被设置为内核数据段(0x10),堆栈指针esp设置成指向user_stack数组的顶端,保留了1页内存(4K)最为堆栈使用。此时该堆栈是内核程序自己使用的堆栈。
(有疑问的答案:系统初始化用的是0进程的堆栈 -- 也就是是init_task的堆栈。
整个start_kernel()都是在init_task的堆栈中执行的。start_kernel()最后clone出1进程--也就是init进程。然后0进程就去执行cpu_idle()函数了--也就是变成idle进程了。然后发生一次进程调度(进程切换时会切换内核堆栈),init进程得到运行,此时内核就在init进程的堆栈中运行。)
#####
任务0的堆栈
任务0的堆栈比较特殊,在执行了move_to_user_mode()之后,它的内核堆栈位于其任务数据结构所在页面的末端,而它的用户态堆栈就是前面进入保护模式后所使用的堆栈,即user_stack数组的位置。任务0的内核态堆栈是在其人工设置的初始化任务数据结构中指定的,而它的用户态堆栈是在执行move_to_user_mode()时,在模拟iret返回之前的堆栈中设置的。在该堆栈中,esp仍然是user_stack中原来的位置,而 ss被设置成0x17,也即用户局部表中的数据段,也即从内存地址0开始并且限长640KB的段。

 
任务切换
I386硬件任务切换机制
 
1.I386硬件任务切换机制
   Intel 在i386体系的设计中考虑到了进程的管理和调度,并从硬件上支持任务间的切换。为此目的,Intel在i386系统结构中增设了一种新的段“任务状态 段”TSS。一个TSS虽然说像代码段,数据段等一样,也是一个段,实际上却是一个104字节的数据结构,用以记录一个任务的关键性的状态信息。
   像其他段一样,TSS也要在段描述表中有个表项。不过TSS只能在GDT中,而不能放在任何一个LDT中或IDT中。若通过一个段选择项访问一个TSS,而选择项中的TI位为1,就会产生一次GP异常。
    另外,CPU中还增设一个任务寄存器TR,指向当前任务的TSS。相应地,还增加了一条指令LTR,对TR寄存器进行装入操作。像CS和DS一样,TR也 有一个程序不可见部分,每当将一个段选择码装入到TR中时,CPU就会自动找到所选择的TSS描述项并将其装入到TR的程序不可见部分,以加速以后对该 TSS段的访问。
   还有,在IDT表中,除了中断门、陷阱门和调用门以为,还定义了一种任务门。任务门中包含一个TSS段选择码。当CPU因中断而穿过一个任务门时,就会将 任务门中的选择码自动装入TR,使TR指向新的TSS,并完成任务的切换。CPU还可以通过JMP和CALL指令实现任务切换,当跳转或调用的目标段实际 上指向GDT表中的一个TSS描述项时,就会引起一次任务切换。
阅读更多

没有更多推荐了,返回首页