jkv*_*jkv 94 linux linux-device-driver linux-kernel
内核堆栈和用户堆栈之间有什么区别?为什么要使用内核堆栈?如果在ISR中声明了局部变量,那么它将被存储在哪里?每个进程都有自己的内核堆栈吗?然后这两个堆栈之间的进程如何协调?
Fra*_*kH. 170
- 内核堆栈和用户堆栈之间有什么区别?
简而言之,没有 - 除了在内存中使用不同的位置(因此堆栈指针寄存器的值不同),以及通常不同的内存访问保护.即,在用户模式下执行时,内核内存(其中一部分是内核堆栈)即使映射也无法访问.反之亦然,没有内核代码明确要求(在Linux中,通过类似的功能copy_from_user()),用户内存(包括用户堆栈)通常不能直接访问.
- 为什么使用[单独的]内核堆栈?
权限和安全性的分离.例如,用户空间程序可以使他们的堆栈(指针)成为他们想要的任何东西,并且通常没有架构要求甚至没有有效的架构.因此,内核不能信任用户空间栈指针有效也不可用,因此需要一组在其自己的控制之下.不同的CPU架构以不同的方式实现这一点; 当特权模式切换发生时,x86 CPU会自动切换堆栈指针,并且可以配置用于不同权限级别的值 - 特权代码(即只有内核).
- 如果在ISR中声明了局部变量,它将在何处存储?
在内核堆栈上.内核(Linux内核,即)不会将 ISR直接挂接到x86架构的中断门,而是将中断调度委托给公共内核中断进入/退出机制,该机制在调用已注册的处理程序之前保存预先中断寄存器状态. .调度中断时CPU本身可能会执行权限和/或堆栈切换,这由内核使用/设置,以便公共中断入口代码可以依赖于存在的内核堆栈.
也就是说,执行内核代码时发生的中断将在那时简单地(继续)使用内核堆栈.如果中断处理程序具有深度嵌套的调用路径,则会导致堆栈溢出(如果深度内核调用路径中断且处理程序导致另一个深度路径;在Linux中,文件系统/软件RAID代码被iptables活动的网络代码中断)已知在未经调整的旧内核中触发此类内容...解决方案是增加此类工作负载的内核堆栈大小).
- 每个进程都有自己的内核堆栈吗?
不仅仅是每个进程 - 每个线程都有自己的内核堆栈(事实上,它也有自己的用户堆栈).请记住,进程和线程(对Linux)之间的唯一区别是多个线程可以共享一个地址空间(形成一个进程).
- 这两个堆栈之间的进程是如何协调的?
完全没有 - 它不需要.调度(如何/何时运行不同的线程,如何保存和恢复其状态)是操作系统的任务和过程不需要关心它.在创建线程(并且每个进程必须至少有一个线程)时,内核为它们创建内核堆栈,而用户空间堆栈由显式创建/提供由用于创建线程的任何机制(函数类似makecontext()或pthread_create()允许调用者指定一个用于"子"线程堆栈的内存区域,或者继承(通过访问时内存克隆,通常称为"写入时复制"/ COW,创建新进程时).
也就是说,该过程可以影响其线程的调度和/或影响上下文(状态,其中就是线程的堆栈指针).这有多种方式:UNIX信号setcontext(),pthread_yield()/ pthread_cancel(),... -但这disgressing从原来的问题有点.
Jey*_*ram 15
我的答案是从我的东西中收集到的其他SO问题.
What's the difference between kernel stack and user stack?
Run Code Online (Sandbox Code Playgroud)
作为内核程序员,您知道内核应该受到错误的用户程序的限制.假设您为内核和用户空间保留相同的堆栈,那么用户应用程序中的简单段错误会导致内核崩溃并需要重新启动.
每个CPU有一个"内核堆栈",如ISR堆栈,每个进程有一个"内核堆栈".每个进程都有一个"用户堆栈",尽管每个线程都有自己的堆栈,包括用户和内核线程.
http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html
Why kernel stack is used?
Run Code Online (Sandbox Code Playgroud)
因此,当我们处于内核模式时,堆栈类型的机制是处理函数调用所必需的,局部变量类似于用户空间.
http://www.kernel.org/doc/Documentation/x86/kernel-stacks
If a local variable is declared in an ISR, where it will be stored?
Run Code Online (Sandbox Code Playgroud)
它将存储在ISR堆栈(IRQSTACKSIZE)中.仅当硬件支持时,ISR才在单独的中断堆栈上运行.否则,ISR堆栈帧被推入中断线程的堆栈.
用户空间不知道,并且坦率地不关心中断是在当前进程的内核堆栈还是单独的ISR堆栈中提供.由于每个CPU都有中断,因此ISR堆栈必须是每个CPU.
Does each process has its own kernel stack ?
Run Code Online (Sandbox Code Playgroud)
是.每个进程都有自己的内核堆栈.
Then how the process coordinates between both these stacks?
Run Code Online (Sandbox Code Playgroud)
@ FrankH的答案看起来很棒.
- 内核栈和用户栈有什么区别
参考 Robert Love 的 Linux Kernel Development,主要区别在于大小:
用户空间可以避免在堆栈上静态分配许多变量,包括巨大的结构和千元素数组。
这种行为是合法的,因为用户空间有一个可以动态增长的大堆栈。
内核堆栈既不大也不动态;它体积小,尺寸固定。
内核堆栈的确切大小因架构而异。
在 x86 上,堆栈大小可在编译时配置,可以是 4KB 或 8KB。
历史上,内核堆栈是两页,这通常意味着它在 32 位架构上是 8KB,在 64 位架构上是 16KB——这个大小是固定的和绝对的。
每个进程接收自己的堆栈。
此外,内核堆栈包含一个指向 thread_info 结构的指针,该结构保存有关线程的信息。
| 归档时间: |
|
| 查看次数: |
47671 次 |
| 最近记录: |