一、系统调用
1.1 概述
现代操作系统中,内核提供了用户进程与内核进行交互的一组接口,这些接口使得应用程序受限地访问硬件设备,保证系统稳定可靠,避免应用程序肆意妄行。
系统调用就是用户空间进程和外围设备之间的中间层,提供系统调用主要有三个作用:
- 给用户进程提供抽象接口,屏蔽底层实现。
- 内核自身通过用户类型权限等做校验,保证系统的稳定安全。
- 为了更好的实现多任务,虚拟内存等内容。
而站在程序员的角度,往往又在系统调用之上再封装了一层 API 用来调用。
另外,每个系统调用都会分配一个系统调用号来唯一表示系统调用函数。
系统调用大致可分为六大类:进程控制(process control)、文件管理(file manipulation)、设备管理(device manipulation)、信息维护(information maintenance)、通信(communication) 和保护(protection)。
1.2 系统调用处理程序
用户空间的程序无法直接执行内核代码,所以需要通知内核切换内核态,执行系统调用。
这种通知机制使用软中断实现(软中断是软件模拟的中断,类似于信号;硬中断是外部设备中断 CPU),通过引发一个异常来迫使系统切换到内核态去处理异常处理程序,这个异常处理程序其实系统调用的处理程序,x86 系统与定义的软中断号为 128,通过 int $0x80 指令触发。最近又加入了 sysenter 指令,对速度和效率有了一定的优化。
仅仅陷入内核还不足够,需要确定具体的系统调用程序,就需要在陷入内核之前,将系统调用号通过 eax 寄存器 传递给内核。也就是将系统调用号放在该寄存器中。陷入内核之后,内核就通过该系统调用号确