系统调用的一生--从触发到执行

85 阅读2分钟

系统调用想必大家都不陌生,在这里我们再对系统调用进行一下回顾:

操作系统分为用户态和内核态,这样做的目的是操作系统具有几乎对硬件软件的全部控制权,如此强大的能力不能够随意让用户使用,不然可能造成系统安全问题。因此区分出了用户态和内核态,部分指令只有在内核态才可以执行,而在用户态要使用这些特权指令,就需要使用操作系统为我们提供的系统调用。

接下来,我将带大家回顾系统调用的流程。

触发中断

我们知道,中断是操作系统由用户态转到内核态的唯一途径,在系统调用的一开始,需要向处理器发送中断请求,处理器在收到中断请求后会暂停手头的工作,接着就开始我们系统调用的流程。

而操作系统之所以能知道本次中断是为了进行系统调用,是因为在发送中断的同时,操作系统还在处理器的特定寄存器中保存了中断向量号,而接下来处理器会前往中断向量表中查询本次中断对应的例程。进而处理器能够找到操作系统为系统调用提供的中断服务例程。具体过程如下所示:

image.png

触发系统调用

接下来,就由我们的系统调用服务例程来为系统调用提供服务。

系统调用服务例程要做的是从特定寄存器中读取对应的系统调用号(这是在触发中断前就已经设置好的),之后查询系统调用表获取对应的系统调用服务例程。

而找到对应的系统调用例程后,同样的需要从cpu中获取系统调用函数的参数,一般来说有多个寄存器可以存放,而对于更多的参数,可以在寄存器中存放内存地址,在例程调用时到对应地址中寻找函数参数。

至此,一次系统调用就完成了(忽略中断返回等操作),操作系统通过对应系统调用例程便可以帮我们完成相应的功能。

具体过程可以如下图所示,为了显示清晰,右侧又添加了一个cpu图,但实际上和左边是同一个。

image.png