CoderMrWu

生活诚可期,爱情价更高!

操作系统的系统调用是什么以及系统调用的结构

为了从操作系统中获得服务,用户程序必须使用系统调用( System Call),系统调用陷入内核并调用操作系统。访管指令把目态切换成管态,并启用操作系统。当有关工作完成之后,在系统调用后面的指令把控制权返回给用户程序。本节介绍系统调用的概念,系统调用的分类,以及系统调用的执行过程。

一、系统调用简介

所谓系统调用,就是用户在程序中调用操作系统所提供的一些子功能。这是一种特殊的过程调用,这种调用通常是由特殊的机器指令实现的。除了提供对操作系统子程序的调用外,这条指令还将系统转入特权方式(管态)。因此,系统调用程序被看成是一个低级的过程,只能由汇编语言直接访问。系统调用是操作系统提供给编程人员的唯一接口。编程人员利用系统调用,动态请求和释放系统资源,调用系统中已有的系统功能来完成与计算机硬件部分相关的工作以及控制程序的执行速度等。因此,系统调用像一个黑箱子那样,对用户屏蔽了操作系统的具体动作而只提供有关的功能。

1、系统调用与函数调用的区别

由于操作系统的特殊性,应用程序不能采用一般的函数调用方式来调用这些功能过程,而是利用一种系统调用命令去调用所需的操作系统过程。因此,系统调用在本质上是应用程序请求操作系统核心完成某一特定功能的一种函数调用,是一种特殊的函数调用,它与一般的函数调用有以下几方面的区别。

(1)运行在不同的系统状态

一般的函数调用,其调用程序和被调用程序都运行在相同的状态:管态或目态;而系统调用与函数调用的最大区别就在于:调用程序运行在目态,而被调用程序则运行在系统态。

(2)状态的转换

一般的函数调用不涉及系统状态的转换,可直接由调用过程转向被调用过程;但在运行系统调用时,由于调用和被调用过程工作在不同的系统状态,因而不允许由调用过程直接转向被调用过程,通常都是通过软中断机制先由目态转换为管态,在操作系统核心分析之后,转向相应的系统调用处理子程序。

(3)返回问题

一般的函数调用在被调用过程执行完后,将返回到调用过程继续执行。但是,在采用抢占式调度方式的系统中,被调用过程执行完后,系统将对所有要求运行的进程进行优先级分析。如果调用进程仍然具有最高优先级,则返回到调用进程继续执行;否则,将引起重新调度,以便让优先级最高的进程优先执行。此时,系统将把调用进程放入就绪队列。

(4)嵌套调用

像一般过程一样,系统调用也允许嵌套调用,即在一个被调用过程的执行期间,还可再利用系统调用命令去调用另一个系统调用。在一般情况下,每个系统对嵌套调用的深度都有定的限制。

2、系统调用的分类

通常,一个操作系统的功能分为两大部分:一部分是系统自身所需要的;另一部分功能是作为服务提供给用户的,有关这部分功能可以从操作系统所提供的系统调用上体现出来。

不同的操作系统所提供的系统调用会有一定的差异。对于一般通用的操作系统而言,可将其所提供的系统调用分为以下几方面。

(1)进程控制类系统调用

这类系统调用主要用于对进程的控制,如创建和终止进程的系统调用、获得和设置进程属性的系统调用等。

(2)文件操作类系统调用

对文件进行操纵的系统调用数量较多,有创建文件、打开文件、关闭文件、读文件、写文件、创建一个目录、建立目录、移动文件的读/写指针、改变文件的属性等。

(3)进程通信类系统调用

该类系统调用被用在进程之间传递消息和信号。

(4)设备管理类系统调用

该类系统调用被用于请求和释放有关设备,以及启动设备操作等

(5)信息维护类系统调用

操作系统中还提供了一类有关信息维护的系统调用。用户可利用这类系统调用来获得当前时间和日期、设置文件访问和修改时间、了解系统当前的用户数、操作系统版本号、空闲内存和磁盘空间的大小等。

不同的系统提供有不同的系统调用。一般,每个系统为用户提供几十到几百条系统调用。

