系统调用如何实现

   系统调用的实现与一般过程调用的实现相比,两者间有很大差异。对于系统调用,控制是由原来的用户态转换为系统态,这是借助于中断和陷入机制来完成的,在该机制中包括中断和陷入硬件机构及中断与陷入处理程序两部分。

  中断和陷入硬件机构

  图1所示为中断的处理过程。中断可进一步分为外中断和内中断。外中断是指由于外部设备事件所引起的中断,如通常的磁盘中断、打印机中断等;而内中断则是指由于CPU内部事件所引起的中断,如程序出错(非法指令、地址越界)等。内中断(trap)也被译为“陷入”或“陷阱”。


  通常,陷入是由于执行了现行指令引起的,而中断则是由于系统中某事件引起的,该事件与现行指令无关。为了处理上的方便,通常针对不同的设备编制不同的中断处理程序,并把该程序的入口地址放在某特定的内存单元中。此外,不同的设备也对应着不冋的处理机状态字PSW,且把它放在与中断处理程序入口指针相邻接的特定单元中。在进行中断处理时,只要有了这样两个字,便可转入相应设备的中断处理程序,重新装配处理机的状态字和优先级,进行对该设备的处理,因此这两个字被称为中断向量。相应地,把存放这两个字的单元称为中断向景单元。类似地,对于陷入也有陷入向量表。由所有的中断向景和陷入向景构成了中断和陷入向量表。

  系统调用号和参数的设置

  通常,一个系统中设置了几十条甚至上百条系统调用,系统赋予每条系统调用一个唯一的系统凋用号。在有的系统中,直接把系统凋用号放在系统凋用命令中,如IBM370和早期的UNIX系统,是用系统调用命令的低8位存放系统调用号;在另一些系统中,则将系统调用号装入某指定寄存器或内存单元中,如MS-DOS是将系统调用号放在AH寄存器中。每一条系统调用都含有若干个参数,在执行系统调用时,设置系统调用所需的系数通常有两种方式。

  (1)直接将参数送入相应的寄存器中。这是一种最简单的方式,MS-DOS采用的便是这种方式,即用MOV指令将各个参数送入相应的寄存器中。这种方式的主要问题是由于寄存器数量有限,因而限制了所设置参数的数目。

  (2)参数表方式。将系统调用所需的参数放入一张参数表中,再将指向该参数表的指针放在某个指定的寄存器中。在当前大多数的OS中,如UNIX系统,便是采用了这种方式。该方式又可进一步分成直接和间接两种方式,如图2所示。在直接参数方式中,将所有的参数值和参数的个数N都放入一张参数表中;而在间接参数方式中,则在参数表中仅存放参数个数和指向真正参数数据表的指针。


  系统调用的处理步骤

  在设置了系统凋用号和参数后,便可执行一条系统凋用命令。不同的系统可采用不同的执行方式。在UNIX系统中,是执行CHMK命令;而在MS-DOS中则是执行INT21软中断。

  系统调用的处理过程可分成以下3步。

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

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

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

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

  系统调用的功能主要是由系统调用子程序来完成的。对于不同的系统调用,其处理程序将执行不同的功能。

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

时间: 2025-01-07 18:07:19

系统调用如何实现的相关文章

win7系统出现“系统调用失败”该怎么办

  前不久,一位朋友打电话来求助:他刚使用Win7系统不久,但却遇到一个怪问题,按照通常的方式双击打开"计算机"(我的电脑)时,弹出"系统调用失败"的提示,这是怎么回事呢?到底是调用什么失败呢?让他一头雾水.其实这个问题并没有那么难,只是大家不了解罢了.这里就为大家介绍两种快速解决的方法. 方法一:使用IE浏览器 可以随便打开一个IE浏览器,在网址栏里面输入C:windowsexplorer.exe,然后就点击回车,这个方法其实还算是最简单的了,一般就可以解决问题的

系统调用追踪工具strace

当我们想知道某个进程为什么突然卡了,或者是某个工具到底是如何实现的时候.strace就派上了用场.它能将程序的调用信息打印出来. strace原理: 它的实现基础是ptrace系统调用.ptrace系统调用提供了一种方法来跟踪和控制进程的执行,它可以读取和修改进程地址空间中的内容,包括寄存器的值.ptrace主要用于实现断点调试和跟踪系统调用. ptrace系统调用 1 #include <sys/ptrace.h> 2 int ptrace(int request, int pid, int

