use*_*220 9 stack operating-system kernel process context-switch
以下是我读过进程A和进程B之间的上下文切换的描述.我不明白内核堆栈的用途.假设是每进程内核堆栈.我正在阅读的描述说明了将A的寄存器保存到A的内核堆栈中,并将A的寄存器保存到A的进程结构中.将寄存器保存到内核堆栈和进程结构的重点是什么?为什么需要两者?
上下文切换在概念上很简单:所有操作系统必须做的是为当前正在执行的进程保存一些寄存器值(例如,在其内核堆栈上),并为即将执行的进程恢复一些(来自它的内核堆栈).通过这样做,OS因此确保当最终执行从陷阱返回指令时,系统不再返回到正在运行的进程,而是继续执行另一个进程...
进程A正在运行,然后被定时器中断中断.硬件将其寄存器(在其内核堆栈上)保存并进入内核(切换到内核模式).在定时器中断处理程序中,操作系统决定从正在运行的进程A切换到进程B.此时,它调用switch()例程,小心地保存当前寄存器值(进入A的进程结构),恢复寄存器进程B(来自其进程结构条目),然后切换上下文,特别是通过更改堆栈指针以使用B的内核堆栈(而不是A的).最后,OS从陷阱返回,它恢复B的寄存器并开始运行它.
我对第二段有不同意见.
进程A正在运行,然后被定时器中断中断.硬件将其寄存器(在其内核堆栈上)保存并进入内核(切换到内核模式).
我不知道一个系统在中断上保存内核堆栈上的所有寄存器.程序计数器,处理器状态和堆栈指针(假设硬件没有单独的内核模式堆栈指针).通常,处理器在中断后保存内核堆栈上所需的最小值.然后中断处理程序将保存它想要使用的任何其他寄存器,并在退出之前恢复它们.处理器的RETURN FROM INTERRUPT或EXCEPTION指令然后恢复由中断自动存储的寄存器.
该描述假定该过程没有变化.
如果中断句柄决定改变进程,它将保存当前寄存器状态("进程上下文" - 大多数处理器只有一条指令.在Intel版本中你可能需要使用多条指令)然后执行另一条指令来加载新流程的流程背景.
要回答标题问题"什么是用于的内核堆栈?",只要处理器处于内核模式,就会使用它.如果内核没有受到用户访问保护的堆栈,则系统的完整性可能会受到影响.内核堆栈往往非常小.
为了回答第二个问题,"将寄存器保存到内核堆栈和进程结构以及为什么需要这两个问题到底是什么意思?"
他们有两个不同的目的.内核堆栈上保存的寄存器用于退出内核模式.上下文处理块保存整个寄存器集以便更改进程.
我认为你的误解来自你的源代码的措辞,它表明所有寄存器在进入内核模式时都存储在堆栈中,而不仅仅是进行内核模式切换所需的最小寄存器数.系统通常只保存返回用户模式所需的内容(并且可以使用相同的信息返回到另一个上下文切换中的原始进程,具体取决于系统).进程上下文的更改将保存所有寄存器.
编辑回答其他问题:
如果中断处理程序需要使用由中断自动保存的寄存器,则在进入时将它们推送到内核堆栈并在退出时弹出它们.中断处理程序必须显式保存和恢复它使用的任何[通用]寄存器.没有触及过程上下文块.
进程上下文块仅作为实际上下文切换的一部分进行更改.
例:
让我们假设我们有一个带有程序计数器,堆栈指针,处理器状态和16个通用寄存器的处理器(我知道这个系统确实不存在),并且所有模式都使用相同的SP.
硬件将PC,SP和PS推送到堆栈,使用内核模式堆栈的地址加载SP,并从中断处理程序(来自处理器的分派表)加载PC.
经纪人的作者决定他要去我们R0-R3.所以处理程序的第一行有:
Push R0 ; on to the kernel mode stack
Push R1
Push R2
Push R3
Run Code Online (Sandbox Code Playgroud)
中断处理程序执行它想做的任何事情.
清理
中断处理程序的编写者需要做:
Pop R3
Pop R2
Pop R1
Pop R0
REI ; Whatever the system's return from interrupt or exception instruction is.
Run Code Online (Sandbox Code Playgroud)
从内核模式堆栈恢复PS,PC和SP,然后继续执行中断之前的位置.
我已经制作了自己的处理器以简化.某些处理器具有可中断的冗长指令(例如,块字符移动).这些指令通常使用寄存器来维护其上下文.在这样的系统上,处理器必须自动保存用于维护指令内的上下文的任何寄存器.
除非正在更改进程,否则中断处理程序不会破坏进程上下文块.