【问题标题】:What is the difference between kernel stack and user stack?内核栈和用户栈有什么区别?
【发布时间】:2011-02-09 06:36:40
【问题描述】:

在同一个程序中使用两个不同的堆栈有什么需要? Trap 如何将当前程序栈从用户栈变为内核栈?完成系统调用后如何返回用户栈?

每个进程都有内核和用户栈吗?

【问题讨论】:

  • 你在学习什么架构?
  • cs.umb.edu/~eoneil/cs444_f06/class10.html :澄清问题的好方法。来自大学网站!!
  • 我 5 年前从大学毕业了,这个问题仍然让我想起了我的本科岁月。每次收到有关堆栈溢出问题的通知时,我都充满了怀旧之情。

标签: operating-system stack kernel


【解决方案1】:

每个 CPU (基本上)有一个“内核堆栈”。每个进程都有一个“用户堆栈”,但每个线程都有自己的堆栈,包括用户线程和内核线程。

“陷阱改变堆栈”实际上是相当简单的。

CPU 因中断而改变进程或“模式”。中断的发生可能有很多不同的原因 - 发生故障(如错误或页面错误),或物理硬件中断(如来自设备) - 或定时器中断(例如,当进程使用所有这些都是分配的 CPU 时间”)。

无论哪种方式 - 当调用此中断时,CPU 寄存器都保存在堆栈中 - 所有寄存器 - 包括堆栈指针本身。

通常会调用“调度程序”。然后调度程序选择另一个进程运行 - 恢复其所有保存的寄存器包括堆栈指针,并从它停止的地方继续执行(存储在返回地址指针中)。

这称为“上下文切换”。

我正在简化一些事情——比如如何保存和恢复内存管理上下文,但这就是我的想法。它只是为了响应中断而保存和恢复寄存器 - 包括“堆栈指针”寄存器。

所以 每个 程序或 thread 都有自己的(“用户模式”)堆栈(即多线程程序将有多个堆栈) - 并且上下文切换切换在这些之间。

更具体地说,“内核模式”堆栈存在于机器(或特定 CPU)在内核中运行时。确切的处理是特定于操作系统的——例如,Linux 将每个 CPU 有一个中断(内核)堆栈(通常用于中断,包括页面错误和系统调用,它本质上包括几乎所有东西——比如设备驱动程序和调度程序) .与用户空间线程一样,Linux 内核也有单独的内核线程堆栈。 (Windows 内核做了一些不同的事情)。

【讨论】:

  • 它的意思是windows每个cpu有一个内核栈,而linux每个进程都有用户栈和内核栈。
  • 在 Windows 中,每个线程(甚至是用户模式线程)都有自己的内核堆栈。内核堆栈绝对不是每个 CPU。
【解决方案2】:

有 2 个堆栈,因为有 2 个 CPU 执行上下文。用户模式堆栈将在为函数、局部变量、返回地址等创建堆栈帧方面迎合您的程序。当 CPU 将上下文切换到内核模式时,例如在系统调用执行期间,它需要访问内核内存和数据结构因此切换到使用它的内核堆栈。 是的,我相信 Unix 使用每个进程的内核堆栈。

【讨论】:

    【解决方案3】:

    我在大学学习操作系统,我们的项目是基于哈佛建立的OS/161。所以我的回答都是基于这个操作系统的。

    在 OS/161 中,每个线程都有 2 个堆栈 - 一个用于用户/应用程序,一个用于内核程序。

    1. 在同一个程序中使用两个不同的栈需要什么?

    假设我们只在应用程序模式下使用堆栈。由于内存空间由多个线程共享,如果其他线程不小心覆盖了内核使用的地址,那么内核可能会崩溃,从而导致操作系统非常脆弱。

    2、trap如何将当前程序栈从用户栈变为内核栈?

    在 OS/161 中,陷阱用于从应用程序传输到内核。可以调用陷阱的机制有三种:系统调用、异常和中断。内核堆栈中的陷阱帧用于保存当前线程上下文。

    以下是详细过程(来自lecture note of UWaterloo CS350):

    • 当上述机制之一发生时,硬件切换 CPU 进入特权模式并将控制权转移到预定义的位置, 内核处理程序应位于的位置。

    • 内核处理程序创建一个陷阱帧并使用它来保存 应用程序线程上下文,以便可以执行处理程序代码 在 CPU 上。

    • 在内核处理程序完成执行之前,它会恢复 来自陷阱帧的应用程序线程上下文,在返回之前 控制到应用程序。

    3. 系统调用完成后如何返回用户栈?

    上面的过程也清楚地解释了这个问题。

    【讨论】:

    • 谢谢,我问这个问题已经 4 年了,那时我还在上大学。您的回答仍然增加了我的知识。
    【解决方案4】:

    拥有一个单独的内核堆栈的原因之一是内核需要一个地方来存储用户模式代码无法触及的信息。这可以防止在不同线程/进程中运行的用户模式代码意外或恶意影响内核的执行。

    【讨论】:

      【解决方案5】:

      在同一个程序中使用两个不同的栈需要什么

      我从未听说过单个进程同时使用内核堆栈和用户堆栈,尽管它可能非常常见。讨论了here

      内核堆栈必须与用户模式堆栈隔离。否则,用户模式代码可能会损坏内核堆栈,从而导致内核崩溃。

      trap如何将当前程序堆栈从用户堆栈更改为内核堆栈

      您可能想查找类似Intel Software Developer's Manuals 的内容。

      每个进程都有内核和用户栈

      我认为这会因操作系统设计而异,尽管它可能相当普遍。我在上面提供的链接表明 Linux 每个进程使用两个(或更多)堆栈。我还没有听说过 Windows 使用每个进程的内核模式堆栈。

      【讨论】:

      • 它的意思是windows每个cpu有一个内核栈,而linux每个进程都有用户栈和内核栈。
      【解决方案6】:

      进程的上下文(psw, state of registers,pc...)保存在进程的PCB中,在内存的内核空间中,而不是在堆栈中。是的,每个用户进程都有一个堆栈,用户空间内存中的每个线程都有一个堆栈。 在内核中,数据结构由内核中函数的倍数代码共享。栈是用来调用过程和局部变量的,不是用来保存上下文的。

      【讨论】:

        【解决方案7】:

        它取决于操作系统。拥有它的原因是操作系统的基本安全性。这是通过对操作系统本身的精心设计。例如,一些处理器具有内核、执行、主管和用户堆栈。

        蕾妮

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-10
          • 1970-01-01
          • 2015-08-05
          • 2016-08-18
          • 2012-10-06
          • 2011-11-20
          • 1970-01-01
          相关资源
          最近更新 更多