(1) 按照用户的请求,控制设备的各种操作,完成I/O 设备与内存之间的数据交换,最终完成用户的I/O 请求
设备分配与回收
记录设备的状态
根据用户的请求和设备的类型,采用一定的分配算法,选择一条数据通路
执行设备驱动程序,实现真正的I/O 操作
设备中断处理:处理外部设备的中断
缓冲区管理:管理I/O
(2) 建立方便、统一的独立于设备的接口
方便性:向用户提供使用外部设备的方便接口,使用户编程时不考虑设备的复杂物理特性
统一性:对不同的设备采取统一的操作方式 ,即在 用户程序中使用的是逻辑设备
逻辑 设备与物理 设备
屏蔽 硬件细节(设备的 物理特性、错误处理、不同I/O过程的 差异性)
通用性
种类繁多、结构各异
→ 设计简单、避免错误
→ 采用统一的方式处理所有设备
(3) 充分利用各种技术(通道,中断,缓冲,异步I/O等)提高CPU 与设备、设备与设备之间的并行工作能力,充分利用资源,提高资源利用率
并行性
均衡性(使设备充分忙碌)
(4) 保护
设备传送或管理的数据应该是安全的、不被破坏的、保密的
3、I/O设备组成I/O 设备一般由机械和电子两部分组成:
机械部分是设备本身(物理装置)
电子部分又称设备控制器( 或适配器)
(端口)地址译码
按照主机与设备之间约定的格式和过程接受计算机发来的数据和控制信号 或 向主机发送数据和状态信号
将计算机的数字信号转换成机械部分能识别的模拟信号,或反之
实现设备内部硬件缓冲、数据加工等提高性能或增强功能
操作系统将命令写入控制器的接口寄存器(或接口缓冲区)中,以实现输入/输出,并从接口寄存器读取状态信息或结果信息
当控制器接受一条命令后,可 独立于CPU 完成指定操作,CPU 可以另外执行其他计算;命令完成时,控制器产生一个中断,CPU 响应中断,控制转给操作系统;通过读控制器寄存器中的信息,获得操作结果和设备状态
控制器与设备之间的接口常常是一个低级接口
控制器的任务:把串行的位流转换为字节块,并进行必要的错误修正: 首先,控制器按位进行组装,然后存入控制器内部的缓冲区中形成以字节为单位的块;在对块验证检查和并证明无错误时,再将它复制到内存中
I/O 端口地址:接口电路中每个寄存器具有的、唯一的地址,是个整数
所有I/O 端口地址形成I/O 端口空间( 受到保护)
- 分配给系统中所有端口的地址空间与内存的地址空间统一编址
- 把I/O 端口看作一个存储单元,对I/O 的读写操作等同于对内存的操作
- 优点
- 凡是可对内存操作的指令都可对I/O 端口操作
- 不需要专门的I/O 指令
- I/O 端口可占有较大的地址空间
- 缺点
- 占用内存空间
不 需要特殊的保护机制来阻止用户进程执行I/O 操作操作系统必须要做的事情 : 避免把包含控制寄存器的那部分地址空间放入任何用户的虚拟地址空间之中
可以引用内存的每一条指令也可以引用控制寄存器
例如,如果指令TEST 可以测试一个内存字是否为0 ,那么它也可以用来测试一个控制寄存器是否为0
对一个设备控制寄存器 不能 进行高速缓存
考虑 以下 汇编代码循环 , 第一次引用PORT_4 将导致它被高速缓存,随后的引用将只从高速缓存中取值并且不会再查询设备 , 之后当设备最终变为就绪时,软件将没有办法发现这一点 , 结果循环将永远进行下去
为避免这一情形,硬件必须针对每个页面具备选择 性 禁用高速缓存的能力 , 操作系统必须管理选择性高速缓存,所以这一特性为硬件和操作系统两者增添了额外的复杂性
LOOP :TEST PORT-4 // 检测端口4 是否为0
BEQ READY // 如果为0 ,转向READY
BRANCH LOOP // 否则,继续测试
READY
10、I/O软件设计
分层的设计思想
- 把I/O 软件组织成多个层次
- 每一层都执行操作系统所需要的功能的一个相关子集,它依赖于更低一层所执行的更原始的功能,从而可以隐藏这些功能的细节 ; 同时,它又给高一层提供服务
- 较低层考虑硬件的特性,并向较高层软件提供接口
- 较高层不依赖于硬件,并向用户提供一个友好的、清晰的、简单的、功能更强的接口
用户编写的程序可以访问任意I/O 设备,无需事先指定设备
从用户角度: 用户在编制程序时,使用逻辑设备名,由系统实现从逻辑设备到物理设备(实际设备)的 转换,并实施I/O 操作
从系统角度: 设计并实现I/O 软件时, 除了直接与设备打交道的低层软件之外,其他部分的软件不赖于硬件
好处:
设备分配时的灵活性
易于实现I/O
12、引入缓存技术解决什么问题?操作系统中最早引入的技术
解决CPU 与I/O 设备之间速度的不匹配问题
凡是数据到达和离去速度不匹配的地方均可采用缓冲技术
提高CPU 与I/O 设备之间的并行性
减少了I/O 设备对CPU 的中断请求次数,放宽CPU
采用缓冲池技术,可平滑和加快信息在内存和磁盘之间的传输
缓冲区结合 提前读和延迟写 技术对具有 重复性及阵发性I/O 进程、提高I/O 速度很有帮助
可以充分利用之前从磁盘读入、虽已传入用户区但仍在缓冲区的数据 ( 尽可能减少磁盘I/O 的次数,提高系统运行的速度)
缓冲池:200 个缓冲区(512 字节或1024 字节)
每个缓冲区由两部分组成:缓冲控制块或缓冲首部 + 缓冲数据区
系统通过缓冲控制块来实现对缓冲区的管理
空闲缓冲区队列(av 链)
队列 头部为bfreelist
设备缓冲队列(b 链)
链接 所有分配给各类设备使用的缓冲区,按照散列方式组织
buf 用b 双向链,可以有64 个队列,每个队列首部有头标设备为b_dev上的逻辑块b 在散列队列的 头标为:i=(b_dev + b) mod 64
每个缓冲区同时在av 链和b 链:
开始:在空闲av 链( 缓冲区未被使用时)
开始IO 请求:在设备IO 请求队列和设备b 链
IO 完成:在空闲av 链和设备b
当进程想从指定的盘块读取数据时,系统根据盘块号从设备b 链( 散列队列) 中查找,如找到缓冲区,则将该缓冲区状态标记为“忙”,并从空闲av 队列中取下,并完成从缓冲区到内存用户区的数据传送
如果在设备b 链中未找到时,则从空闲av 链队首摘取一个缓冲区,插入设备I/O 请求队列;并从原设备b 链中取下,插入由读入信息盘块号确定的新的设备b 链中
当数据从磁盘块读入到缓冲区后,缓冲区从设备I/O 请求队列取下;当系统完成从缓冲区到内存用户区的数据传送后,要把缓冲区释放,链入空闲av 链队尾
当数据从磁盘块读入到缓冲区,并传送到内存用户区后,该缓冲区一直保留在原设备b 链中,即它的数据一直有效。若又要使用它,则从空闲av 链中取下,使用完后插入到空闲av 链队尾。若一直未使用它,则该缓冲区从空闲av 链队尾慢慢升到队首,最后被重新分配,旧的盘块数据才被置换
系统对缓冲区的分配是采用近似LRU 算法
本文整理自:《操作系统原理》北京大学_陈向群 讲义
个人微信公众号:
作者:jiankunking 出处:http://blog.csdn.net/jiankunking