ubuntu-增添一个系统调用,我的内核版本是linux3.13.0-46-generic.

问题描述 增添一个系统调用,我的内核版本是linux3.13.0-46-generic. 想要向ubuntu14.04内核增添一个系统调用,我的内核版本是linux3.13.0-46-generic.该怎么做. 解决方案 一.源码修改 1下载一个与所用系统内核版本接近的内核,放在/usr/src下,解压,作个链接ln -s linux-2.6.18.1 linux 2修改:修改三个地方 1)/usr/src/linux/kerner/sys.c中添加, asmlinkage int sys_my

minix添加系统调用

环境minix3.1.8 打印进程的vm信息: 添加系统调用分为三个部分: 1,库函数向用户提供接口: 2,pm接受消息处理信息: 3,vm接收消息处理信息.   1库函数添加:   1.1 posix/下添加print_vmmap函数,文件名命名为_print_vmmap.c: #include<lib.h>#define print_vmmap _print_vmmap#include<unistd.h>PUBLIC int print_vmmap(){ message m; 

kernel学习:系统调用的知识点

一般情况下,用户进程是不能访问内核空间的.它既不能访问内核中的数据,也不能访问内核中的函数.但在linux内核中设置了一组用于实现各种系统功能的函数,成为系统调用.用户可以在应用程序中调用它们. linux系统还提供了一些c库,这些库对系统调用进行了一些包装和扩展. 系统调用,POSIX,C库,系统命令和内核函数 1.系统调用和POSIX 虽然系统调用是内核和用户空间的桥梁,但是用户的应用程序在访问内核时是通过系统提供的应用编程接口API来实现的. 操作系统的API主要作用是把操作系统的功能全展

kernel学习之系统调用在用户空间的访问

这篇文章是对上篇的一个补充. 如何使用系统调用 1.通过c库来使用系统调用 2.在2.6.18之前的内核使用_syscall宏来使用系统调用. 3.在2.6.19开始废除了_syscall,而使用syscall()通过向函数提供调用号和参数实现调用 c语言中系统调用 #include <unistd.h> #include <stdio.h> #include <sys/syscall.h> #include <sys/types.h> int main()

kernel学习之系统调用过程分析

过程分析: 1.系统调用需要一个用户空间到内核空间的转换,不同的平台有不同的指令来完成这样的转换,这个指令也叫做操作系统陷入(operating systemtrap)指令.在linux中对于x86来说是用软中断0x80,也即是int $0x80.软中断由软件指令触发,硬中断由硬件触发. 通过软中断,系统会跳到一个预定的内核空间.它指向了系统调用处理程序(不是系统调用服务程序)system_call函数(arch/x86/kernel/entry32.h).如上图. 2.system_call到

kernel学习之动手添加系统调用(ARM)

我是在linux2.6.38中添加的系统调用,在mini6410开发板上测试的. 添加系统调用: 向内核中添加系统调用,需要执行三个步骤: 1.添加新的内核函数 2.更新unistd.h 3.更新系统调用表 1. 在kernel/sys.c中添加函数 asmlinkageint sys_add(int a,int b) { return a+b; } 2. 在arch/arm/include/asm/unistd.h 添加: #define_NR_add (_NR_SYSCALL+BASE +

如何在Salesforce中创建Web Service供外部系统调用

在Salesforce中可以创建Web Service供外部系统调用,并且可以以SOAP或者REST方式向外提供调用接口,接下来的内容将详细讲述一下用SOAP的方式创建Web Service并且用Asp.net的程序进行简单的调用. 1):在Salesforce中创建如下Class [注:要想使其成为web service,那么class一定要定义成global的,具体的方法要用 webService static 修饰] [代码中省略了GenerateAccountFromXmlInfo方法的

solaris的sar命令(二) 检查系统调用统计信息 (sar -c)

使用 sar -c 命令可显示系统调用统计信息. $ sar -c 00:00:00 scall/s sread/s swrit/s  fork/s  exec/s rchar/s wchar/s 01:00:00      38       2       2    0.00    0.00     149     120 示例 检查系统调用统计信息 (sar -c) 以下示例显示 sar -c 命令的输出. $ sar -c SunOS balmyday 5.10 s10_51 sun4u