I/O操作的实现

2019-03-25  本文已影响0人  菜根小友

目录

  1. I/O子系统概述
  2. 用户空间I/O软件
  1. I/O硬件与软件接口
  1. 内核空间I/O软件

I/O子系统概述

使用高级语言编写程序时,通常利用编译系统提供的专门的I/O库函数来实现外设的I/O功能,而I/O库函数通常将具体的I/O操作功能通过相应的陷阱指令(自陷制令,有时也叫做“软中断指令”),以“系统调用”的方式转换为由操作系统内核来实现。也就是说,任何I/O操作过程最终都是由操作系统内核控制完成的。

8.1 I/O子系统概述

I/O子系统也采用层次结构。包括I/O软件I/O硬件两大部分。

操作系统在I/O子系统中承担极其重要的作用,这主要是由I/O子系统的以下三个特性决定的:

用户程序总是通过某种I/O函数或者I/O操作符请求I/O操作。下图给出了用户程序用printf()来调出内核提供的write系统调用的过程。


image.png

可以看出,对于一个C语言用户程序,若在某过程(函数)中调用了printf(),则在执行到调用printf()语句时,便会转到C语言函数库中对应的I/O标准库printf()去执行,而printf()最终又会转到调用函数write();在执行到write()语句时,便会通过一系列步骤在内核空间中找到write对应的系统调用服务例程来执行,从而从用户态转到内核态执行。

每个系统调用的封装函数会被转换为一组与具体机器架构相关的指令序列,这个指令序列中至少有一条陷阱指令,在陷阱指令之前还可能有若干条传送指令用于将I/O操作的参数送入相应的寄存器。

I/O子系统工作的大致过程如下:首先,CPU在用户态执行用户进程,当CPU执行到系统调用封装函数对应的指令序列中的陷阱指令时,会从用户态陷入到内核态;转到内核态执行后,CPU根据陷阱指令执行时EAX寄存器中的系统调用号,选择执行一个相应的系统调用服务例程;在系统调用服务例程的执行过程中可能需要调用具体设备的驱动程序;在设备驱动程序执行过程中启动外设工作,外设准备好后发出中断请求,CPU响应中断后,就调出中断服务程序执行,在中断服务程序中控制主机与设备进行具体的数据交换。

image.png
如图所示,假定用户程序有一个语句调用了库函数printf(),在printf()函数中又通过一系列的函数调用,最终转到调用write()函数,在write()函数对应的指令序列中,一定有一条用于系统调用的陷阱指令。该陷阱指令执行后,进程就从用户态陷入到内核态执行。Linux中有一个系统调用的统一入口,即系统调用处理程序system_call()。CPU执行陷阱指令后,便转到system_call()的第一条指令执行。在system_call()中,将根据EAX寄存器中的系统调用号跳转到当前的系统调用服务例程sys_write()去执行。system_call()执行结束时,从内核态返回到用户态下的陷阱指令后面一条指令继续执行。
上一篇 下一篇

猜你喜欢

热点阅读