《操作系统概念精要》之I/O系统

计算机的两个主要工作是I/O和处理,在很多情况下,主要工作是I/O,而处理只是附带的。例如:当浏览器网页和编辑文本时,直接兴趣是读取或者输入信息,而非计算。

计算机的操作系统I/O 的功能是,管理和控制I/O 操作和I/O设备。

概述

计算机设备的控制是操作系统的设计人员的主要关注之一。因为I/O设备的功能与速度差异很大。所以需要采用不同的方法来控制设备,这些方法构成了内核的I/O子系统。
I/O设备技术呈现两个冲突趋势。一方面。软件和硬件的接口标准化日益增长。这个趋势有助于将改进和升级设备,从而可以集成到计算机中。另一方面,I/O设备的种类也日益增多。为了封装各种设备的细节与特点,操作系统内核采用设备驱动程序。
设备驱动程序为I/O子系统提供了统一的设备访问接口。

内核I:O子系统结构.png

I/O硬件

设备与计算机系统的通信,可以通过电缆或者空气来进行发送信息。设备与计算机的通信通过一个连接点或者端口,比如串行端口。连接这些端口电缆就是总线。

一个典型的PC 总线的结构.png

总线在计算机体系中应用广泛。上图是一个典型的PC总线结构,图中,PCI 总线将内存和各个设备进行连接。 其他的设备都需要连接到PCI 总线上。 扩展总线连接相对较慢的设备。如键盘和串口USB端口。4个磁盘通过小型计算机系统接口(SCSI)总线连接到SCSI控制器。

控制器是可以操作端口和总线或者设备的一组电子器件。串行端口控制器是计算机内的单个芯片,用于控制串口线路信号。 SCSI控制器一般是比较复杂,遵循SCSI协议。一般为单独的电路板。他包括,处理器,微代码和一些专业内存。

处理器如何对控制器发出命令和数据以便完成I/O传输?
控制器是具有多个寄存器的,用于数据和控制信号。处理器通过读写这些寄存器的位模式与控制器通信。这种通信的一种方式是,通过使用特殊的I/O指令 针对I/O端口 地址传输一个字节或字。
I/O指令出发总线线路,选择适当的设备,并将位移入或者移出设备寄存器。
或者设备控制器支持内存映射I/O。在这种情况下,设备控制寄存器被映射到处理器的地址空间,处理器执行I/O 请求是通过标准数据传输指令读写映射到物理内存的设备控制器。

I/O端口通常由四个寄存器组成, 即状态,控制,数据输入,数据输出寄存器。
数据输入寄存器: 被主机读出以便获取数据。
数据输出寄存器:被主机写入以发送数据。
状态寄存器:包含一些主机可以读取的位,例如当前命令是否完成,数据输入寄存器是否有数据可读,是否出现设备故障等。
控制寄存器: 主机写入,以便启动命令或者改变设备模式。

轮询

主机与控制器之间交互的完整协议可以很复杂,但基本的握手概念是比较简单的。握手概念可以通过例子来解释。
假设采用2个位协调控制器和主机之间的生产者和消费者关系,控制器通过状态寄存器的忙来显示状态。控制器工作忙时就置忙, 而可以接收下个命令时就清忙位。主机通过命令 寄存器的 命令就绪位来表示意愿。当主机有命令需要控制器执行时,命令就绪位被置为1。

当主机需要通过端口来输出数据时,主机与控制器之间的握手的协调如下:

  1. 主机重复读取忙位,直到该位清零。
  2. 主机设置命令寄存的写位,并写出一个字节到数据输出寄存器。
  3. 主机设置命令就绪位。
  4. 当主控器注意到命令就绪位被设置,则设置忙位。
  5. 控制器读取命令寄存器,并看到写命令。它从数据输出寄存器中读取一个字节,并向设备执行I/O操作。
  6. 控制器清除命令就绪位,清除状态寄存器的故障位表示设备I/O成功,清除忙位表示完成。
    对于每个字节重复这个循环。在步骤1 中,主机处于忙等待,或者轮询。

中断

基本的中断机制的工作原理是:CPU 硬件有一条线,称为 中断请求线(IRL)。CPU 在执行完每条指令的后,都会检查是否有中断请求,当CPU检测到控制器已在IRL上发出了一个信号时,CPU执行状态保留并且跳到内存固定位置的中断处理程序中。 中断处理程序确定中断原因,并执行必要处理,执行状态恢复。并且返回中断指令以便CPU 回到中断前的位置继续执行。

