文章目录
系统调用
与内核通信
系统调用在用户空间进程和硬件设备之间添加了一个中间层,主要作用是:
- 为用户空间提供了硬件的抽象接口
- 保证了系统的稳定和安全,可以基于权限、用户类型和其他一些规则对需要进行的访问进行裁决
系统调用是用户空间访问内核的唯一手段,除了异常和陷入之外,它是内核唯一的合法入口
API、POSIX和C库
应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来变成,一个API定义了一组应用程序使用的编程接口,可以实现为一个或多个系统调用,或者完全不使用任何系统调用
POSIX、API、C库以及系统调用的关系如下图
系统调用
系统调用号
在Linux中,每个系统调用被赋予了一个系统调用号。
系统调用号的特点:
- 系统调用号一旦分配就不能再有变更,否则编译好的程序有可能崩溃
- 如果系统调用被删除,所占用的系统调用号不允许被回收利用,否则以前编译过的代码会调用这个系统调用,但是却调用的另一个系统调用,Linux使用“未实现”系统调用
sys_ni_syscall()
来填补这种空缺,它除了返回-ENOSYS
外不做任何工作
系统调用表sys_call_table,为每一个有效的系统调用指定了唯一的系统调用号
系统调用的性能
Linux系统调用比其他许多操作系统都要快,原因是:
- Linux很短的上下文切换时间,进出内核被优化的很简洁
- 系统调用处理程序和每个系统调用本身也很简洁
系统调用处理程序
通知内核的机制通过软中断实现:通过引发一个异常来促使系统切换到内核态去执行异常处理程序
在x86系统上预定义的软中断是中断号128,通过int $0x80指令触发中断,这条指令触发一个异常导致系统切换到内核态并执行第128号异常处理程序(这个异常处理程序就是系统调用处理程序),它的名字是system_call()
指定恰当的系统调用
因为所有系统调用陷入内核的方式都一样,所以需