一、计算机系统的组成
1、计算机系统由硬件和软件组成,软件包括操作系统和普通软件,如下图所示:
多数计算机有两种运行模式:内核态和用户态。操作系统运行于内核态,可以执行机器支持的任何指令;普通软件运行于用户态,只能执行机器指令的一个子集(如I/O操作相关指令在用户态中是被禁止的)。
2、任何单CPU计算机一次只能执行一条指令。如果一个过程正在用户态运行一个用户程序,并且需要一个系统服务,比如从一个文件读数据,那么它就必须执行一个陷阱或系统调用命令,将控制权转移到操作系统。操作系统接着通过参数检查,找出所需的调用过程。然后,它执行系统调用,并把控制权返回给在系统调用后面跟随着的指令。
二、计算机系统的软件层次
1、操作系统主要有两种功能:管理计算机资源(控制硬件)和为用户提供抽象(提供服务)。在计算机系统软件中,操作系统由于通常比较小并且位于核心位置,因此被称为内核。操作系统与计算机系统软件中其它部分的关系如下图所示:
内核的外面是一层称为系统调用的软件,库过程(库调用)建立在系统调用之上,应用软件可以使用库过程也可以直接使用系统调用,而shell是一个用于运行其它应用软件的特殊应用软件。
2、以上是严格意义上的操作系统定义,但是从广义上来说,操作系统包括内核和所有其它能使得计算机变得有用的软件(如系统工具、应用、shell、通用库等等)。
三、系统调用
1、操作系统为程序的运行提供服务,典型的服务包括执行新程序、打开文件、读写文件、分配内存、获取当前时间等。操作系统通过一组数量有限并且定义良好的入口点来“暴露”其提供的服务,这些入口点就是系统调用。
2、在系统调用的具体实现上,UNIX系统采取的方式为让每个系统调用都对应一个同名的C函数(如write, read等)(别的操作系统可能使用汇编语言来实现)。C函数所做的工作可能是将该函数的参数放入CPU通用寄存器,然后执行一些机器指令来使内核产生软件中断。
这些系统调用对应的C函数对应的文档为Secion 2 of UNIX Programmer’s Manual,在Ubuntu终端执行man man命令可以看到:(第2类即为系统调用)
3、从系统实现者的角度来看,系统调用与相应的同名C函数并不是同一个东西;但是从应用开发者的角度来看,可以把这些C函数直接称为系统调用,并且在某种意义上说,调用这些C函数与调用普通的C函数并没有什么不同。
四、库调用
库调用建立在系统调用之上,本身并不是用于获取内核服务的“入口点”,但是其内部可能会调用一个或多个系统调用,通常用于为应用程序提供一些更加方便的功能。因此,库过程可以是对系统调用的“包装”,从而为应用程序提供一些更加实用和便捷的服务。例如:sbrk是一个提供基本内存管理功能——增加或减少一个进程的地址空间的系统调用,而malloc则是一个在sbrk的基础上实现了特定分配策略的内存管理库过程,它们的关系如下图所示:
库调用对应的文档为Secion 3 of UNIX Programmer’s Manual。
POSIX标准定义了大约100个过程调用,这些调用所提供的服务确定了多数操作系统所应该具有的功能。值得注意的是,POSIX标准并没有规定这些过程调用是系统调用、库调用还是其它形式。不过,多数过程调用都确实进行系统调用,通常是一个过程直接映射到一个系统调用上。
这些过程调用可以分为4类:进程管理、文件管理、目录与文件系统管理和杂项。其中文件管理的过程调用如下图所示:
参考:
《现代操作系统》
《UNIX环境高级编程》