KEY:功能 逻辑分层 功能分步 系统
I/O子系统可能是操作系统设计最麻烦的部分了。因为硬件设备和应用都是多种多样的,很难为其设计一套通用和统一的解决方案。本部分按照由一般到特殊的顺序讲述I/O子系统相关的内容。
I/O设备分类方式有很多种,其中一种是分成以下三大类:人可读设备、机器可读设备和通信设备。
这三类设备不仅在各大类之间设备差异性很大,同一类内的各种设备的差异也是很大的(所以这种分类对是I/O系统的设计显然是初步的),它们之间的差异关键点如下:
无论是从操作系统角度还是从用户进程的角度看,为如此多样化的设备设计一套统一的I/O系统都是很困难的。
计算机技术日新月异,计算机系统及各独立组件的演变表现出一定的模式。I/O功能的演变最明显。下面是I/O功能演变过程的概况:
下图展示了DMA最一般的逻辑构成。与CPU一样,DMA也是计算机的逻辑单元(部件),负责接替CPU完成部分系统功能——控制系统总线并进行内存数据传送。通常,DMA模块必须只在CPU不需要使用总线时工作,或者强迫CPU临时挂起操作后工作。后者被称为周期窃取或周期挪用。
DMA技术工作过程是这样的。当CPU要读或写一块数据时,它向DMA模块发出一条命令,内容如下:
当完整的下达DMA命令后,CPU继续自己的工作,与DMA控制器这个特殊的处理器并行工作。DMA控制器负责传送大块数据(一次一字)进出内存,无须CPU干涉。当传输完成后,DMA会发送一个中断信号给CPU表示完成;因此在数据传输的全程中,CPU只涉及传输开始和结束处理。
下图展示了CPU在指令周期何处被挂起。CPU在试图使用被DMA占用的总线时被挂起。DMA然后在传输完一个字后把控制权交还给CPU。注间这个过程并不是中断,CPU并不保持上下文信息或做其它动作,CPU只是被暂停了一个总线周期。整体效果是感觉CPU运行慢了(KEMIN:因为是共用总线,多少要有点代价)。虽然如此,在传输大块数据的情况时,DMA还是要比中断方式或编程I/O有效得多。
DMA机制可以按需要配置(configured)成各种不同的模式。下图展示了几种可能的模式。在第一种模式中,计算机的所有模块共享单一的总线。DMA模块扮演着代理(surrogate)的角色,负责使用编程I/O的方式交换内存和I/O模块间的数据。这种配置模式显然是很经济的,效率低下也是很明显的。因为使用编程I/O的方式,每传输一个字都消耗两个总线周期。
提高效率的通用手法是把通用的东西改为专用的。所以通过给I/O模块集成DMA可以大大的降低传输所需的总线周期。如图中的第二种配置模式,DMA模块与一个或几个I/O模块之间有单独的非系统总线通路(path)。DMA逻辑上是I/O模块的一部分,或者是独立的模块,但是负责控制部分I/O模块。这个思想可以往前推进一步,把所有I/O模块用单独的I/O总线链接到DMA模块,看第三种配置模式。通过共用I/O总线,把连接DMA的接口降低到一个,这样提供一种极易扩展的配置方式(KEMIN:看原文,具体如何配置没讲)。在后两种配置模式里,DMA与CPU、内存共用的系统总线只用于传送从CPU到DMA的控制信号和DMA与内存间数据信息,DMA和I/O模块间的数据传输完全被移离系统总线。
I/O系统设计有两个至高(paramount)的目标:效率(efficiency)和通用性(generality)。效率的重要性体现在I/O操作已经成为目前计算机性能的第一大瓶颈。
由本文第一张图可见,输入输出设备的速度远远慢于内存和处理器。解决办法之一就是引入多道程序,使得一些进程等待IO操作时,另一些进程可以继续执行。虽然现今的机器内存已经相当的大了,但是I/O操作常常还是跟不上处理器。而为了让处理器操持忙碌,引入对换(swapping)机制把额外就绪的进程从磁盘调入内存执行,可是这个动作本身就是I/O操作。所以I/O系统设计主要目标是试图提高效率。由于磁盘I/O的重要性,这方面也是受到最多的关注,本章主要研究磁盘I/O的效率。
另一个主要目标是通用性。为了追求简单性和降低输入输入出的错误,人们想使用一致的方式处理输入输入出。包括面向用户进程的接口和操作系统的管理接口。因为设备的差异性(diversity),实践中上很难做到真正的一致。实际上能做到的是利用分层的模块化的方法设计I/O功能(function)。这种方法把设备I/O操作的细节隐藏入一些低级别的例程中,而用户进程和高一级的操作系统把设备看成一系列通用功能,如read,write,open,close,lock,unlock。
在讨论系统结构的时候,我们看到了现代操作系统是分层结构的。分层的指导原则是,操作系统各层必须根据功能复杂度、时间量程(time scale)特性和抽象级别进行分隔。分层思想把操作系统分成数层,每一层负责实现操作系统功能的一个子集(KEMIN:如果是分层的话,这个功能子集不应该是横向,而应该是纵向的,不是吗?如果回答是肯定,那不能叫子集,叫某一个功能的某一步,是么?)。高一层的功能的实现有赖于低一层提供的原始操作原始功能,而这一层本身对这些原始的操作进行包装提供给更高一层的功能的实现。在理想的情况下,各层通过接口互操作,一层的修改都不影响另一层。分层思想使我们可以把复杂的大问题分解成多个可管理的小问题。
通常,层次更低的操作工作在更短的时间量程(time scale)内。比如,操作系统的一些部分是直接与硬件交互的,而这些交互操作的时间量程一般在十亿分之一秒;而交互的另一端,操作系统与用户交互则在数秒之内。这种情况是使用分层思想的理想之地。
分层思想应用于I/O系统时有如下图的分层结构。结构的具体详细可能会因不同的设备和应用而有所不同。图中展示的是最重要的三种逻辑分层结构:本地外围设备、通信端口和文件系统。
我们来分析最简单的I/O例子——通过字符流或记录流通信的本地外围设备:
逻辑I/O层:顾名思义,本层提供的I/O是逻辑的(包括逻辑资源和逻辑操作),是对具体的I/O数据和控制进行包装,为用户进行提供简易接口,比如设备标识和设备操作命令open,close,read,write等。
设备I/O层:来自逻辑层的数据(缓冲的字符和记录)和操作请求会在本层被转译成相应的I/O指令序列、通道命令(channel commands)和控制器命令(controller orders)。缓冲技术会在本层实现,用来提高性能。
调度与控制层(scheduling and control):操作系统对I/O操作的排队与调度发生在本层,也包括对操作的控制。因此,中断处理和I/O状态报告也发生在本层。本层是软件层中最底的一层,是与硬件进行实际交互的一层。
在通信设备的例子中,分层结构与外围设备很类似,只是逻辑I/O被替换成通信架构(communications architecture)。通信架构本身也由一系列逻辑层组成,比如我们熟知的七层的开放系统互联结构(OSI)。
在文件系统的例子中,有三层是以上两个例子的分层结构所没有的,它们是:
目录管理层:在这一层中,文件名符号被转换为一个标识,这标识通过一个文件描述符或索引表直接或间接地引用一个文件。本层也会处理面向用户的一些文件目录操作,比如添加、删除和重组。
文件系统层:本层处理文件的逻辑结构和面向用户的一些文件操作,像open, close, read, write。文件访问权限管理也在这一层实现。
物理组织层:就像虚拟内存地址通过分段和分页结构转为物理内存地址一样,对文件或记录的逻辑引用也必须通过文件的物理轨道和扇区结构转换为外存的物理地址。外存空间管理以及外存缓冲管理功能也在这一层实现。