HelloOs总结之进程管理(下)

HelloOs总结之进程管理(下)

5.2 系统调用

   上面我们实现的进程其实都是内核态进程(更准确的说,应该是内核态线程),它们出生就含着金钥匙,拥有至高无上的权利,可以驾驶着CPU这驾风驰电掣的烈马,任意驰骋。这种情况在内核线程势可以的,因为内核一般都是经过精心设计的。 但是如果对于用户程序也给他这样的权利,那就有点过分了,因为你也不知道哪个用户态进程会是个“叛徒”,会把你的计算机分分钟搞死。所以我们需要进行隔离。但是,对于普通的 “老百姓进程”,它们有的时候还是需要访问一些重要的设备的,因此我们需要开些通道,让这些进程访问一些可以访问的资源。这些通道,就是系统调用。
   关于系统调用,从某种程度上说是一种隔离用户进程和内核进程,用以保护内核资源、硬件资源的一种手段。这种机制一般都需要底层CPU硬件上的支持,比如说s3c2410中不同的等级模式,x86中不同的特权级,以及从较低的特权级到较高的特权级所需要的特殊指令,对于s3c2410来说是swi(软中断),对于x86来说是int 80(系统调用)。
   这里还需要了解一点,对于一般的系统调用来说,其实现都需要和内存保护机制相结合。简单来说就是在内核启动的时候,给资源所对应的内存空间设上不同的访问权限(低等级无法访问,高等级可以访问)。然后对于普通进程来说,其出生就是出于低等级的,如果强制访问这些资源空间,就会引发出错。所以其访问这些资源空间只能靠系统调用,暂时提高运行等级,访问对应的资源,访问完成或,退出系统调用的时候,自动回到较低的用户等级。如下图5.9所示。

在这里插入图片描述

  • 图5.9 系统调用示意图

   以上就是系统调用的基本原理。下面简单说下HelloOs中系统调用的实现。
   s3c2410中CPU具有七种模式,其中除了用户模式之外,其他的都是特权模式(特权模式可以更改状态寄存器从而变更到其他的模式,用户模式不可以)。用户进程初始的时候一般处于用户模式,当期想要访问内核态资源,其会调用swi 指令陷入软中断(这个swi指令也就是操作系统教科书中的访管指令),自动进入svc这个特权模式,然后再从svc模式主动切换到sys模式(因为HelloOs的内核态就是运行在sys模式),然后通过用户传递的参数,调用事先准备好的系统调用函数。整个流程如下图5.10所示。如果不考虑系统调用中的模式变化,调用系统调用就像是调用一个普通的中断处理函数一样。(怪不得在在s3c2410中把swi叫做软中断呢)

在这里插入图片描述

  • 图5.10 系统调用流程图

   整个过程也不是很复杂,下面简要说明一下流程中的解析用户参数。因为swi这个软中断指令是32位的,其机器码格式为0xEFXXXXXX,所以只要机器码的高8位是0xEF的,CPU都会把它当成swi指令,所以,我们一般会把调用的中断号放到swi 机器码的后24位,然后在swi的中断处理程序中在解析出来(当然也可以通过普通参数传递的方式传递中断号,即把中断号当成普通参数)。

   最后,对于系统中断还要说明一点,HelloOs中实现了write、get_pid这两个系统中断,但是由于skyeye模拟器对MMU内存保护支持的模拟不是很好,所以效果没法体现出来。