目录
IO设备的概念
含义:I/O就是输入/输出(input/output);IO设备就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部分。
注意:
- UNIX系统会将外部设备抽象为一种特殊的文件,用户可以使用与文件操作相同的方式对外部设备进行操作
- write操作:向外部设备写出数据
- read操作:从外部设备读入数据
IO设备的分类
按照使用特性分类
- 人机交互类外部设备:经常用于和计算机进行交互的设备(数据传输速度慢)——鼠标、键盘
- 存储设备:用于数据存储的设备(数据传输速度快)——移动硬盘、光盘
- 通络通信设备:用于网络通信的设备(数据传输速度介于两者之间)——调制解调器
按照传输速度来分类
- 低速设备
- 中速设备
- 高速设备
按照信息交换的单位分类
- 块设备:数据传输的基本单位是“块”,其传输速率较高,可寻址,即对它可随机的读/写任意一块——磁盘
- 字符设备:数据传输的基本单位是字符,传输速率较慢,不可寻址,在输入/输出时常采用中断驱动的方式——鼠标、键盘
IO控制器
IO设备的组成
- 机械部件:主要用于执行具体的IO操作,如我们看得见摸得着的鼠标、键盘按钮(显示器的LED屏,移动硬盘的磁臂,磁盘盘面)
- 电子部件:通常是一块插入主板扩充槽的印刷电路板(IO控制器、设备控制器)
注意:当我们这些IO设备连上电脑之后,CPU是无法直接控制IO设备的机械部件,它必须通过电子部件(IO控制器又称设备控制器)来间接的控制机械部件。
IO控制器的功能
- 接收和识别CPU发来的命令:如CPU发来的read/write命令,IO控制器中会有相应的控制寄存器用来存放命令和参数
- 向CPU报告设备的状态:IO控制器中会有相应的状态寄存器,用于记录IO设备的当前状态。如:1表示空闲,0表示忙碌
- 数据交换:IO控制器中会设置相应的数据寄存器。输出时数据寄存器用于暂存CPU发来的数据,之后再由控制器传送设备。输入时,数据寄存器用于暂存设备发来的数据,之后CPU从数据寄存器中取走数据
- 地址识别:类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的地址。IO控制器通过CPU提供的地址来判断CPU要读/写的是那个寄存器
IO控制器的组成
- CPU与控制器的接口:用于实现CPU与控制器之间的通信,CPU通过控制线发出命令;通过地址线来指明要操作的设备;通过数据线来取出输入数据或放入输出数据
- IO逻辑:负责接收和识别CPU的各种命令(如地址译码)并负责对设备发出命令
- 控制器与设备的接口:用于实现控制器与设备之间的通信
具体流程
- CPU会通过控制线向IO逻辑发送一个具体的IO指令,同时CPU还会在地址线这个线路上说明自己要操作的是那个设备,此时CPU想要输出设备,CPU会通过数据总线,把自己要输出的数据放到IO控制器的数据寄存器中,之后IO逻辑就可以从数据寄存器中取得CPU想要输出的数据,CPU发送的IO指令可能会有一些参数,这些参数会被放到控制寄存器中,IO逻辑就可以从控制寄存器中得到相应的参数了;为了实现对各个数据之间的管理,那么CPU还会从状态寄存器中读出各个设备之间的状态(忙碌,空闲,故障等)IO逻辑会往状态寄存器中写入相应的数据来告诉CPU各个设备的状态;
- IO逻辑从数据寄存器中取出CPU输出的数据,从控制寄存器中取出控制参数,将这些数据输出到对应地址的控制器设备接口,同时设备还要及时的向IO控制器内的IO逻辑反馈自己的状态,以供CPU了解
注意:
- 一个IO控制器有可能会负责控制多个具体的IO设备,为了区别CPU要操作的是那个设备,因此需要给设备接口一个地址编号
- CPU与控制器的接口中有控制寄存器、状态寄存器、数据寄存器;并且这些寄存器可能有多个(每个控制/状态寄存器对应一个具体的设备),这些寄存器都要有相应的地址,才能方便CPU操作。有的计算机会让这些寄存器占用内存地址的一部分,称为内存映像IO;另一些计算机则采用IO专用地址,即寄存器独立编址
内存映像IO与寄存器独立编址
- 内存映像IO:控制器中的寄存器与内存地址统一编址(简化了指令,可以采用对内存进行操作的指令来对控制器进行操作)
- 寄存器独立编址:控制器中的寄存器使用单独的地址(需要设置专门的指令来实现对控制器的操作,不仅要指明寄存器的地址,还需要指明控制器的编号)
IO控制方式
程序直接控制方式
读操作:CPU通过控制线向IO控制器的IO逻辑发送一条读指令同时CPU还会在地址线这个线路上说明自己要操作的是那个设备,于是设备启动,并且状态寄存器设为1(未就绪),于是设备就开始准备计算机想要读入的数据,但是设备的速度比CPU的速度慢很多,所以在设备还没有完成IO前CPU会不断地轮询检查控制器状态,状态一直为1的话就说明设备在忙碌还没有准备号数据,若输入设备准备好数据后,那么就会将数据通过IO逻辑传给数据寄存器,并且通过IO逻辑报告自己的状态为已就绪到状态寄存器;CPU轮询到设备的状态为已就绪,CPU就可以从数据寄存器中读取到相应的数据(CPU会先将数据寄存器中的数据读入到自己的寄存器中,再把CPU寄存器中的内容放到内存)
中断驱动方式
前言:引入了中断机制,由于IO设备速度很慢,因此在CPU发出读/写命令后,可以将IO的进程阻塞,先切换到别的进程执行。当IO完成后,控制器会向CPU发送一个中断信号,CPU检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断。中断处理的过程中,CPU从IO控制器读一个字的数据传送到CPU寄存器,再写入主存。接着CPU恢复等待IO的进程或其他进程的运行环境,然后继续执行
注意:
- CPU会在每个指令周期的末尾检查中断
- 中断处理过程中需要保存、恢复进程的运行环境,这个过程是需要一定的时间开销。可见,若中断发生的频率太高,也会影响系统性能
DMA方式
前言:与中断驱动方式相比,DMA(直接存储器存取。主要用于块设备的IO控制)有这样几个改进
- 数据传送的单位是块,不再是一个字一个字的传送;
- 数据的流向是从设备直接流向内存,或者从内存直接到设备,不再需要CPU进行中转
- 仅在传送一个或多个数据块的开始和结束时才需要CPU干预
DMA控制器
- DR(data register,数据寄存器):暂存从设备到内存,或从内存到设备的数据
- MAR(memory address,内存地址寄存器):在输入时,MAR表示数据应放到内存的什么位置;输出时MAR表示要输出的数据要放在内存的什么位置
- DC(data counter,数据计数器):表示剩余要读写的字节数
- CR(command register,命令/状态寄存器):用于存放CPU发来的IO命令,或设备的状态信息
注意:
- 系统总线会把DMA控制器和内存连接起来,所以DMA控制器和内存之间可以直接进行数据的读写
- DMA控制器并不是每次直接读入一整块的数据,直接把一整块放到内存中;其实DMA控制器在读入数据中也是一个字一个字的读入,每次读入的一个字都会先放到DR中,再从DR写入到内存中
通道控制方式
前言:所谓的通道其实就是一种硬件,可以理解为弱鸡版CPU。通道可以识别并执行一系列通道指令
通道的工作原理
- CPU、内存、通道通过系统总线连接在一起,首先CPU会向通道发出IO指令。并且指明此次要执行的通道程序通道指令的序列存放在内存的什么位置,并指明要操作的时那个IO设备,之后CPU就可以切换到其他进程运行了
- 通道会根据CPU的指示去找到此次要执行的通道程序(任务清单)存放在内存中的什么位置,并执行通道程序(其中指明了要读入/写出多少数据。读写的数据应放在内存的什么位置等信息)
- 通道执行完规定的任务后,向CPU发出中断信号,之后CPU对中断进行处理
注意:通道可以识别并执行一系列的通道指令,但是与CPU相比,通道可以执行的指令很单一,并且通道程序是放在主机内存中的,也就是说通道与CPU共享内存
总结
IO软件的层次结构
注意:
- 在这些层次结构中,越靠近上层,越接近用户,越靠近下层,越接近硬件
- 各个层次都会使用它们下面一层软件所提供的功能,并且向他上层的软件提供一些服务
- 每一层会利用其下层提供的服务,实现某些功能,并屏蔽实现具体细节,向高层提供服务(封装思想)
- 当用户发起IO请求的时候,这个IO请求会从上至下经过各个层次进行处理,最后被扔给IO硬件来执行实际的IO操作,当IO硬件做完这些IO操作发出IO应答时就会由这些层次从下往上依次进行处理最后返回给用户
用户层软件
理解:用户层软件实现了与用户交互的接口,用户可直接使用该层提供的,与IO操作相关的库函数对设备进行操作。
注意:
- 用户层软件将用户的请求翻译成格式化的IO请求,并通过系统调用请求操作系统内核的服务
- windows操作系统向外提供一系列的系统调用,但是由于系统调用的格式严格,使用麻烦,因此在用户层上封装了一系列更方便的库函数接口供用户使用(windows API)
设备独立性软件
含义:设备独立性软件,又称设备无关性软件。与设备的硬件特性无关的功能几乎都在这一层实现
实现的功能
- 向上层提供统一的调用接口(如read/write等系统调用)
- 对设备的保护(原理类似于文件保护。设备被看作一种特殊的文件,不同用户对各个文件的访问权限是不一样的,同理,对设备的访问权限也不一样)
- 差错处理(设备独立性软件需要对一些设备的错误进行处理)
- 对设备的分配与回收
- 数据缓冲区的管理(可以通过缓冲区技术屏蔽设备之间数据交换单位大小和传输速度的差异)
- 建立逻辑设备名到物理设备名的映射关系;根据设备类型选择调用相应的驱动程序(用户或用户层软件发出IO操作相关系统调用的系统调用时,需要指明此次要操作的IO设备的逻辑设备名)
逻辑设备表
注意:
- 设备独立软件需要通过逻辑设备表(LUC)来确定逻辑设备对应的物理设备,并找到该设备对应的设备驱动程序
- IO设备被当做一种特殊的文件
- 不同类型的IO程序需要有不同的驱动程序处理
操作系统管理逻辑设备表方式
- 整个系统只设置一张LUT,这就意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用单用户操作系统
- 为每个用户设置一张LUC,各个用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而LUC久存放在用户管理进程的PCB中
设备驱动程序
前言:设备驱动程序主要负责对硬件设备的具体控制,将上层发出的一些列命令(如read/write)转化成特定设备能听得懂的一系列操作。包括设置设备寄存器,检查设备状态等
注意:驱动程序一般会以一个独立进程的方式存在
中断处理程序
前言:当IO任务完成时,IO控制器会发送一个中断信号,系统会根据中断信号的类型找到相应的中断处理程序并执行。
中断处理程序的流程
硬件
前言:不同的IO设备具有不同的硬件特性,具体的细节只有设备的厂家才知道.因此厂家需要根据设备的硬件特性设计并提供相应的硬件驱动程序
作用:执行IO操作,由机械部件和电子部件组成
IO的核心子系统
前言:设备独立性软件,设备驱动程序,中断处理程序属于操作系统内核部分,即IO系统或IO核心子系统
注意:假脱机技术(SPOOLing技术)需要请求磁盘设备的设备独立性软件的服务,因此一般来说假脱机技术是用户层软件实现的。但是408大纲又将假脱机技术归为IO核心子系统的功能。
假脱机技术
脱机技术
脱机:脱离主机的控制来进行输入/输出的操作。
注意:引入脱机技术后,缓解了CPU与慢速的IO设备的速度矛盾。换言之,即使CPU再忙碌,也可以提前将需要运算的数据输入到磁带中,即使输出设备再忙碌,也可以先将数据输出到磁带
假脱机技术诞生
前言:基于脱机技术的思想,人们又研究了假脱机技术,又称SPOOLing技术,其是用软件的方式模拟脱机技术
注意:
- 系统会在磁盘上开辟出两个存储区——输入井和输出井
- 输入井模拟脱机输入时的磁带,用于收容IO设备输入的数据
- 输出井模拟脱机输出时的磁带,用于收容用户进程输出的数据
- 输入进程用来模拟脱机输入时的外围控制机,输出进程模拟脱机输出时的外围控制机
- 要实现SPOOLing技术,必须有多道程序技术的支持
- 输入缓冲区和输出缓冲区主要作为模拟脱机技术时作为数据的中转站
共享打印机原理分析
独占设备与共享设备
- 独占式设备:只允许各个进程串行使用的设备。一段时间内只能满足一个进程的请求
- 共享设备:允许多个进程同时使用的设备(宏观上同时使用,微观上可能是交替使用)可以同时满足多个进程的使用请求
前言:打印机是独占式设备(若进程1正在使用打印机,则进程2请求使用打印机时必然导致阻塞),但是可以用SPOOLing技术将其改变为共享设备
当多个用户进程提出输出打印请求时,系统会答应他们的请求,但并不是真正的把打印机分配给他们,而是由假脱机管理进程为每个进程做以下处理
- 在磁盘输出井中为进程申请一个空闲缓冲区(也就是说,这个缓冲区是在磁盘上的)并将要打印的数据送入其中
- 为用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中(其实就是用来说明用户的打印数据存放位置等信息)再将该表挂到假脱机文件队列上
- 当打印机空闲时,输出进程会从文件队列的队头取出一张打印请求表,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印。用这种方式可依次处理完全部的打印任务
总结:SPOOLing技术可以把一台物理设备虚拟成逻辑上的多台设备,可将独占式设备改造成共享设备
IO调度
含义:用某种算法确定一个好的顺序来处理各个IO请求
如磁盘调度(先来先服务算法、最短寻道优先算法、SCAN算法、C-SCAN算法、LOOK算法、C-LOOK算法)当多个磁盘IO请求到来时,用某种调度算法确定满足IO请求的顺序;同理,打印机等设备也可以用先来先服务算法、优先级算法、短作业优先算法等确定IO调度的顺序
设备保护
- 操作系统需要实现文件保护的功能,不同的用户对于各个文件有不同的访问权限(如:只读、读和写等)
- 在unix系统中,设备被看作是一种特殊的文件,每个设备也会有相应的FCB。当用户请求访问某个设备时,系统根据FCB中记录的信息来判断该用户是否有相应的访问权限,以此实现设备保护的功能
设备的分配与回收
设备分配时要考虑的因素
- 设备的固有属性
- 设备的分配算法
- 设备分配中的安全性
设备的固有属性
- 独占设备:一个时间段内只能分配给1个进程(如打印机)
- 共享设备:可同时分配给多个进程使用(如磁盘)各个进程往往宏观上同时共享使用设备,而微观上是交替使用
- 虚拟设备:采用SPOOLing技术将独占式设备改造成虚拟的共享设备,可同时分配给多个进程使用(如采用SPOOLIng技术实现的共享打印机)
设备的分配算法
- 先来先服务
- 优先级高者优先
- 短任务优先
设备分配的安全性
安全分配方式
含义:为进程分配一个设备后就将进程阻塞,本次IO完成后才将进程唤醒(一个时间段内仅能使用一个设备)
优缺点
- 优点:破坏了请求和保持条件,不会死锁
- 缺点:对于一个进程来说,CPU和IO设备只能串行的工作
不安全分配方式
含义:进程发出IO请求后,系统为其分配IO设备,进程可继续执行,之后还可以发出新的IO请求。只有某个IO请求得不到满足时才将进程阻塞(一个进程可以同时使用多个设备)
优缺点
- 优点:进程的计算任务和IO任务可以并行处理,使进程迅速推进
- 缺点:可能会发生死锁
静态分配和动态分配
- 静态分配:进程运行前就为其分配全部的所需资源,运行结束后归还资源
- 动态分配:进程运行过程中动态申请设备资源
设备分配管理中的数据结构
设备,控制器,通道之间的关系
注意:一个通道可以控制多个设备控制器,每个设备控制器可控制多个设备
设备控制表
前言:系统为每个设备配置一张设备控制表(DCT),用于记录设备情况
控制器控制表
前言:每个设备控制器都会对应一张控制器控制表(COCT)。操作系统根据COCT的信息对控制器进行操作和管理
通道控制表
前言:每个通道都会对应一张通道控制表(CHCT)。操作系统根据CHCT的信息对通道进行操纵和管理
系统设备表
前言:系统设备表(SDT)记录了系统中全部设备的情况,每个设备对应一个表目
设备的分配步骤
注意:只有设备、控制器、通道三者都分配成功时,这次设备分配才算成功,之后便可启动IO设备进行数据传输
缺点:
- 用户编程时必须使用物理设备名,底层细节对用户不透明,不方便编程
- 若换一个物理设备,则程序无法运行
- 若进程请求的物理设备正在忙碌,则即使系统中还有同类型的设备,进程也必须阻塞等待
设备分配步骤的改进
前言:由于原始设备分配步骤的缺点,所以可以建立逻辑设备名与物理设备名的映射机制,用户编程时只需提供逻辑设备名
逻辑设备表(LUC)
前言:逻辑设备表建立了逻辑设备名和物理设备名的映射关系
注意:
- 某用户进程第一次使用设备时使用逻辑设备名向操作系统发出请求,操作系统根据用户进程指定的设备类型(逻辑设备名)查找系统设备表,找到一个空闲设备分配给进程,并在LUC中增加相应的表项
- 若之后用户进程再次通过相同的逻辑设备名请求使用设备,则操作系统通过LUC表即可知道用户进程实际要使用的是那个物理设备了,并且也能知道该设备驱动程序入口地址
逻辑设备表的设置问题
- 整个系统只有一张LUC:各个用户所用的逻辑设备名不允许重复,适用于单用户操作系统
- 每个用户一张LUC:不同用户的逻辑设备名可以重复,适用于多用户操作系统
缓冲区管理
何谓缓冲区
含义:缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可以利用内存作为缓冲区
注意:
- 使用硬件作为缓冲区的成本较高,容量也比较小,一般仅用在对速度要求非常高的场合(如存储器管理中所用的联想寄存器,由于对页表的访问频率极高,因此使用速度很快的联想寄存器来存放页表项的副本)
- 一般情况下,更多的是利用内存作为缓冲区,设备独立性软件的缓冲区管理就是要组织管理好这些缓冲区
缓冲区的作用
单缓冲
前言:假设某用户进程请求某种块设备读入若干块的数据,若采用单缓冲的策略,操作系统会在主存中为其分配一个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一个块)
注意:
- 当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出;
- 当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区充满以后才能从缓冲区把数据传出
单缓冲的使用
理解:首先,系统在主存中为该用户进程分配了一块大小的缓冲区,那么块设备会产生一块大小的数据将其输入到缓冲区中;缓冲区充满后,里面的数据需要传送到用户进程工作区中才可以被用户进程所处理;之后用户进程就可以通过CPU对该块数据进行处理;当处理完后,用户进程的工作区就会被腾空。
双缓冲
前言:假设某用户进程请求某种块设备读入若干块的数据,若采用双缓冲策略,操作系统会在主存中为其分配两个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一块)
使用单/双缓冲在通信时的区别
前言:两台机器之间通信时,可以配置缓冲区用于数据的发送和接收
注意:
- 若两台相互通信的机器只设置单缓冲区,在任一时刻只能实现数据的单向传输
- 若两个相互通信的机器设置双缓冲区,则同一时刻可以实现双向数据传输
- 管道通信中的管道其实就是缓冲区。要实现数据的双向传输,必须设置两个管道
循环缓冲区
前言:很多时候只有2个缓冲区依然不能满足进程的实际需要,所以操作系统可以给进程分配多个大小相等的缓冲区,让这个缓冲区连成一个循环的队列,这就是循环缓冲区
注意:
- 上图中,橙色表示已经充满数据的缓冲区,绿色表示空缓冲区
- 系统会保持两个指针用于缓冲区的管理
缓冲池
前言:缓冲池由系统中共用的缓冲区组成。这些缓冲区按照使用状况可以分为:空缓冲队列、装满输入数据的缓冲队列(输入队列)、装满输出数据的缓冲队列(输出队列)
简单理解:放满了各种各样缓冲区的一个池子,当我们需要使用一个缓冲区或者归还一个缓冲区的时候,就可以对这个池子中的各种缓冲区进行操作
另外,根据一个缓冲区在实际运算中扮演的功能不同,又设置了4种缓冲区:用于收容输入数据的工作缓冲区(hin)、用于提取输入数据的工作缓冲区(sin)、用以收容输出数据的工作缓冲区(hout)、用于提取输出数据的工作缓冲区(sout)
缓冲池的具体使用
- 输入进程请求输入数据:系统会从空缓冲队列的队头中取下一块空的缓冲区,把他作为hin,当该缓冲区被充满后便会被挂到输入队列的队尾
- 计算进程想要取得一块输入数据:操作系统会从输入队列的队头取下一块缓冲区,将其作为sin,这块缓冲区的数据会被传送到计算进程的工作区当中,所以这块缓冲区的数据被取空进而放到空缓冲区的队尾
- 计算进程将已经准备好数据冲入缓冲区:操作系统会从空缓冲队列的队头取下一个空闲的缓冲区,将该缓冲区作为hout,因此该缓冲区会被充满,进而放到输出缓冲区队尾
- 输出进程请求输出数据:系统会从输出队列的队头取下一块缓冲区,将其作为sout,接下来该缓冲区内的数据会被取空,进而被挂到空闲缓冲区队尾