【操作系统】第九章-操作系统接口

九、操作系统接口

前言

操作系统作为计算机系统资源的管理者,对系统中的所有硬件和软件资源进行统一的管理和操纵。无论是用户(程序)或OS的外层软件,凡是涉及到系统资源的有关操作,都必须作为服务请求提交给OS,由它来完成。为了使用户能方便地使用计算机,操作系统提供了相应的用户接口,帮助用户快速、有效、安全、可靠地操纵计算机系统中的各类资源,完成相关的处理。一般地,操作系统向用户提供了两类接口,即用户接口和程序接口。值得说明的是,在Internet广为流行的今天,OS又增加了一种面向网络的网络用户接口。

1.用户接口

1.1 字符显示式联机用户接口

字符显示式联机用户接口又称为联机命令接口,是指用户通过命令语言实现对作业的控制,以及取得操作系统的服务。即用户在实现与机器的交互时,先在终端的键盘上键入所需的命令,由终端处理程序接收该命令,并在用户终端屏幕上以字符显示方式反馈用户输入的命令信息、命令执行及执行结果信息。

所谓命令语言,就是以命令为基本单位,指示操作系统完成特定的功能,由诸多命令组成了命令集,完整的命令集包括了操作系统提供给用户可使用的全部功能。而命令是由一组命令动词和参数组成的,具有规定的此法、语法、语义和表达形式,用户在终端键盘上以命令行的形式输入,并提交给系统。不同操作系统所提供的命令语言在词法、语法、语义即表达形式等方面各不相同。通常,命令语言可分为两种方式:

  1. 命令行方式

    该方式是以行为单位,输入和显示不同的命令。每行长度一般不超过256个字符,一般情况下,以回车作为一个命令的结束标记。通常,命令的执行采用的是间断式的串行执行方式,即后一个命令的输入一般需等到前一个命令执行结束。

    在许多操作系统中也提供了命令的并行执行方式。例如,当两条命令的执行是不相关的情况下,即用户对一条命令的执行结果并不急需,而且该命令的执行可能需要耗费较长时间时,用户可以在该命令的结尾输入特定的标记,将该命令作为后台命令处理,这样,用户不必等待该命令执行完毕,即可继续输入下一条命令,系统便可对两条命令进行并行处理。

  2. 批命令方式

    在操作命令的实际使用过程中,经常遇到需要对多条命令的连续使用、或对若干条命令的重复使用、或对不同命令进行选择性使用的情况,如果用户每次都采用命令行方式将命令一条条由键盘输入,既浪费时间,又容易出错。因此,操作系统都支持一种称为批命令的特别命令方式,允许用户预先把一系列命令组织在一种称为批命令文件的文件中,一次建立,多次执行。使用这种方式可减少用户输入命令的次数,既节省了时间,减少了出错概率,又方便了用户。通常批命令文件都有特殊的文件扩展名,如MS-DOS系统的.BAT文件。

1.2 图形化联机用户接口

  1. 图形用户接口GUI(Graghics User Interface)的引入

    虽然用户可以通过命令行方式和批命令方式,取得操作系统的服务,并控制自己的作业运行,但却要牢记各种命令的动词和参数,必须严格按规定的格式输入命令,而且不同操作系统所提供的命令语言的此法、语法、语义及表达形式是不一样的,这样既不方便又花费时间。于是,图形化用户接口GUI便应运而生。

  2. 使用WIMP技术

    GUI采用了图形化的操作界面,使用WIMP技术,该技术将窗口(Window)、图标(Icon)、菜单(Menu)、鼠标(Pointing device)和面向对象技术等集成在一起,引入形象的各种图标,将系统的各项功能、各种应用程序和文件直观、逼真地表示出来,形成一个图文并茂的视窗操作环境。

  3. Windows的GUI简介

    以Microsoft公司的Windows操作系统为例,在系统初始化后,OS为终端用户生成了一个运行explorer.exe的进程,它运行一个具有窗口界面的命令解释程序,该窗口是一个特殊的窗口,即桌面。在“开始”菜单中罗列了系统的各种应用程序,点击某个程序,则解释程序会产生一个新进程,由新进程弹出一个新窗口,并允许该应用程序,该新窗口的菜单栏或图标栏会显示应用程序的子命令。用户可进一步选择并点击子命令,如果该子命令需要用户输入参数,则会弹出一个对话窗口,指导用户进行命令参数的输入,完成后用户点击“确定”按钮,命令进入执行处理过程。

    在Windows系统中,采用的是事件驱动控制方式,用户通过动作来产生事件,以驱动程序工作。事件实质就是发送给应用程序的一个消息,用户的按键或点击鼠标等动作都会产生一个事件,通过中断系统引出事件驱动控制程序工作,对事件进行接收、分析、处理和清除。各种命令和系统中所有的资源,如文件、目录、打印机、磁盘、各种系统应用程序等,都可以定义为一个菜单、一个按钮或一个图标。所有的程序都拥有窗口界面,窗口中所使用的滚动条、按钮、编辑框、对话框等各种操作对象,都采用统一的图形显示方式和操作方法。用户可以通过鼠标(或键盘)点击操作,选择所需要的菜单、图标或按钮,从而达到控制系统、运行某个程序、执行某个操作(命令)的目的。