系统调用命令是作为扩充机器指令,增强系统的功能,方便用户使用而提供的。因此,在一些计算机系统中,把系统调用命令称为“广义指令”。但“广义指令”和机器指令在性质上是不同的。机器指令是由硬件线路直接实现的,而“广义指令”则是由操作系统所提供的一个或多个子程序模块,即软件实现的。从用户角度来看,操作系统提供了这些“广义指令”,也就是系统调用指令,就好像扩大了机器的指令系统,增强了处理器的功能。用户不仅可以使用硬件提供的机器指令,也可以直接使用软件,即操作系统提供的广义指令,这就如同为用户提供了一台功能更强,使用更方便的处理器,即实现了处理器性能上的扩充。为了区别于真实的物理处理器,我们称它为“虚处理器”。

3、系统调用与库函数、API、内核函数的关系

库函数是在C语言程序设计中,所有匹配标准的头文件( Head file)的集合,以及常用的函数库实现程序。应用程序接口( ApplicationProgramming Interface,API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定,它是提供给应用程序调用使用的代码。库函数与API的主要目的是让应用程序开发人员得以调用一组例程功能,而无须考虑其底层的源代码为何或理解其内部工作机制的细节。在编写应用程序时,用户使用库函数和APⅠ来完成具体功能的实现。

通常应用程序是使用API在用户空间里实现的,而不是直接使用系统调用实现的,用户使用库函数和AP来完成系统调用的执行,这二者相当于是系统调用的封装。系统调用是操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务。具体关系如图2-7所示。

二、系统调用的处理过程

为了提供系统调用功能,操作系统内必须有事先编制好的、实现这些功能的子程序或过程。显然,这些程序或过程是操作系统程序模块的一部分,且不能直接被用户程序调用。而且,为了保证操作系统程序不被用户程序破坏,一般操作系统都不允许用户程序访问操作系统的系统程序和数据。那么,编程人员给定了系统调用名和参数之后是怎样得到系统服务的呢?显然,这里需要有一个类似于硬件中断处理的中断处理机构。当用户使用操作系统调用时,产生一条相应的指令,处理器在执行到该指令时发生相应的中断,并发出有关的信号给该处理机构;该处理机构在收到了处理器发来的信号后,启动相关的处理程序去完成该系统调用所要求的功能。

在系统中为控制系统调用服务的机构称为陷入(Trap)或异常处理机构。与此相对应,把由于系统调用引起处理器中断的指令称为陷入或异常指令(或称访管指令)。在操作系统中,每个系统调用都对应一个事先给定的功能号,例如0,1,2,3等。在陷入指令中必须包括对应系统调用的功能号。而且,在有些陷入指令中,还带有传给陷入处理机构和内部处理程序的有关参数。

为了实现系统调用,系统设计人员还必须为实现各种系统调用功能的子程序编造入口地址表,每个入口地址都与相应的系统程序名对应起来。然后,陷入处理程序把陷入指令中所包含的功能号与该入口地址表中的有关项对应起来,从而由系统调用功能号驱动有关子程序执行。

由于在系统调用处理结束之后,用户程序还需利用系统调用的返回结果继续执行,因此,在进入系统调用处理之前,陷入处理机构还需保存处理器现场。再者,在系统调用处理结束之后,还要恢复处理器现场。在操作系统中,处理器的现场一般被保护在特定的内存区或寄存器中,系统调用的处理过程如图2-8所示。当处理器执行到特殊的陷入指令时,首先会调用中断,通过査中断向量表把控制权转给系统调用总入口程序,该程序会对现场进行保存,包括将参数保存在内核堆栈里,通过查系统调用表把控制权转给相应的系统调用处理例程或内核函数,然后执行系统调用历程,完成后恢复现场并返回用户程序。

有关系统调用的另一个问题是参数传递过程问题。不同的系统调用需要传递给系统子程序以不同的参数,而且,系统调用的执行结果也要以参数形式返回给用户程序。那么,怎样实现用户程序和系统程序之间的参数传递呢?下面介绍几种常用的实现方法。

第一种方法是由陷入指令自带参数。一般来说,一条陷入指令的长度总是有限的,而且,该指令还要携带个系统调用的功能号,从而,陷入指令只能自带有限的几个参数进人系统内部。

第二种方法是通过有关通用寄存器来传递参数。显然,这些寄存器应是系统程序和用户程序都能访问的。

第三种方法是在内存中开辟专用堆栈区来传递参数

UNⅨX类操作系统通常采用第二种方法,即通过通用寄存器传递参数。

该文章转载于自考库,如有侵权,请联系删除

点赞