系统调用

内核提供一系列实现预定功能的内核函数,通过一组称为「系统调用」(system call)的接口呈现给用户。系统调用把应用程序的请求传达给内核,内核调用对应的内核函数完成请求所需处理后,再将处理结果返回给应用程序。

内核的主体是系统调用的集合,可以把内核看做特殊的公共子程序。系统调用是应用程序获得操作系统服务的唯一途径。

系统调用是一种中介,把用户与硬件隔离开来,应用程序通过系统调用才能请求系统服务和使用系统资源。系统调用的作用有

  • 内核可基于权限和规则对资源访问进行裁决,保证系统的安全性;
  • 系统调用封装资源抽象,提供一致性接口,避免用户使用资源时可能发生的错误,且使编程方便效率高。

系统调用可以大致分为

  • 进程和作业管理
  • 文件操作
  • 设备管理
  • 主存管理
  • 信息维护
  • 进程通信

系统调用实现时,需要注意:

  • 编写系统调用处理内核函数;
  • 设计一张系统调用入口地址表,每个入口地址都指向一个系统调用的处理内核函数,有的系统还包含系统调用自带参数的个数;
  • 陷入处理机制需开辟现场保护区,以保存发生系统调用时的处理器现场。

系统调用的处理过程可表示为

img-2024-03-08 21-19-56.png

系统调用的参数传递,可由访管指令或陷入指令自带参数,分为:

  • 直接参数
  • 间接参数

通过 CPU 的通用寄存器传递参数,或在主存的一个块或表中存放参数,其首地址送入寄存器,实现参数传递。也可在主存中开辟专用堆栈区域传递参数。

系统调用与函数调用的区别在于:

  • 调用形式和实现方式不同。函数一般调用指令,其专项地址包含在跳转语句中。系统调用不包含处理程序入口,仅提供功能号,按功能号调用
  • 被调用代码的位置不同。函数调用时,调用程序和被调用代码在同一程序中。系统调用的处理代码在调用程序之外(在操作系统中)
  • 提供方式不同。函数有编译系统提供,不同编译系统提供的函数可以不同。系统调用函数由操作系统提供,对设计好的操作系统,系统调用的功能、种类与数量固定不变。

在 Linux 系统中,系统调用通过 0x80 号中断实现,