1.3 联机命令的类型

  1. 系统访问类

    在多用户系统中,为了保证系统的安全性,都毫无例外地设置注册命令Login。凡要在多用户系统的终端上上机的用户,都必须先在系统管理员处获得一合法的注册名和口令。以后,每当用户在接通其所用终端的电源后,便由系统直接调用,并在屏幕上显示出以下的注册命令:

    Login: /提示用户键入自己的注册名

    当用户键入正确的注册名并按下回车键后,屏幕上又会出现:

    Password: /提示用户键入自己的口令

    用户在键入口令时,系统将关闭掉回送显示,以使口令不在屏幕上显示出来。如果键入的口令正确而使注册成功时,屏幕上会立即出现系统提示符(所用符号随系统而异),表示用户可以开始键入命令。如果用户多次(通常不超过三次)键入的注册名或口令都有错,系统将解除与用户的联接。

  2. 文件操作命令

    每个操作系统都提供了一组文件操作命令。在微机OS中文件操作命令有:

    (1) 显示文件命令type,用于将指定文件内容显示在屏幕上。

    (2) 拷贝文件命令copy,用于实现文件的拷贝。

    (3) 文件比较命令comp,用于对两个指定文件进行比较,两文件可以在同一个或不同的驱动器上。

    (4) 重新命名命令Rename,用于将以第一参数命名的文件改成用第二参数给定的名字。

    (5) 删除文件命令erase,用于删除一个或一组文件。

  3. 目录操作命令

    (1) 建立子目录命令mkdir

    (2) 显示目录命令dir

    (3) 删除子目录命令rmdir

    (4) 显示目录结构命令tree

    (5) 改变当前目录命令chdir

  4. 其他命令

    (1) 输入输出重定向命令

    (2) 管道连接

    (3) 过滤命令

    (4) 批命令

2.Shell命令语言

2.1 简单命令简介

  1. 简单命令的格式

    简单命令的格式比较自由,包括命令名字符的个数及用于分隔命令名、选项、各参数间的空格数等,都是任意的。命令的格式如下:

    $ Command -option argument list

  2. 简单命令的分类

    (1) 系统提供的标准命令

    (2) 用户自定义的命令

  3. Shell的种类

    (1) Bourne Shell

    (2) C Shell

    (3) Korn Shell

2.2 简单命令的类型

根据简单命令功能的不同,可将它们分成如下五大类:

  1. 进入和退出系统

    (1) 进入系统,也称为注册

    (2) 退出系统

  2. 文件操作命令

    (1) 显示文件内容命令cat

    (2) 复制文件副本的命令cp

    (3) 对已有文件改名的命令mv

    (4) 撤销文件的命令rm

    (5) 确定文件类型的命令file

  3. 目录操作命令

    (1) 建立目录的命令mkdir(简称md)

    (2) 撤销目录的命令rmdir(简称rd)

    (3) 改变工作目录的命令cd

  4. 系统询问命令

    (1) 访问当前日期和时间命令date

    (2) 询问系统当前用户的命令who

    (3) 显示当前目录路径名的命令pwd

