一、Exceptions(异常) and System Call(系统调用)
1.1 陷阱
陷阱是有意为之的异常,是处理器执行程序的一条指令的结果。陷阱最重要的用途是提供用户程序和内核之间一个像普通过程调用似的接口,名曰:系统调用。用户程序经常需要向内核请求服务,比如读一个文件(read) 、创建一个新的进程(fork) 、加载一个新的程序(execv),或者终止当前进程(exit) 。为了允许对这些内核服务的受控的访问,处理器提供了一条特殊的 “syscall n” 指令,当用户程序想要请求服务n时,可以执行这条指令。执行syscall 指令会导致一个到异常处理程序的陷阱,这个处理程序对参数解码,并调用适当的内核程序。
1.1.1 System Call N
系统调用运行在内核模式中,内核模式允许执行系统调用函数的指令,并访问定义在内核中的栈。
Examples of popular system calls:
Linux provides hundreds of system calls.
Source: /usr/include/sys/syscall.h.
1.1.2 实现
1.在IA32 系统上,系统调用是通过一条称为int n1 的陷阱指令来提供的,其中n可能是IA32 异常表 中256 个条目中任何一个的索引。在历史上,系统调用是通过异常128 (Ox80) 提供的。
2.所有的传到Linux系统调用服务程序的参数都是通过寄存器传递的。按照惯例,寄存器%eax包含系统调用号,寄存器%ebx 、%ecx 、%edx 、%esi 、%edi和%ebp 包含最多六个任意的参数。栈指针%esp不能使用,因为当进入内核模式时,内核会覆盖它。
3.C程序用syscall函数可以直接调用任何存在于系统调用表中的系统调用。然而,实际中几乎没必要这么做。对于大多数系统调用,标准C库提供了一组方便的包装函数。这些包装函数将参数打包到一起,以适当的系统调用号陷入内核,然后将系统调用的返回状态传递回调用程序。我们将系统调用和与它们相关联的包装函数称为系统级函数。
4.内核记录了