内核堆栈和用户空间堆栈
内核堆栈和用户堆栈有什么区别? 为什么使用内核堆栈? 如果一个局部variables在ISR中被声明,它将被存储在哪里? 每个进程都有自己的内核堆栈吗? 那么这两个堆栈之间的过程如何协调?
- 内核堆栈和用户堆栈有什么区别?
简而言之,除了在内存中使用不同的位置(因此堆栈指针寄存器的值不同)和通常不同的内存访问保护之外,什么也不是。 即当在用户模式下执行时,内核内存(其中一部分是内核堆栈)即使映射也不可访问。 反之亦然,不需要内核代码的明确请求(在Linux中,通过像copy_from_user()
这样的函数),通常不能直接访问用户内存(包括用户堆栈)。
- 为什么使用[独立的]内核堆栈?
分离特权和安全。 例如,用户空间程序可以使他们的堆栈(指针)任何他们想要的东西,通常没有任何架构要求,甚至有一个有效的。 因此,内核不能相信用户空间堆栈指针是有效的,也不可用的,因此将需要在它自己的控制之下的一个集合。 不同的CPU架构以不同的方式实现这一点; 当特权模式切换时,x86 CPU会自动切换堆栈指针,并且用于不同特权级别的值可以通过特权代码(即只有内核)进行configuration。
- 如果一个局部variables在ISR中被声明,它将被存储在哪里?
在内核堆栈上。 内核(即Linux内核)并不直接将ISR挂接到x86架构的中断门 ,而是将中断调度委托给通用的内核中断入口/出口机制,在调用注册的处理程序之前节省预中断注册状态, 。 CPU本身在调度中断时可能会执行特权和/或堆栈切换,并由内核使用/设置,以便公共中断入口代码可以依赖于内核堆栈的存在。
也就是说,执行内核代码时发生的中断将简单地(继续)在那个地方使用内核堆栈。 如果中断处理程序具有深度嵌套的调用path,则会导致堆栈溢出(如果深层内核调用path被中断并且处理程序导致另一个深度path;在Linux中,使用iptables active的networking代码中文件系统/软件RAID代码被中断已知可以触发这样的旧的内核…解决scheme是增加这种工作量的内核堆栈大小)。
- 每个进程都有自己的内核堆栈吗?
不只是每个进程 – 每个线程都有自己的内核堆栈(实际上也有自己的用户堆栈)。 记住进程和线程(对于Linux)之间的唯一区别是multithreading可以共享一个地址空间(形成一个进程)。
- 这两个堆栈之间的过程如何协调?
一点也不 – 不需要。 调度(如何/何时运行不同的线程,如何保存和恢复其状态)是操作系统的任务,进程不需要担心这一点。 当线程被创build(并且每个进程必须至less有一个线程)时,内核为它们创build内核栈,而用户空间栈可以由任何用于创build线程的机制来显式创build/提供(像makecontext()
或pthread_create()
允许调用者指定要用于“子”线程堆栈的内存区域,或者inheritance(通过按访问内存克隆,通常在创build新进程时称为“copy on write”/ COW)。
也就是说,这个过程可以影响其线程的调度和/或影响上下文 (状态,其中是线程的堆栈指针)。 有多种方法:UNIX信号, setcontext()
, pthread_yield()
/ pthread_cancel()
,… – 但这是从原来的问题有点疏忽。
我的答案是从其他SO问题收集我的东西。
What's the difference between kernel stack and user stack?
作为一名内核程序员,您知道内核应该受到错误用户程序的限制。 假设你为内核和用户空间保持相同的堆栈,那么用户应用程序中的简单段错误会使内核崩溃并需要重新启动。
每个CPU有一个“内核堆栈”,如每个进程的ISR堆栈和一个“内核堆栈”。 每个进程都有一个“用户堆栈”,尽pipe每个线程都有自己的堆栈,包括用户线程和内核线程。
http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html
Why kernel stack is used?
所以当我们处于内核模式时,处理函数调用需要堆栈类机制,类似于用户空间的局部variables。
http://www.kernel.org/doc/Documentation/x86/kernel-stacks
If a local variable is declared in an ISR, where it will be stored?
它将被存储在ISR栈(IRQSTACKSIZE)中。 ISR只在硬件支持的情况下才在单独的中断堆栈上运行。 否则,ISR堆栈帧会被压入中断线程的堆栈中。
用户空间不知道,并坦率地不关心是否在当前进程的内核堆栈或单独的ISR堆栈中提供中断。 由于每个CPU都有中断,所以ISR堆栈必须是每个CPU。
Does each process has its own kernel stack ?
是。 每个进程都有自己的内核堆栈。
Then how the process coordinates between both these stacks?
@ FrankH的回答对我来说很好。