设备控制器通过中断请求线发送信号引起中断,CPU捕获中断,并分派到中断处理程序,中断处理程序通过处理设备来清除中断。

直接内存访问(DMA)

对于执行大量传输的设备,例如磁盘驱动器,如果通过昂贵的CPU来按字节的方式发送数据到控制寄存器,则会增加CPU的负担。所以为了避免这种情况,将这一部分任务交给一个专用的处理器(DMA控制器)。
在启动DMA 传输时,主机将DMA 命令块写到内存。该块包含传输来源地址,目标地址和传输的字节数。 CPU将这个命令块写入DMA控制器后,继续工作。 DMA 再继续直接操作内存总线,将地址放到总线,在没有主CPU的帮助下,进行传输。

DMA控制器与设备控制器之间的握手,通过 一组对称的 DMA 请求和DMA确认来完成的。当有数据需要传输时,设备控制器发送信号到 DMA 请求线路。这个信号使得DMA控制器占用内存总线,发送所需地址到内存地址总线,并发送信号到DMA确认线路。当设备控制器收到DMA确认信号时,他就传输数据到内存,并且清除DMA 请求信号。
当DMA 控制器占用内存总线时,CPU被暂时阻止访问总线,但是仍然可以返回主缓存。虽然这种周期窃取 会减慢CPU的计算,但是将数据传输给工作交给DMA控制器通常能够改进总的系统性能。

DMA数据传输.png

应用程序I/O接口

内核I:O子系统结构.png

在操作系统对I/O设备封装的时候,因为各个设备的不同,所以会形成上面的那个I/O结构。接下面主要说明一些不同的设备的处理方法。

块与字符设备

块设备接口为磁盘驱动器和其他基于块设备的访问。它提供了read(), write(), seek()等接口屏蔽了 底层设备的差异。
键盘是字符流设备的。通常使用get() 和put() 接口来进行封装。其他设备还有键盘,鼠标,modem。

网络设备

因为网络I/O的性能和寻址的特点不同于磁盘I/O,大多数操作系统提供的网络I/O接口不同于 read()-write()-seek()操作。 许多系统都使用socket接口。
为了支持实现服务器,套接字还支持了select()函数。调用select可以得知,那个套接字已经有消息接收和处理。

时钟与计时器

大多数计算机都有硬件时钟来定时器。以便实现三种功能

  1. 获取当前时间
  2. 获取经过时间
  3. 设置定时器,以便在T时出发操作X
    测量经过的时间和触发操作的硬件称为可编程间隔定时器。他可以设置一段时间,然后触发中断;调度程序采用这种机制产生中断,以便抢占时间片用完的进程。
    I/O系统使用这种机制,定期刷新脏的缓存到磁盘,网络子系统中,定时取消由于网络拥塞或者故障而产生的太慢的操作。

非阻塞I/O与异步I/O

系统调用接口的另一方面设计选择阻塞I/O 和非阻塞I/O。当应用程序执行阻塞系统调用时,应用程序的执行就被挂起。应用程序会从操作系统的运行队列移到等待队列。等待系统调用完成后,再回到运行队列。
有些用户级进程需要使用非阻塞I/O。比如,一个用户接口,用来接收键盘和鼠标的输入,同时处理数据并显示到屏幕。
针对非阻塞系统,系统一般提供了异步系统调用。异步调用立即返回,无需等待I/O完成。应用程序继续执行代码,等将来I/O 完成了,通过设置应用程序地址空间的某个变量,或通过触发信号或软件中断,或者执行回调函数,来通知应用程序。

内核I/O子系统

内核提供与I/O相关的许多服务。包括调度,缓冲,假脱机,设备预留及错误处理。

I/O调度

调度一组I/O请求意味着,确定好顺序,来执行它们。应用程序执行系统调用的顺序很少是最佳的。

操作系统开发人员通过为每个设备维护一个请求等待队列,来实现队列。当应用程序发出阻塞I/O的系统调用时,该请求被添加到相应的设备的队列。I/O调度程序重新安排队列顺序。以便提高总的效率和应用程序平均的响应时间。之前就有提到过磁盘的调度算法。

当内核支持异步I/O时,它必须能够同时跟踪许多I/O请求。为此,操作系统可能会将等待附加到设备状态表中。内核管理此表,其中每个条目对应每个I/O 设备。每个表条目表明设备的类型, 地址和状态。如果设备忙于一个请求,则请求的类型和其他参数都被保存在该设备的表条目中。

