根据我的理解,每个用户过程都有一个单独的内核堆栈。
如何使用此内核堆栈,为什么我们不能仅对所有用户流程使用一个堆栈?这如何帮助我们进行抢先?当内核在中断上下文中运行时,使用了什么堆栈?
[编辑:感兴趣的体系结构是x86]
如何使用此内核堆栈
例如,当Usermode进程通过SYSCALL进入内核时。在内核内的Syscall处理程序中,您将使用内核堆栈进行本地变量。
为什么我们不能仅对所有用户流程使用一个堆栈?
但是如何?他们将如何同时在SMP系统上使用它?这将导致数据损坏。
这如何帮助我们进行抢先?
我不确定你在问什么。基本上,它与抢先息息相关。如果您被系统计时器中断,则可能会切换到不同内核堆栈的不同线程。上下文可以保存在该堆栈的顶部(我不确定Linux是否以相同的方式实现了它(。Linux中还有一个preempt_counter
的东西,它放在内核堆栈的顶部。该变量可以通过preempt_disable(enable)
递增/减少。这意味着内核线程preekention switched off/on
。它被广泛使用F.E.由spinlocks
。
当内核在中断上下文中运行时,使用了什么堆栈?
当我们从用户 ->内核时,在这种情况下会发生以下操作:
- 使用内核堆栈。处理器切换到由TSS的
SS0
和ESP0
字段定义的堆栈。 -
处理器在内核堆栈上推动异常参数
+--------------------+ KSTACKTOP | 0x00000 | old SS | " - 4 | old ESP | " - 8 | old EFLAGS | " - 12 | 0x00000 | old CS | " - 16 | old EIP | " - 20 <---- ESP +--------------------+
-
处理器读取IDT条目N(取决于发生的IRQ或异常(,并将CS:EIP设置为指向条目所描述的处理程序功能。
- 处理程序功能采用控制并处理例外。
来源:https://pdos.csail.mit.mit.edu/6.828/2016/labs/lab3/