2.3 重定向与管道命令

  1. 重定向命令

    在Linux系统中,由系统定义了三个文件。其中,有两个分别称为标准输入和标准输出的文件,各对应于终端键盘输入和终端屏幕输出。它们是在用户注册时,由Login程序打开的。这样,在用户程序执行时,隐含的标准输入是键盘输入,标准输出即屏幕(输出)显示。但用户程序中可能不要求从键盘输入,而是从某个指定文件上读取信息供程序使用;同样,用户可能希望把程序执行时所产生的结果数据写到某个指定文件中而非屏幕上。为此,用户必须不使用标准输入、标准输出,而把另外的某个指定文件或设备作为输入或输出文件。

    Shell向用户提供了这种用于改变输入、输出设备的手段,此即标准输入与标准输出的重定向。用重定向符“<”和“>”分别表示输入转向与输出转向。

  2. 管道命令

    人们又进一步把重定向思想加以扩充,用符号“|”来连接两条命令,使其前一条命令的输出作为后一条命令的输入。

2.4 通信命令

  1. 信箱通信命令mail

    信箱通信是作为在UNIX的各用户之间进行非交互式通信的工具。发信者把要发送的消息写成信件,“邮寄”到对方的信箱中。通常各用户的私有信箱采用各自的注册名命名,即它是目录/usr/spool/mail中的一个文件,而文件名又是用接收者的注册名来命名的。信箱中的信件可以一直保留到被信箱所有者消除为止。mail命令在用于发信时,把接收者的注册名当做参数输入后,便可在新行开始键入信件正文,最后仍在一个新行上,用“.”来结束信件或用“^D”退出mail程序(也可带选项)。接收者也用mail命令读取信件,可使用可选项r、q或p等。其命令格式为:mail

  2. 对话通信命令write

    用这条命令可以使用户与当前在系统中的其他用户直接进行联机通信。由于UNIX系统允许一个用户同时在几个终端上注册,故在用此命令前,要用who命令去查看目标用户当前是否联机,或确定接收者所使用的终端名。命令格式为:write user[ttyname],当接收者只有一个终端时,终端名可缺省。

  3. 允许或拒绝接收消息的mesg命令

    其格式为:mesg[-n][-y]

    选项n表示拒绝对方的写许可(即拒绝接收消息);选项y指示恢复对方的写许可,仅在此时双方才可联机通信。

2.5 后台命令

有些命令需要执行很长时间,这样,当用户键入该命令后,便会发现自己已无事可做,要一直等到该命令执行完毕,方可再键入下一条命令。这时用户自然会想到应该利用这段时间去做别的事。UNIX系统提供了这种机制,用户可以在这种命令后面再加上“&”号,以告诉Shell将该命令放在后台执行,以便用户能在前台继续键入其他命令,完成其他工作。

在后台运行的程序仍然把终端作为它的标准输出和标准输入文件,除非对它们进行重新定向。其标准输入文件是自动地被从终端定向到一个称为“/dev/null”的空文件中。若shell未重定向标准输入,则shell和后台进程将会同时从终端读入。这时,用户从终端键入的字符可能被发送到一个进程或另一个进程,并不能预测哪个进程将得到该字符。因此,对所有在后台运行的命令的标准输入,都必须加以重定向,从而使从终端键入的所有字符都被送到Shell进程。用户可使用ps、wait及Kill命令去了解和控制后台进程的运行。

3.联机命令接口的实现

3.1 键盘终端处理程序

  1. 字符接收功能

    为了实现人机交互,键盘终端处理程序必须能够接收从终端输入的字符,并将之传送给用户程序。有两种方式可实现字符接收功能:

    (1) 面向字符方式。

    (2) 面向行方式。

  2. 字符缓存功能

    为了能暂存从终端键入的字符,以降低中断处理器的频率,在终端处理程序中,还必须具有字符缓存功能。字符缓存功能可采用以下两种方式之一:

    (1) 专用缓冲方式。

    (2) 公用缓冲方式。

    在这里插入图片描述

  3. 回送显示

    回送显示(回显)是指每当用户从键盘输入一个字符后,终端处理程序便将该字符送往屏幕显示。

  4. 屏幕编辑

    用户经常希望能对从键盘打入的数据(字符)进行修改,如删除(插入)一个或多个字符。为此,在终端处理程序中,还应能实现屏幕编辑功能,包括能提供若干个编辑键。

  5. 特殊字符处理

    终端处理程序必须能对若干特殊字符进行及时处理,这些字符是:

    (1) 中断字符

    (2) 停止上卷字符

    (3) 恢复上卷字符