设备状态表.png

缓冲

调度I/O操作是I/O子系统提高计算机效率的一种方法。另外一种方法是通过缓冲,缓存和假脱机,使用内存或磁盘的存储空间。

缓冲区是一块内存区域,用于保存在两个设备之间或者设备和应用程序之间传输的数据。采用缓冲有三个理由:

  1. 处理数据流的生产者和消费者之间的速度不匹配。例子:通过调制解调器接收一个文件,并保存在硬盘。调制解调器的速度比硬盘慢1000倍。这样创建一个缓冲区在内存中,以便累积从调制解调器出接受的字节。当整个缓冲区填满时,就可以通过一次磁盘操作写入磁盘。
  2. 调节传输代销不一致的设备。这种不一致在计算机网络中特别常见,缓冲区大量用于消息的分段和重组。在发送端,一个大的消息分成若干个小的网络分组。这些网络分组通过网络传输,而接收端将他们放在重组缓冲区内,以便完成的源数据进行重组映射。
  3. 支持应用程序I/O的复制语义。假设应用程序有一个数据缓冲区,它希望写到磁盘。它调用系统调用write,提供缓冲区的指针和表示所写字节数量的整数。在系统调用返回后,如果应用程序更改缓冲区的内容,那么会发生什么?采用复制语义,写到磁盘的的数据版本保证是系统调用时的版本,而与应用程序缓冲区的任何后续操作无关。
    系统调用write 返回到应用程序之前,复制应用程序缓冲区到系统内核缓冲区。磁盘写入通过内核缓冲区来执行。以便应用程序缓冲区的后续更改没有影响。

缓存

缓冲和缓存的区别是: 缓冲可以保存数据项的唯一现有版本。而缓存只是提供了一个位于其他地方的数据项的更快存储版本。

缓存和缓冲的功能不同,但是有时一个内存区域可以用于两个目的。
如为了保留复制语义和有效地调度磁盘I/O。 操作系统采用内存中缓冲区来保存磁盘数据。这些缓冲区也用作缓存,以便提高文件的I/O效率。这些文件可被多个程序共享,或者更快速的写入和重读。
当内核收到文件I/O请求时,内核首先访问缓冲区缓存。以便查看文件区域是否已经在内存中可用。

假脱机和设备预留

假脱机是保存设备输出的缓冲区,这些设备,如打印机,不能接受交叉的数据流。虽然打印机只能一次打印一个任务,但是多个应用程序可能希望并发打印输出,而不能让他们的输出混合在一起。操作系统拦截所有的打印数据。来解决这个问题。
应用程序的输出先是假脱机到一个单独的磁盘文件。当应用程序完成打印后,假脱机系统排序相应的假脱机文件。以便输出到打印机。

内核数据结构

内核需要保存I/O组件的使用的状态信息。它通过各种内核数据结构来完成。内核使用许多类似的结构来跟踪网络连接,字符设备和其他的I/O操作。
Unix提供了各种实体的文件系统访问,如用户文件,原始设备和进程的地址空间。虽然这些实体都支持read 操作, 但是语义不同。当读取用户文件时,内核首先需要检查缓冲区缓存,然后决定是否执行磁盘I/O。 当读取原始磁盘时,内核需要确保,请求大小是 磁盘扇区大小的倍数而且与扇区边界对齐。 当读取进程映像时, 内核秩序从内存读取数据。


unix I:O内核结构.png

I/O请求转换硬件操作

操作系统如何将应用程序请求连到网络线路或者特定的磁盘扇区。
从磁盘文件读文件。应用程序通过文件名称引用数据。对于磁盘,文件系统通过文件目录对文件名进行映射,从而得到文件的空间分配。
但是如何建立文件名称到磁盘控制器的连接?
MS-DOS 文件名称的第一部分, 在冒号之前表示特定硬件设备的字符串。 C: 是主硬盘的每个文件名称的第一部分。 C: 通过设备表映射到特定的端口地址。由于冒号分隔符,设备名称空间不同于文件系统的名称空间。
Unix 通过常规文件系统的名称空间来表示设备名称。与具有冒号分隔符的MS-DOS系统不用, Unix没有 路径 没有明确的设备部分。为了解析路径,Unix 检查安装表内的名称,以查找最长的匹配前缀;安装表的相应条目给出了设备名称。

你可能感兴趣的:(《操作系统概念精要》之I/O系统)