【问题标题】:Why do we need software interupt to start the execution of the system call?为什么我们需要软件中断来启动系统调用的执行?
【发布时间】:2014-11-28 18:30:42
【问题描述】:

这可能是一个非常愚蠢的问题。 但是我想澄清我的疑问,因为我对这件事很陌生。

据我了解,CPU 通过递增程序计数器逐步执行进程指令。

现在假设我们有一个系统调用作为指令之一,那么为什么在遇到这条指令时我们需要给一个软件中断呢?不能像执行其他指令一样执行此系统调用(指令序列),因为据我所知,中断是为了发出某些异步事件的信号。但是这里系统调用是流程指令的一部分,不是异步的。

【问题讨论】:

标签: operating-system kernel system-calls


【解决方案1】:

它不需要中断。您可以制作一个使用简单call 的操作系统。但大多数人不这样做有几个原因。其中可能有:

  1. 在许多架构上,中断会提升或更改 CPU 的访问级别,从而允许操作系统实施保护其内存免受非特权用户代码的攻击。

  2. 抢占式操作系统已经利用中断来调度进程。使用相同的机制可能会很方便。

  3. 大多数体系结构都存在中断。替代方案可能需要跨架构进行重大重新设计。

这是一个不使用中断的“系统调用”示例(如果您将系统调用定义为向操作系统请求功能):

旧版本的 ARM 不提供增加计数器的原子指令。这意味着原子增量需要操作系统的帮助。天真的方法是让它成为一个系统调用,使进程在加载-添加-存储指令期间不可中断,但这会产生中断处理程序的大量开销。相反,Linux 内核选择将一小段代码映射到固定地址的每个进程中。该代码包含原子增量指令,可以直接从用户代码中调用。内核调度程序负责确保在此块中中断的任何操作都正确重新启动。

【讨论】:

  • 你能把一些“证据”和“确凿的事实”联系起来吗?究竟哪一小部分 Linux 代码位于固定地址..?
  • 看起来主要操作实际上是比较和交换,但我很接近。原子添加通常使用 CAS 实现。其实这篇文章中包含了一个原子添加实现:lwn.net/Articles/314561
【解决方案2】:

首先,系统调用是同步软件中断,不是异步的。当处理器执行陷阱机器指令进入内核空间时,一些内核寄存器被中断处理函数改变。修改这些寄存器需要特权模式执行,即不能使用用户空间代码更改这些寄存器。

当用户空间程序无法直接从磁盘读取数据时,因为它无法控制设备驱动程序。用户空间程序不应该打扰驱动程序代码。与设备驱动程序的通信应该通过内核代码本身进行。我们倾向于相信内核代码是原始且完全值得信赖的;用户代码总是可疑的。

因此,它需要特权指令来更改寄存器的内容和/或访问驱动程序功能;用户不能像普通函数调用一样执行系统调用函数。您的处理器应该知道您是否处于内核模式以访问这些设备。

我希望这在某种程度上是清楚的。

【讨论】:

    猜你喜欢
    • 2019-06-06
    • 2016-04-29
    • 2021-01-14
    • 1970-01-01
    • 2019-08-21
    • 2017-03-14
    • 1970-01-01
    • 2011-12-13
    • 2021-07-10
    相关资源
    最近更新 更多