系统调用的三层机制
用户态与内核态
为了减少有限资源的访问和使用冲突,提供机制对用户程序进行权限划分。
内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理内存,对所有的指令包括特权指令都可以执行;
用户态:低级别指令,代码能够掌控的范围受限;
CPU的执行级别
CPU有四种执行级别,分别是0、1、2、3,数字越小,级别越高。Linux操作系统中只是采用了其中的0和3两个特权级别,分别对应内核态和用户态。用户态和内核态很显著的区分方法就是CS:EIP的指向范围,在内核态时,CS:EIP的值可以是任意的地址。在4GB的进程地址空间中,内核态下的这4GB地址空间是都可以访问,用户态只能访问0x00000000~0xbfffffff的地址空间,0xc0000000以上的地址空间只能在内核态下访问。
PS:地址空间是进程的逻辑地址而不是物理地址,逻辑地址是进程的地址空间里面的,cpu都可以通过MMU(内存管理单元)把逻辑地址转化为物理地址
状态的转换。
1.中断
中断处理是从用户态进入内核态的主要方式。
从用户态切换到内核态时,中断int指令会在堆栈上保存用户态的寄存器上下文,同时包括用户态栈顶地址、当时的状态字、当时的cs:eip的值,以及内核态的栈顶地址、内核态的状态字,并将cs:eip的值指向中断处理程序的入口。中断发生后的第一件事就是保存现场(save_all),保存一系列的寄存器的值;中断处理结束前的最后一件事就是恢复现场(restorm_all),退出中断程序,恢复保存寄存器的数据。
2.系统调用
系统调用是特殊的中断
作用
- 把用户从底层的硬件编程中解放出来。
- 极大地提高系统安全性。
- 是用户程序具有可移植性。
关系
API应用程序编程接口是函数定义,一个API可能只对应一个系统调用,也可能内部由多个系统调用实现,一个系统调用也可能被多个API调用。不涉及与内核进行交互的API内部不会封装系统调用。
三层机制
xyz(),system_call,sys_xyz()
User Mode表示用户态,Kernel Mode表示内核态。xyz()就是一个API函数,是系统调用对应的API,封装了一个调用系统,会触发int$0x80对应的中断服务程序入口,内部会有sys_xyz()系统调用处理函数,执行完sys_xyz()后会ret_from_sys_call,若没有发生进程调度,就会执行iret再返回到用户态接着执行。