linux - 内核栈和用户空间栈

标签 linux linux-kernel kernel stack-memory interrupt-handling

内核栈和用户栈有什么区别?为什么使用内核堆栈?如果在 ISR 中声明了局部变量,它将存储在哪里?每个进程都有自己的内核堆栈吗?那么进程如何在这两个堆栈之间进行协调?

最佳答案

  1. What's the difference between kernel stack and user stack ?

简而言之,没什么——除了在内存中使用不同的位置(因此堆栈指针寄存器的值不同),以及通常不同的内存访问保护。 IE。在用户模式下执行时,即使映射,内核内存(其中一部分是内核堆栈)也将不可访问。反之亦然,如果内核代码没有明确请求(在 Linux 中,通过 copy_from_user() 等函数),用户内存(包括用户堆栈)通常不能直接访问。

  1. Why is [ a separate ] kernel stack used ?

权限和安全性分离。其一,用户空间程序可以使他们的堆栈(指针)成为他们想要的任何东西,而且通常甚至没有有效的架构要求。因此,内核不能相信用户空间堆栈指针是有效的或可用的,因此将需要一组在它自己的控制下。不同的 CPU 架构以不同的方式实现这一点;当发生特权模式切换时,x86 CPU 会自动切换堆栈指针,并且用于不同特权级别的值是可配置的 - 通过特权代码(即仅内核)。

  1. If a local variable is declared in an ISR, where will it be stored ?

在内核堆栈上。内核(即 Linux 内核)将 ISR 直接挂接到 x86 架构的中断门,而是将中断调度委托(delegate)给一个通用的内核中断进入/退出机制,该机制在调用已注册的处理程序之前保存中断前寄存器状态。调度中断时,CPU 本身可能会执行特权和/或堆栈切换,这是由内核使用/设置的,因此公共(public)中断入口代码已经可以依赖于存在的内核堆栈。
也就是说,在执行内核代码时发生的中断将简单地(继续)使用此时的内核堆栈。如果中断处理程序具有深层嵌套的调用路径,这会导致堆栈溢出(如果深层内核调用路径被中断并且处理程序导致另一个深层路径;在 Linux 中,文件系统/软件 RAID 代码被 iptables 事件的网络代码中断是已知会在未调整的旧内核中触发此类......解决方案是增加此类工作负载的内核堆栈大小)。

  1. Does each process have its own kernel stack ?

不仅仅是每个进程——每个线程 都有自己的内核栈(事实上,还有自己的用户栈)。请记住,进程和线程(对于 Linux)之间的唯一区别是多个线程可以共享一个地址空间(形成一个进程)。

  1. How does the process coordinate between both these stacks ?

一点也不——不需要。调度(如何/何时运行不同的线程,如何保存和恢复它们的状态)是操作系统的任务,进程不需要关心这个。随着线程的创建(每个进程必须至少有一个线程),内核为它们创建内核堆栈,而用户空间堆栈要么由用于创建线程的任何机制显式创建/提供(函数如 makecontext ()pthread_create() 允许调用者指定一个内存区域用于“子”线程的堆栈),或继承(通过按访问内存克隆,通常称为“写时复制”/COW,在创建新进程时)。
也就是说,进程可以影响其线程的调度和/或影响上下文(状态,其中包括线程的堆栈指针)。有多种方法:UNIX 信号、setcontext()pthread_yield()/pthread_cancel(),... - 但这是有点偏离原来的问题。

关于linux - 内核栈和用户空间栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54248326/

相关文章:

linux-kernel - Linux 内核是否有自己的 SSE/AVX 上下文?

php - 如何在 Laravel PHP 中使用控制台内核?

c++ - 使用 C++ 获取 Linux 中进程的 RAM 和 CPU 使用情况

linux - Linux 进程记帐 (psacct) 是如何工作的?

linux-kernel - spinlock 和 cli 一起使用

security - 如何解决 "Kernel panic - not syncing - Attempted to kill init"——不删除任何用户数据

android - 替换 Android Platform Source 中的预构建内核

Linux 页表管理和 MMU

linux - 需要通过 SFTP 将文件从一台 Linux 机器传输到另一台 Linux 机器

linux - 右大括号后的额外字符