I/O设备技术呈现两个相矛盾的趋势
1、 硬件与软件接口的日益增长的标准化
2 、I/O设备日益增长的多样性
为了隐藏不同设备的细节与特点,操作系统内核设计成使用设备驱动程序模块的结构。
设备驱动程序为I/O子系统提供了统一接口,正如系统调用为应用程序与操作系统之间提供了统一的标准接口。
设备与计算机通信有一个连接点(或端口),例如:串行端口。
如果一个或多个设备使用一组共同的线,那么这种连接则称为总线。
总线是一组线和一组严格定义的可以描述在线上传输信息的协议。
I/O端口通常有四种寄存器:状态、控制、数据输入、数据输出
1、 状态寄存器包含一些主机可读取的位信息,这些位信息指示各种状态如当前任务是否完成,数据输入寄存器中是否有数据可以读取,是否出现设备故障等
2、 控制寄存器可以被主机用来向设备发送命令或改变设备状态。例如,串口控制寄存器中的一位选择全工通信或单工通信,另一位控制是否奇偶校验检查。
3 、数据输入寄存器被主机读取数据
4 、数据输出寄存器被主机写入数据以发送数据
当主机需要通过端口来写出数据时,主机与控制器之间握手协调如下:
1 、主机不断地读取忙位,直到该位被清除
2 、主机设置命令寄存器中的写位并向数据输出寄存器中写入一个字节
3 、主机设置命令就绪位
4 、当控制器注意到命令就绪位已被设置,则设置忙位
5、 控制器读取命令寄存器,并看到写入命令,它从数据输出寄存器中读取一字节,并向设备执行I/O操作
6、 控制器清除命令就绪位,清除状态寄存器的故障位以表示设备I/O成功,清除忙位以表示完成。
能使外设通知CPU的硬件机制称为中断。
让设备准备好时再通知处理器,这样的效率会更高,这种外设通知CPU的硬件机制称为中断(interrupt)。
设备控制器通过中断请求线发送信号引起(raise)中断,CPU 捕获中断并分发到中断处理程序中,中断处理程序通过处理设备请求来清除中断。
进入中断前,CPU保存当前状态;完成中断后,CPU执行中断返回指令以便使CPU返回中断以前的执行状态。
绝大多数CPU有两个中断请求线:
中断机制接受一个地址,以用来从一小集合内选择特定的中断处理程序。对绝大多数体系结构,这个地址是一个称为中断向量(interrupt vector)的表中偏移量。该向量包含了特殊中断处理程序的内存地址。
中断机制也实现了中断优先级(interrupt priority),该中断机制能使CPU延迟处理低优先级中断而不屏蔽所有中断,也可以让高优先级中断抢占低优先级中断处理。
对于需要做大量传输的设备,例如磁盘,耗费CPU来观察寄存器太浪费,通常将任务下方给专用处理器,称之为直接内存访问(DMA)控制器。
CPU向内存写入数据,然后就继续忙别的,DMA控制器接手进行数据传输,完成以后中断通知CPU。
IO应用接口使得IO设备可以按统一的标准方式来对待。
具体来说,从不同的IO设备中抽象出通用类型,每个通用类型都可以通过一组标准函数(即接口)来访问。具体的差别被**内核模块(设备驱动程序)**所封装。
设备驱动程序层的作用就是为内核IO子系统隐藏设备控制器之间的差异。
设备在许多方面都有很大差异:
对应用程序而言,设备的许多差别都被操作系统所隐藏,设备可以分为几种类型:块与字符设备,网络设备,时钟与定时器等。
块设备接口规定了访问磁盘驱动器和其他基于块设备所需要的各个方面。通常设备有read()、write()、seek()命令
操作系统本身和特殊应用程序(如数据库管理系统)可能更加倾向于将块设备当做一个简单的线性块数组来访问。这种访问方式有时称为原始IO。
内存映射文件访问是建立在块设备驱动程序之上的。内存映射接口并不提供read和write操作,而是通过内存中的字节数组来访问磁盘存储。
因为传输采用了与按需分页虚拟内存访问相同的机制,所以内存映射IO比较高效。
当应用程序发出阻塞系统调用时,应用程序的执行被挂起,应用程序将会从操作系统的运行队列移到等待队列上去。在系统调用完成后,应用程序就移回到运行队列,并在合适的时候继续执行并能收到系统调用返回的值。
但阻塞系统调用显然不能满足所有的需要,有的用户级进程需要使用非阻塞IO,如接受键盘和鼠标输入的同时处理在屏幕上显示数据。
非阻塞IO的实现方式之一是通过编写多线程应用程序。有的线程执行阻塞系统调用,而其他线程继续执行。
一个非阻塞调用在程序执行过长时间时并不中止应用程序,它会很快返回,其返回值表示已经传输了多少字节。
非阻塞与异步系统调用的差别是非阻塞read()调用会马上返回任何可用的数据,其所读的数据可以等于或少于所要求的,或为0。异步read()调用所要求的传输应该完整的执行,但其具体执行可以是将来某个特定时间。
内核中许多与IO有关的服务是由内核IO子系统提供的,并建立在硬件和设备驱动程序结构之上。IO子系统还负责保护自己免受错误进程和恶意用户的危害。
IO调度就是确定一个合适的顺序来执行IO请求。通过调度来改善性能。
IO子系统改善计算机效率的方法之一就是IO操作调度,另外一种方法是使用主存或磁盘上的存储空间技术,如缓冲、高速缓存、假脱机等。
缓冲区是用来保存两个设备之间或设备和应用程序之间所传输数据的内存区域。
这样做有三个理由:
高速缓存是可以保留数据副本的高速存储器。
高速缓存副本的访问要比原始数据访问更高效。
假脱机(Spooling)是用来保存设备输出的缓冲区,这些设备(如打印机)不能接受交叉的数据流。
当应用程序完成打印时,假脱机系统将对相应的待送打印机的假脱机文件进行排队。
采用内存保护的操作系统可以预防许多硬件和应用程序的错误,这样就不会因为小的机械失灵导致系统崩溃。
IO系统调用通常返回一个位来表示调用状态信息,以表示成功或失败。
为了防止用户执行非法IO,定义所有IO指令为特权指令
用户不能直接发出IO指令,只能通过操作系统来进行。
另外,所有内存映射和IO端口内存位置都受到内存保护系统的保护,以阻止用户访问。
内核需要保存IO组件使用的状态信息,可以通过若干内核数据结构如文件打开表等来完成。
UNIX提供对若干实体,如用户文件、原设备和进程地址空间的文件系统访问。
现代计算机每秒能处理数千个中断
改善I/O效率,可以采用一些原则:
1 、减少关联切换的次数
2 、减少设备和应用程序之间传递数据时在内存中的数据拷贝次数
3、 通过使用大传输、智能控制器及轮流检测,来减少中断频率
4 、通过采用DMA智能控制器和通道来为主CPU承担简单数据拷贝,以增加并发
5、 将处理原语移入硬件,允许控制器内的操作与CPU和总线内的操作并发
6 、平衡CPU、内存子系统、总线和I/O的性能,这是因为任何一处的过载都会引起其他部分空闲