根据我的理解,每个用户进程都有一个单独的内核堆栈。
如何使用此内核堆栈,为什么我们只能为所有用户进程使用一个堆栈? 这如何帮助我们抢占先机? 当内核在中断上下文中运行时,使用了什么堆栈?
[编辑:感兴趣的架构是x86]
答案 0 :(得分:2)
如何使用此内核堆栈
例如,当usermode进程通过syscall进入内核时使用。在内核中的syscall处理程序中,您将使用内核堆栈作为局部变量。
但是怎么样?他们将如何在SMP系统上同时使用它?这将导致数据损坏。为什么我们不能只为所有用户进程使用一个堆栈?
这有助于我们先发制人吗?
我不确定你在问什么。基本上它非常间接地与先发制人有关。如果您被系统计时器中断,您可能会切换到具有不同内核堆栈的不同线程。上下文可以保存在该堆栈的顶部(我不确定linux是否以相同的方式实现它)。在linux中还有一个preempt_counter
的东西,它放在内核堆栈的顶层。该变量可以递增/递减preempt_disable(enable)
。什么意味着内核线程抢占switched off/on
。它被广泛使用f.e. spinlocks
。
当内核在中断上下文中运行时,使用了什么堆栈?
当我们离开用户时 - >在这种情况下,内核会发生以下情况:
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设置为指向条目描述的处理函数。