3.2 MS-DOS解释程序

  1. 命令解释程序的作用

    在联机操作方式下,终端处理程序把用户键入的信息送至键盘缓冲区中保存。一旦用户键入回车符,便立即把控制权交给命令解释程序。显然,对于不同的命令,应有能完成特定功能的命令处理程序与之对应。可见,命令解释程序主要作用是在屏幕上给出提示符,请用户键入命令,然后读入该命令,识别命令,再转到相应命令处理程序的入口地址,把控制权交给该处理程序去执行,并将处理结果送至屏幕上显示。若用户键入的命令有错,而命令解释程序未能予以识别,或在执行终结出现问题时,则应显示出某一出错信息。

  2. 命令解释程序的组成

    (1) 常驻部分

    (2) 初始化部分

    (3) 暂存部分

  3. 命令解释程序的工作流程

    在这里插入图片描述

3.3 Shell解释程序

  1. Shell命令的特点

    前面我们介绍了MS-DOS的命令解释程序,它非常简单。而Shell命令解释程序就复杂得多,这主要是因为Shell命令的类型多而复杂所致。主要表现如下:

    (1) 一条命令行中含有多个命令。

    (2) 具有不同的分隔符。

  2. 二叉树结构的命令行树

    (1) 命令表型结点

    Shell命令解释程序按命令行语句的结构顺序进行检查,每当遇到“;”及“&”分隔符时便为之建立一个命令表型结点,将分隔符左面部分构成该结点的左子树,右面部分构成右子树。例如下面的命令行所构成的命令树如下图所示:

    Coomand 1; Command 2; &Command 3

    由于每一条命令对应了一个处理进程,故在执行命令树时,对应于每一条命令都需要为之创建一个进程,由此为命令树生成一个对应的进程树。在具体执行时,对于“;”型结点,先递归地执行其左子树,待其左子树执行完后,再执行其右子树。对于“&”型结点,可在启动了左子节点执行后,无须等待它执行完毕,便可转去执行其右子结点。

    在这里插入图片描述

    (2) 管道文件型结点

    当Shell命令解释程序遇到管道算符“|”时,先为之建立一个管道文件型结点,再将分隔符左面部分构成该结点的左子树,右面部分构成右子树。例如对下面的命令行所构成的命令如下图所示:

    Command 1 | Command 2 | Command 3

    在这里插入图片描述

    (3) 简单命令型结点

    对于简单命令,在命令行中仅有一条命令,它是属于可以立即执行的命令,系统无需为它建立二叉树结构的命令行树。

  3. Linux命令解释程序的工作流程

    在Linux系统中,系统初启后,内核为每个终端建立一个进程,去执行Shell解释程序。它的执行过程基本上按如下步骤进行:

    (1) 读取用户有键盘输入的命令行。

    (2) 对命令进行分析。

    (3) 建立相应的子进程。

    (4) 等待子进程完成。

    (5) 对于“&”型结点,在其左子结点执行后,直接执行其右子树。

    在这里插入图片描述

4.系统调用的概念和类型

程序接口,是OS专门为用户程序设置的,提供给程序员在编程时使用,也是用户程序获得OS服务的唯一途径。它是由一组系统调用(system call)组成,因而,也可以说,系统调用提供了用户程序和操作系统内核之间的接口。系统调用不仅可供所有的应用程序使用,而且也可供OS自身使用。在每个系统中,通常都有几十条甚至上百条的系统调用,并可根据其功能把它们划分成若干类,每一个系统调用都是一个能完成特定功能的子程序。

