上一节我们学习的内容是I/O系统的特点和设备分类和差异,这一节我们将主要关注I/O控制方式、OS设计问题、I/O逻辑结构等。
I/O功能的演变
在专栏的ch1-2中,我们详细讲解了CPU与外设的三种交互方式,这里简单地带过。
(1)轮询的方式,一般I/O操作CPU是空闲的,且都要经过CPU数据中转到内存
(2)中断的方式,一般是CPU在等待I/O操作完成的同时可以执行其他任务
(3)磁盘一般都是DMA(挪用总线周期,无需CPU高速传输),键盘一般是中断驱动的
一开始I/O功能直接由处理器直接控制,处理器来调度和操作外设
后来添加了控制器和I/O模块,使用类似于“轮询”的方式与外设进行交互,这样I/O设备就由自身的控制器控制,处理器不需要直接处理。
然后,控制器开始支持中断的方式,处理器就不需要每次“轮询”等待I/O操作,但是处理器仍然要执行中断处理程序,参与数据移动。
接着,出现了更高级的DMA方式,数据块通过总线直接进入内存,处理器不需要参与数据移动,大大加快了数据传输速率。
为了使CPU从I/O事务中解脱出来,提高CPU与设备,设备与设备之间的并行工作能力,OS又引入了通道。通道是独立于CPU的专门负责数据输入/输出传输工作的处理机,可以执行通道程序。
通道相当于一个功能简单的处理机,包含通道指令(空操作,读操作,写操作,控制,转移操作),并可执行用这些指令编写的通道程序。因此可以进行较为复杂的I/O控制,通道程序通常由操作系统所构造,放在内存里,执行一个通道程序可以完成多批I/O操作。
I/O设计目标和问题
设计目标:高效率+通用性
- 高效率:最重要的是提高I/O自身的性能,其次可以使用类似于文件系统多级划分来提高
- 通用性
- 为了简单性避免出错,应以统一方式处理所有I/O设备
- 将设备I/O的大部分细节隐藏在底层例程中(read, write, open, close, lock and unlock等),底层例程主要是各种初始化,比如设备的初始以及寄存器的初始化
I/O软件需要考虑的问题
- 设备无关性:
- 逻辑设备(将设备视为文件),OS将逻辑设备进行转换完成对实际物理设备的驱动,比如键盘是0号文件、显示器是1号文件、错误信息是2号文件
- 物理设备:键鼠、显示器等不同种类的外设
- 出错处理:只能报告错误,不能解决问题
- 同步:阻塞需要I/O的进程,通过异步传输(中断驱动)
- 缓冲技术:硬盘的读写一次需要ms级别的传输
I/O的逻辑结构
分层管理:每一层功能向下依赖,向上提供服务
- Logic I/O:针对用户接口提供抽象命令:open、write等
- Device I/O:逻辑设备与物理设备间的过度协调机构
- 用户请求的I/O序列
- I/O缓冲区
- Scheduling and Control:物理设备控制实体,往往是设备驱动程序
e.g., 抽象结构图示
事实上,分层并没有唯一的标准,不同的OS有自己的架构。