第第1010章系统章系统调用调用本章对本章对LinuxLinux系统调用的定系统调用的定义、基本原理、使用方法和注意义、基本原理、使用方法和注意事项作了概括的介绍,以便读者事项作了概括的介绍,以便读者对对LinuxLinux系统调用建立一个大致系统调用建立一个大致的印象。较详细地讨论了系统调的印象。较详细地讨论了系统调用用waitwait、、waitpidwaitpid和和execexec函数函数族,并通过两个实际例子来说明族,并通过两个实际例子来说明系统调用。系统调用。10.110.1系统调用概述系统调用概述所有的操作系统都提供多种服务的入口点所有的操作系统都提供多种服务的入口点,由此程序向内核请求服务。各种版本的,由此程序向内核请求服务。各种版本的UnixUnix都提供经良好定义的有限数目的入口都提供经良好定义的有限数目的入口点,经过这些入口点进入内核,这些入口点,经过这些入口点进入内核,这些入口点被称为系统调用点被称为系统调用(systemcall)(systemcall)。系统调。系统调用是不能更改的一种用是不能更改的一种UnixUnix特征。特征。10.1.110.1.1系统调用过程系统调用过程图10.1系统调用过程示意图LinuxLinux内核中设置了一组用于实现各种系统功能内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。二者在使用方式上户自己提供,运行于用户态。二者在使用方式上也有相似之处。也有相似之处。随随LinuxLinux核心还提供了一些核心还提供了一些CC语言函数库,这些语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。把这些函数也称为系统调用。在在LinuxLinux中,系统调用的过程大体如图中,系统调用的过程大体如图10.110.1所所示:示:一般来说,一般来说,CPUCPU硬件决定了进程不能访问内核所硬件决定了进程不能访问内核所占内存空间也不能调用内核函数,这被称作占内存空间也不能调用内核函数,这被称作""保保护模式护模式""。系统调用是这些规则的一个例外。系。系统调用是这些规则的一个例外。系统调用的原理是:进程先用适当的值填充寄存器统调用的原理是:进程先用适当的值填充寄存器,然后调用一个特殊的指令跳转一个事先定义的,然后调用一个特殊的指令跳转一个事先定义的内核中的一个位置(当然,这个位置是用户进程内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。硬件知道一旦跳到这个位可读但是不可写的)。硬件知道一旦跳到这个位置,就不是在限制模式下运行的用户,而是作为置,就不是在限制模式下运行的用户,而是作为操作系统的内核。在操作系统的内核。在IntelCPUIntelCPU中,这个指令由中,这个指令由中断中断0x800x80实现。实现。进程可以跳转到的内核位置叫做进程可以跳转到的内核位置叫做sysem_callsysem_call。这个过程检查系统调用号,。这个过程检查系统调用号,该号码告诉内核进程请求哪种服务。然后该号码告诉内核进程请求哪种服务。然后内核进程查看系统调用表内核进程查看系统调用表(sys_call_table)(sys_call_table)找到所调用的内核函数入口地址。接着调找到所调用的内核函数入口地址。接着调用相应的函数,在返回后做一些系统检查用相应的函数,在返回后做一些系统检查,最后返回到进程(如果这个进程时间用,最后返回到进程(如果这个进程时间用尽,则返回到其他进程)。尽,则返回到其他进程)。sysem_callsysem_call的的代码在源码代码在源码/kernel/entry.s/kernel/entry.s...