4.1 系统调用的基本概念

  1. 系统态和用户态

    在计算机系统中设置了两种状态:系统态(或称为核心态)和用户态。在实际运行过程中,处理机会在系统态和用户态间切换。相应地,现代多数OS将CPU的指令集分为特权指令和非特权指令两类。

    (1) 特权指令。特权指令是指在系统态运行的指令,它对内存空间的访问范围基本不受限制,不仅能访问用户空间,也能访问系统空间。

    (2) 非特权指令。非特权指令是在用户态运行的指令。应用程序所使用的都是非特权指令,它只能完成一般性的操作和任务,不能对系统中的硬件和软件直接进行访问,对内存的访问范围也局限于用户空间。

  2. 系统调用

    在OS中提供系统调用的目的,是使应用程序可以通过它直接调用OS中的相关过程,取得相应的服务。系统调用在本质上是应用程序请求OS内核完成某功能时的一种调用,但它是一种特殊的过程调用,它与一般的过程调用有下述几方面的明显差别:

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

    (2) 状态的转换。

    (3) 返回问题。

    (4) 嵌套调用。

  3. 中断机制

    系统调用是通过中断机制实现的,并且一个操作系统的所有系统调用,都通过同一个中断入口来实现。如MS-DOS提供了INT 21H,应用程序通过该中断获取操作系统的服务。

    对于拥有保护机制的OS来说,中断机制本身也是受保护的,在IBM PC上,Intel提供了多达255个中断号,但只有授权给应用程序保护等级的终端号,才是可以被应用程序调用的。对于未被授权的中断号,如果应用程序进行调用,同样会引起保护异常,而导致自己被操作系统停止。如Linux仅仅给应用程序授权了4个中断号:3,4,5以及80h。前三个中断号是提供给应用程序调试所使用的,而80h正是系统调用(system call)的中断号。

4.2 系统调用的类型

  1. 进程控制类系统调用

    (1) 创建和终止进程的系统调用。

    (2) 获得和设置进程属性的系统调用。

    (3) 等待某事件出现的系统调用。

  2. 文件操纵类系统调用

    (1) 创建和删除文件。

    (2) 打开和关闭文件的系统调用。

    (3) 读和写文件的系统调用。

  3. 进程通信类系统调用

    在单处理机系统中:

    • 消息传递方式
    • 共享存储区方式

4.3 POSIX标准

目前许多操作系统都提供了上面所介绍的各种类型的系统调用,实现的功能也相类似,但在实现的细节和形式方面却相差很大,这种差异给实现应用程序与操作系统平台的无关性带来了很大的困难。为了解决这一问题,国际标准化组织ISO给出了有关系统调用的国际标准POSIX1003.1(Portable Operating System IX),也称为“基于UNIX的可移植操作系统接口”。

下图示出了UNIX/Linux的系统程序、库函数、系统调用的层次关系。

在这里插入图片描述

5.UNIX系统调用

5.1 进程控制

  1. 进程的创建和终止

    (1) 创建进程(fork)

    (2) 终止进程(exit)

  2. 改变进程映像和等待

    (1) 执行一个文件(exec)

    (2) 等待子进程结束(wait)

  3. 其它进程调用

    (1) 获得进程ID

    (2) 获得用户ID

    (3) 进程暂停(pause)

5.2 文件操纵

  1. 文件的创建和删除
  2. 文件的打开和关闭
  3. 文件的读和写
  4. 建立与文件的连接和去连接

5.3 进程通信和信息保护

  1. 进程通信

    为了实现进程间的通信,在UNIX系统中提供了一个用于进程间通信的软件包,简称IPC。它由消息机制、共享存储器机制和信号量机制三部分组成。在每一种通信机制中,都提供了相应的系统调用供用户程序进行进程间的同步与通信用。

  2. 信息维护

    (1) 设置和获得时间

    (2) 获得进程和子进程时间(times)

    (3) 设置文件访问和修改时间(utime)

    (4) 获得当前UNIX系统的名称(uname)

6.系统调用的实现

系统调用的实现与一般过程调用的实现相比,两者间有很大差异。对于系统调用,控制是由原来的用户态转换为系统态,这是借助于陷入机制来完成的,在该机制中包括陷入硬件机构及陷入处理程序两部分。当应用程序使用OS的系统调用时,产生一条相应的指令,CPU在执行这条指令时发生中断,并将有关信号送给中断和陷入硬件机构,该机构收到信号后,启动相关的陷入处理程序进行处理,实现该系统调用所需要的功能。

6.1 系统调用的实现方法

  1. 系统调用号和参数设置

    往往在一个系统中设置了许多条系统调用,并赋予每条系统调用一个唯一的系统调用号。在系统调用命令(陷入指令)中把相应的系统调用号传递给中断和陷入机制的方法有很多,在有的系统中,直接把系统调用号放在系统调用命令(陷入指令)中;在另一些系统中,则将系统调用号装入某指定寄存器或内存单元中。

    每一条系统调用都含有若干个参数,在执行系统调用时,如何设置系统调用所需的参数,即如何将这些参数传递给陷入处理机构和系统内部的子程序(过程),常用的实现方式有以下几种:

    (1) 陷入指令自带方式。

    (2) 直接将参数送入相应的寄存器中。

    (3) 参数表方式。

  2. 系统调用的处理步骤

    系统调用的处理过程可分成以下三步:

    首先,将处理机状态由用户态转为系统态;之后,由硬件和内核程序进行系统调用的一般性处理,即首先保护被中断进程的CPU环境,将处理机状态字PSW、程序计数器PC、系统调用号、用户栈指针以及通用寄存器内容等压入堆栈;然后,将用户定义的参数传送到指定的地址并保存起来。

    其次,分析系统调用类型,转入相应的系统调用处理子程序。为使不同的系统调用能方便地转向相应的系统调用处理子程序,在系统中配置了一张系统调用入口表。表中的每个表目都对应一条系统调用,其中包含该系统调用自带参数的数目、系统调用处理子程序的入口地址等。因此,核心可利用系统调用号去查找该表,即可找到相应处理子程序的入口地址而转去执行它。

    最后,在系统调用处理子程序执行完后,应恢复被中断的或设置新进程的CPU现场,然后返回被中断进程或新进程,继续往下执行。

  3. 系统调用处理子程序的处理过程

    系统调用的功能主要是由系统调用子程序来完成的。对于不同的系统调用,其处理程序将执行不同的功能。我们以一条在文件操纵中常用的Creat命令为了来说明。

    进入Creat的处理子程序后,核心将根据用户给定的文件路径名Path,利用目录检索过程去查找指定文件的目录项。查找目录的方式可以用顺序查找法,也可用Hash查找法。如果在文件目录中找到了指定文件的目录项,表示用户要利用一个已有文件来建立一个新文件。但如果在该已有文件的属性中有不允许写属性,或者创建者不具有对该文件进行修改的权限,便认为是出错而做出错处理;若不存在访问权限问题,便将已存文件的数据盘块释放掉,准备写入新的数据文件。如果未找到指明文件,则表示要创建一个新文件,核心便从其目录中找出一个空目录项,并初始化该目录项,包括填写文件名、文件属性、文件建立日期等,然后将新文件打开。

6.2 UNIX系统调用的实现

在UNIX系统V的内核程序中,有一个trap.S文件,它是中断和陷入总控程序。该程序用于中断和陷入的一般性处理。为提供运行效率,该文件采用汇编语言编写。由于在trap.S中包含了绝大部分的中断和陷入向量的入口地址,因此,每当系统发生了中断和陷入情况时,通常都是先进入trap.S程序,由它先处理有关CPU环境保护的问题。

另外还有一个处理各种陷入情况的C语言文件,即trap.C程序,共有12种陷入的处理要调用trap.C程序(如系统调用、进程调用中断、跟踪自陷非法指令、访问违章、算术自陷等)用于处理在中断和陷入发生后需要处理的若干公共问题。如果因系统调用进入trap.C,它所要进行的处理将包括:确定系统调用号、实现参数传送、转入相应的系统调用处理子程序。在由系统调用处理子程序返回到trap.C后,重新计算进程的优先级,对收到的信号进行处理等。

  1. CPU环境保护

    当用户程序在用户态,且在执行系统调用命令(即CHMK命令)之前,应在用户空间提供系统调用所需的参数表,并将该参数表的地址送入R0寄存器。在执行CHMK命令后,处理机将由用户态转为核心态,并由硬件自动地将处理机状态长字(PSL)、程序计数器(PC)和代码操作数(code)压入用户核心栈,继而从中断和陷入向量表中取出trap.S的入口地址,然后便转入中断和陷入总控程序trap.S中执行。

    trap.S程序执行后,继续将陷入类型type和用户栈指针usp压入用户核心栈,接着还要将被中断进程的CPU环境中的一系列寄存器如R0 ~ R11的部分或全部压入栈中。至于哪些寄存器的内容要压入栈中,这取决于特定寄存器中的屏蔽码,该屏蔽码的每一位都与R0 ~ R11中的一个寄存器相对应。当某一位置成1时,表示对应寄存器的内容应压入栈中。

  2. AP和FP指针

    为实现系统调用的嵌套使用,在系统中还设置了两个指针,其一是系统调用参数表指针AP,用于指示正在执行的系统调用所需参数表的地址,通常是把该地址放在某个寄存器中;再者,还须设置一个调用栈帧指针。所谓调用栈帧(或简称栈帧),是指每个系统调用需要保存而被压入用户核心栈的所有数据项;而栈帧指针FP则是用于指示本次系统调用所保存的数据项。每当出现新的系统调用时,还须将AP和FP303压入栈中,如下图示出了在trap.S总控程序执行后用户核心栈的情况。

    在这里插入图片描述

  3. 确定系统调用号

    由上述得知,在中断和陷入发生后,应先经硬件陷入机构予以处理,再进入中断和陷入总控程序trap.S,在保护好CPU现场后再调用trap.C继续处理。

  4. 参数传送

    参数传送是指由trap.C程序将系统调用参数表中的内容从用户区传送到User结构的U.U-arg中,供系统调用处理程序使用。

  5. 利用系统调用定义表转入相应的处理程序

    在UNIX系统中,对于不同(编号)的系统调用,都设置了与之相应的处理子程序。为使不同的系统调用能方便地转入其相应的处理子程序,也将各处理子程序的入口地址放入了系统调用定义表即Sysent[]中。该表实际上是一个结构数组,在每个结构中包含三个元素,其中第一个元素是相应系统调用所需参数的个数;第二个元素是系统调用经寄存器传送的参数个数;第三个元素是相应系统调用处理子程序的入口地址。在系统中设置了该表后,便可根据系统调用号i从系统调用定义表中找出相应的表目,再按照表目中的入口地址转入相应的处理子程序,由该程序去完成相应系统调用的特定功能。在该子程序执行完后,仍返回到中断和陷入总控程序中的trap.C程序中,去完成返回到断点前的公共处理部分。

  6. 系统调用返回前的公共处理

    在UNIX系统中,进程调度的主要依据是进程的动态优先级。随着进程执行时间的加长,其优先级将逐步降低。每当执行了系统调用命令并由系统调用处理子程序返回到trap.C后,都将重新计算该进程的优先级;另外,在系统调用执行过程中,若发生了错误使进程无法继续运行时,系统会设置再调度标志。处理子程序在计算进程的优先级后,又去检查该再调度标志是否已又被设置。若已设置,便调用switch调度程序,再去从所有的就绪进程中选择优先级最高的进程,把处理机让给该进程去运行。

6.5 Linux系统调用

与UNIX相似,Linux采用类似技术实现系统调用。

Linux的系统调用号就是系统调用入口表中位置的序号。所有系统调用通过接口函数将系统调用号传给内核,内核转入系统调用控制程序,再通过调用号位置来定位核心函数。

系统调用控制程序的工作流程:①去系统调用号,检验合法性;②执行int 80h产生中断;③进行地址空间的转换,以及堆栈的切换,进入内核态;④进行中断处理,根据系统调用号定位内核函数地址;⑤根据通用寄存器内容,从用户栈中取入口参数;⑥核心函数执行,把结果返回应用程序。

6.6 Win32的应用程序接口

首先需要说明的是应用程序接口(API)与系统调用的区别和联系。API是一个函数的定义,说明如何获得一个给定的服务,而系统调用是通过中断向内核发出的一个请求。一个API函数可能不与任何系统调用相对应,也可以调用若干个系统调用,不同的API函数可能装了相同的系统调用。

Windows系统在程序设计模式上与UNIX以及Linux系统有着根本的不同。Windows程序采用的是事件驱动方式,即主程序等待事件的发生,如鼠标的点击、键盘的敲击或一个USB部件的插入等,然后根据事件内容,调用相应的程序进行处理。因此,在Windows系统中,定义了一系列的程序,称为Win32 API(Application Programming interface),用来提供操作系统的服务。

在Windows系统中,通过Kernel、User和GUI三个组件来支持API。Kernel包含了大多数操作系统函数,如内存管理、进程管理;User集中了窗口管理函数,如窗口创建、撤销、移动、对话及各种相关函数;GUI提供画图函数、打印函数。所有应用程序都共享这三个模块的代码,每个Windows的API函数都可通过名字来访问。具体做法是,在应用程序中使用函数名,并用适当的函数库进行编译和链接,然后,应用程序便可运行。实际上,Windows将三个组件置于动态链接库DDL(Dynamic Link Library)中。

猜你喜欢

转载自blog.csdn.net/m0_50833438/article/details/115186696