47 KiB
设备管理
I/O概述
I/O设备基本概念
I/O设备定义
- “$I/O$”就是“输入/输出”($Input/Output$)。$I/O$设备就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部件。
- $UNIX$系统将外部设备抽象为一种特殊的文件,用户可以使用与文件操作相同的方式对外部设备进行操作。
- 计算机系统为每台设备确定一个编号以便区分和识别设备,这个确定的编号称为设备的绝对号。
I/O设备分类
- 按使用特性分类:
- 人机交互类外部设备:数据传输速度慢,如鼠标、键盘。
- 存储设备:数据传输速度块,如移动硬盘。
- 网络通信设备:数据传输速度介于二者之间,如调制解调器。
- 按传输速率分类:
- 低速设备:鼠标、键盘。
- 中速设备:打印机。
- 高速设备:硬盘。
- 按信息交换的单位分类:
- 块设备:有结构设备,传输速率较高,可寻址,即对它可随机地读/写任一块,如硬盘、磁盘。
- 字符设备:无结构设备,传输速率较慢,不可寻址,在输入/输出时常采用中断驱动方式,键盘、鼠标。
I/O控制器
- $I/O$设备由机械部件和电子部件($I/O$控制器或设备控制器)组成。
- 通过$I/O$逻辑实现设备控制。
- $I/O$设备的机械部件主要用来执行具体$I/O$操作。如鼠标/键盘的按钮,显示器的$LED$屏,移动硬盘的磁臂、磁盘盘面。
- $I/O$设备的电子部件通常是一块插入主板扩充槽的印刷电路板。
- $CPU$无法直接控制$I/O$设备的机械部件,因此$I/O$设备还要有一个电子部件作为$CPU$和$I/O$设备机械部件之间的“中介”,用于实现$CPU$对设备的控制。
I/O控制器功能
- 接受和识别$CPU$发出的命令:如$CPU$发来的$Read/Write$命令,$I/O$控制器中会有相应的控制寄存器来存放命令和参数。
- 向$CPU$报告设备的状态:$I/O$控制器中会有相应的状态寄存器,用于记录$I/O$设备的当前状态。如$1$表示空闲,$0$表示忙碌。
- 数据交换:$I/O$控制器中会设置相应的数据寄存器。输出时,数据寄存器用于暂存$CPU$发来的数据,之后再由控制器传送设备。输入时,数据寄存器用于暂存设备发来的数据,之后$CPU$从数据寄存器中取走数据。
- 地址识别:类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的“地址”。$I/O$控制器通过$CPU$提供的“地址”来判断$CPU$要读/写的是哪个寄存器。
I/O接口
负责与$CPU$和设备进行通信:
- $CPU$与控制器的接口:用于实现$CPU$与控制器之间的通信。$CPU$通过控制线发出命令,通过地址线指明要操作的设备,通过数据线来取出(输入)数据,或放入(输出)数据。
- $I/O$逻辑:负责接收和识别$CPU$的各种命令(如地址译码),并负责对设备发出命令。
- 控制器与设备的接口:用于实现控制器与设备之间的通信,包括数据、状态和控制。
- 一个$I/O$控制器可能会对应多个设备。
I/O端口
- 数据寄存器。
- 控制寄存器。
- 状态寄存器:可能有多个(如每个控制/状态寄存器对应一个具体的设备),且这些寄存器都要有相应的地址,才能方便$CPU$操作。
实现$CPU$与$I/O$端口通信,使用不同编址方式:
- 统一编址:有的计算机会让这些寄存器占用内存地址的一部分,称为内存映像$I/O$,优点是简化了指令。可以采用对内存进行操作的指令来对控制器进行操作。
- 独立编址:另一些计算机则采用$I/O$专用地址,即寄存器独立编址,缺点是需要设置专门的指令来实现对控制器的操作,不仅要指明寄存器的地址,还要指明控制器的编号。
I/O控制方式
用于控制主存和外设之间的输入输出控制方式。
程序直接控制方式
- 完成读写的流程:
- $CPU$向控制器发出读指令。于是设备启动,并且状态寄存器设为$1$(未就绪)。
- 轮询检查控制器的状态,其实就是在不断地执行程序的循环,若状态位一直是$1$,说明设备还没准备好要输入的数据,于是$CPU$会不断地轮询。
- 输入设备准备好数据后将数据传给控制器,并报告自身状态。
- 控制器将输入的数据放到数据寄存器中,并将状态改为$0$(已就绪)。
- $CPU$发现程序已就绪,即可将数据寄存器中的内容读入$CPU$的寄存器中,再把$CPU$寄存器中的内容放入内存。
- 若还要继续读入数据,则$CPU$继续发出读指令。
- $CPU$干预的频率:很频繁,$I/O$操作开始之前、完成之后需要$CPU$介入,并且在等待$I/O$完成的过程中$CPU$需要不断地轮询检查。
- 数据传送的单位:每次读/写一个字。
- 数据的流向:
- 读操作(数据输入): $I/O$设备→$CPU$→内存(指的是$CPU$的寄存器)。
- 写操作(数据输出):内存→$CPU$→$I/O$设备。
- 每个字的读/写都需要$CPU$的帮助。
- 主要缺点和主要优点:
- 优点:实现简单,在读/写指令之后,加上实现循环检查的一系列指令即可,因此才称为“程序直接控制方式”。
- 缺点:
- $CPU$和$I/O$设备只能串行工作。
- $CPU$需要一直轮询检查,长期处于“忙等”状态,$CPU$利用率低。
中断驱动方式
- 引入中断机制。由于$I/O$设备速度很慢,因此在$CPU$发出读/写命令后,可将等待$I/O$的进程阻塞,先切换到别的进程执行。当$I/O$完成后,控制器会向$CPU$发出一个中断信号,$CPU$检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断。处理中断的过程中,$CPU$从$I/O$控制器读一个字的数据传送到$CPU$寄存器,再写入主存。接着,$CPU$恢复等待$I/O$的进程(或其他进程)的运行环境,然后继续执行。
- $CPU$会在每个指令周期的末尾检查中断。
- 中断处理过程中需要保存、恢复进程的运行环境,这个过程是需要一定时间开销的。可见,如果中断发生的频率太高,也会降低系统性能。
- $CPU$干预的频率:每次$I/O$操作开始之前、完成之后需要$CPU$介入。等待$I/O$完成的过程中$CPU$可以切换到别的进程执行。
- 数据传送的单位:每次读/写一个字。
- 数据的流向:
- 读操作(数据输入): $I/O$设备→$CPU$→内存(指的是$CPU$的寄存器)。
- 写操作(数据输出):内存→$CPU$→$I/O$设备。
- 主要缺点和主要优点:
- 优点:
- 与“程序直接控制方式”相比,在“中断驱动方式”中,$I/O$控制器会通过中断信号主动报告$I/O$已完成,$CPU$不再需要不停地轮询。
- $CPU$和$I/O$设备可并行工作,$CPU$利用率得到明显提升。
- 缺点:
- 每个字在$I/O$设备与内存之间的传输,都需要经过$CPU$。
- 频繁的中断处理会消耗较多的$CPU$时间。
- 优点:
DMA方式
- 即直接存储器存取方式,主要用于块设备的$I/O$控制。
- 改进方面:
- 数据的传送单位是“块”。不再是一个字、一个字的传送。
- 数据的流向是从$I/O$设备直接放入内存,或者从内存直接到设备。不再需要$CPU$中转。
- 仅在传送一个或多个数据块的开始和结束时,才需要$CPU$干预。
- 完成读写的流程:
- $CPU$向$I/O$模块发出读或写块的命令。$CPU$指明此次要进行的操作,如读操作说明要读入多少数据、数据要存放在内存的什么位置、数据在外部设备上的地址。
- $CPU$转向其他工作,$DMA$控制器根据$CPU$所给参数完成工作。
- 完成工作后$DMA$控制器向$CPU$发送一个中断信号。$CPU$处理中断。
- $DMA$控制器结构:与$I/O$控制器结构类似:
- 主机控制器接口:
- $DR$($Data,Register$,数据寄存器):暂存从设备到内存,或从内存到设备的数据。
- $MAR$($Memory,Address,Register$,内存地址寄存器):在输入时,$MAR$表示数据应放到内存中的什么位置,输出时$MAR$表示要输出的数据放在内存中的什么位置。
- $DC$($Data,Counter$,数据计数器):表示剩余要读/写的字节数。
- $CR$($Command,Register$,命令/状态寄存器):用于存放$CPU$发来的$I/O$命令,或设备的状态信息。
- $I/O$控制逻辑:用于实现设备控制。
- 块设备控制器接口。
- 主机控制器接口:
- $CPU$干预的频率:仅在传送一个或多个数据块的开始和结束时,才需要$CPU$干预。
- 数据传送的单位:每次读/写一个或多个块(注意每次读写的只能是连续的多个块,且这些块读入内存后在内存中也必须是连续的)。
- 数据的流向(不再需要经过$CPU$):
- 读操作(数据输入):$I/O$设备→内存。
- 写操作(数据输出):内存→$I/O$设备。
- 主要缺点和主要优点:
- 优点:
- 数据传输以“块”为单位,$CPU$介入频率进一步降低。
- 数据的传输不再需要先经过$CPU$再写入内存,数据传输效率进一步增加。
- $CPU$和$I/O$设备的并行性得到提升。
- 缺点:
- $CPU$每发出一条$I/O$指令,只能读/写一个或多个连续的数据块。
- 如果要读/写多个离散存储的数据块,或者要将数据分别写到不同的内存区域时,$CPU$要分别发出多条$I/O$指令,进行多次中断处理才能完成。
- 优点:
$DMA$的控制器与$CPU$分时使用内存,通常采用以下三种方法:停止$CPU$访内存、周期挪用、$DMA$与$CPU$交替访内存。(计算机组成原理会具体讲到)
- 数据块传送方式:在$I/O$接口电路中设置一个比较大的数据缓冲区,一般能存放一个数据块,$I/O$接口电路与内存之间的数据交换以数据块为单位。总线仲裁器判定究竟是$DMA$控制器还是$CPU$能获得总线的使用权。
- 周期挪用方式:当$I/O$接口没有$DMA$请求时,$CPU$按程序要求访问内存;一旦$I/O$接口有$DMA$请求,则$I/O$接口挪用一个或几个周期。缺点是:数据输入或输出过程中实际占用了$CPU$时间。
- 交替访存方式:$CPU$与$DMA$控制器交替访问内存。不需要总线使用权的申请、建立和归还过程。 效率高,但实现起来有困难,基本上不被使用。
通道控制方式
- 通道:一种硬件,可以理解为是简版的$CPU$,因为与$CPU$相比,通道可以执行的指令很单一,并且通道程序是放在主机内存中的,也就是说通道与$CPU$共享内存。
- 通道可以识别并执行一系列通道指令。
- 通道控制设备控制器、设备控制器控制设备工作。
- 字节多路通道:用于连接大量低俗或中速设备。它通常含有许多非分配型子通道,其数量可达几十到几百个,每个通道连接一台$I/O$设备,并控制该设备的$I/O$操作。这些子通道按时间片轮转方式共享主通道。各个通道循环使用主通道,各个通道每次完成其$I/O$设备的一个字节的交换,然后让出主通道的使用权。这样,只要字节多路通道扫描每个子通道的速率足够快,而连接到子通道上的设备的速率不太高时,便不至于丢失信息。
- 完成读写的流程:
- $CPU$向通道发出$I/O$指令。指明通道程序在内存中的位置,并指明要操作的是哪个$I/O$设备。之后$CPU$就切换到其他进程执行。启动时无论成功与否都需要回答$CPU$。
- 通道执行内存中的通道程序(其中指明了要读入/写出多少数据,读/写的数据应放在内存的什么位置等信息),类似任务清单。
- 通道执行完规定的任务后,此时向$CPU$发出中断信号,之后$CPU$对中断进行处理。
- $CPU$干预的频率:极低,通道会根据$CPU$的指示执行相应的通道程序,只有完成一组数据块的读/写后才需要发出中断信号,请求$CPU$干预。
- 数据传送的单位:每次读/写一组数据块。
- 数据的流向((在通道的控制下进行):
- 读操作(数据输入): $I/O$设备→内存。
- 写操作(数据输出):内存→$I/O$设备。
- 主要缺点和主要优点:
- 优点:$CPU$、通道、$I/O$设备可并行工作,资源利用率很高。
- 缺点:实现复杂,需要专门的通道硬件支持。
方式区别
$DMA$方式与中断控制方式的区别:
- 中断控制方式在每个数据传送完成后中断$CPU$,而$DMA$控制方式则在所要求传送的一批数据全部传送结束时中断$CPU$。
- 中断控制方式的数据传送在中断处理时由$CPU$控制完成,而$DMA$控制方式则在$DMA$控制器的控制下完成。不过,在$DMA$控制方式中,数据传送的方向、存放数据的内存始址及传送数据的长度等仍然由
CPU控制。 - $DMA$方式以存储器为核心,中断控制方式以$CPU$为核心。因此$DMA$方式能与$CPU$并行工作。$DMA$方式传输批量的数据,中断控制方式的传输则以字节为单位。
$DMA$方式与通道方式的区别:
- 在$DMA$控制方式中,在$DMA$控制器控制下设备和主存之间可以成批地进行数据交换而不用$CPU$干预,这样既减轻了$CPU$的负担,又大大提高了$I/O$数据传送的速度。
- 通道控制方式与$DMA$控制方式类似,也是一种以内存为中心实现设备与内存直接交换数据的控制方式。
- 不过在通道控制方式中,$CPU$只需发出启动指令,指出通道相应的操作和$I/O$设备,该指令就可以启动通道并使通道从内存中调出相应的通道程序执行。
- 与$DMA$控制方式相比,通道控制方式所需的$CPU$干预更少,并且一个通道可以控制多台设备,进一步减轻了$CPU$的负担。
- 另外,对通道来说,可以使用一些指令灵活改变通道程序,这一点$DMA$控制方式无法做到。
I/O软件层次结构
$I/O$软件结构层次:
- 中断处理程序。
- 设备驱动程序。
- 设备独立性软件。
- 用户层软件。
每一层会利用其下层提供的服务,实现某些功能,并屏蔽实现的具体细节,向高层提供服务(“封装思想”)。
其中中断处理程序、设备驱动程序、设备独立性软件属于操作系统的内核部分,即$I/O$系统或$I/O$核心子系统,需要使用核心态进行运行,而用户层软件用户态就可以运行。
用户层软件
- 用户层软件实现了与用户交互的接口,用户可直接使用该层提供的、与$I/O$操作相关的库函数对设备进行操作。
- 用户层软件将用户请求翻译成格式化的$I/O$请求,并通过“系统调用”请求操作系统内核的服务。
设备独立性软件
- 设备独立性软件,又称设备无关性软件。与设备的硬件特性无关的功能几乎都在这一层实现。
- 主要实现的功能:
- 向上层提供统一的调用接口(如$Read/Write$系统调用)。
- 设备保护。原理类似与文件保护。设备被看做是一种特殊的文件,不同用户对各个文件的访问权限是不一样的,同理,对设备的访问权限也不一样。
- 差错处理。
- 设备的分配与回收。
- 数据缓冲区管理。可以通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异。
- 建立逻辑设备名到物理设备名的映射关系,根据设备类型选择调用相应的驱动程序。(逻辑设备名)
- 用户或用户层软件发出$I/O$操作相关系统调用的系统调用时,需要指明此次要操作的$I/O$设备的逻辑设备名(如去学校打印店打印时,需要选择扣印机$1$/打印机$2$/打印机$3$,其实这些都是逻辑设备名)。
- 设备独立性软件需要通过“逻辑设备表”($LUT$,$Logical,UnitTable$)来确定逻辑设备对应的物理设备,并找到该设备对应的设备驱动程序。
- 操作系统系统可以采用两种方式管理逻辑设备表($LUT$):
- 整个系统只设置一张$LUT$,这就意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用于单用户操作系统。
- 为每个用户设置一张$LUT$,各个用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而$LUT$就存放在用户管理进程的$PCB$中。
设备驱动程序
- 主要负责对硬件设备的具体控制,将上层发出的一系列命令(如$Read/Write$)转化成特定设备“能听得懂”的一系列操作。包括设置设备寄存器、检查设备状态等。
- 不同的$I/O$设备有不同的硬件特性,具体细节只有设备的厂家才知道,因此厂家需要根据设备的硬件特性设计并提供相应的驱动程序。
- 驱动程序一般会以一个独立进程的方式存在。
中断处理程序
- 当$I/O$任务完成时,$I/O$控制器会发送一个中断信号,系统会根据中断信号类型找到相应的中断处理程序并执行。中断处理程序的处理流程如下:
- 从控制器读出设备状态。
- 如果正常结束则从设备中读入一个字的数据并由$CPU$放入内存缓冲区中。交给上一层处理。
- 如果异常结束则根据异常原语进行处理。
应用程序I/O接口
即$I/O$系统与高层软件之间的接口
- 字符设备接口。
- 块设备接口。
- 网络设备接口。
- 阻塞或非阻塞$I/O$。
I/O核心子系统
I/O核心子系统概述
实现功能:
- 用户层软件:假脱机技术。
- 设备独立性软件:
- $I/O$调度:用某种算法确定一个好的顺序来处理各个$I/O$请求。
- 设备保护:将设备看作文件,具有$FCB$。
- 设备分配与回收。
- 缓冲区管理(即缓冲与高速缓存)。
缓冲区管理
磁盘高速缓存
利用内存中的存储空间暂存从磁盘中读出的一系列盘块中的信息,逻辑上是属于磁盘,物理上驻留在内存中。
分为两种形式:在内存中开辟出一个单独的存储空间作为磁盘高速缓存,大小固定;另一种把未利用的内存空间作为缓冲池,供请求分页系统和磁盘$I/O$时共享。
缓冲区概念
- 缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可利用内存作为缓冲区。
- 使用硬件作为缓冲区的成本较高,容量也较小,一般仅用在对速度要求非常高的场合(如存储器管理中所用的联想寄存器,由于对页表的访问频率极高,因此使用速度很快的联想寄存器来存放页表项的副本)。
- 一般情况下,更多的是利用内存作为缓冲区,“设备独立性软件”的缓冲区管理就是要组织管理好这些缓冲区。
- 缓冲区作用:
- 缓和$CPU$与$I/O$设备之间速度不匹配的矛盾。
- 减少对$CPU$的中断频率,放宽对$CPU$中断相应时间的限制。
- 解决数据粒度不匹配的问题。
- 提高$CPU$与$I/O$设备之间的并行性。
- $T$代表输入时间(把数据传入缓冲区)、$M$代表传输时间(把缓冲区数据传入用户区)、$C$代表处理时间($CPU$对数据进行处理)。
单缓冲
- 假设某用户进程请求某种块设备读入若干块的数据。若采用单缓冲的策略,操作系统会在主存中为其分配一个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一个块)。
- 当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出;当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区充满以后,才能从缓冲区把数据传出。
- 常考题型:计算每处理一块数据平均需要多久?技巧:假定一个初始状态(如工作区满、缓冲区空),分析下次到达相同状态需要多少时间,这就是处理一块数据平均所需时间。
- 处理一块数据平均耗时$\max(C,T)+M$。
双缓冲
- 假设某用户进程请求某种块设备读入若干块的数据。若采用双缓冲的策略,操作系统会在主存中为其分配两个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一个块)。
- 若两个相互通信的机器设置双缓冲区,则同一时刻可以实现双向的数据传输。否则单缓冲区只能单向数据传输。
- 一块存,一块可以取,处理一块数据平均耗时$\max(T,(C+M))$。
循环缓冲
- 将多个大小相等的缓冲区链接成一个循环队列。
- $in$指针,指向下一个可以冲入数据的空缓冲区。
- $out$指针,指向下一个可以取出数据的满缓冲区。
缓冲池
- 缓冲池由系统中共用的缓冲区组成。这些缓冲区按使用状况可以分为:
- 空缓冲队列、
- 装满输入数据的缓冲队列(输入队列)。
- 装满输出数据的缓冲队列(输出队列)。
- 根据一个缓冲区在实际运算中扮演的功能不同,又设置了四种工作缓冲区:
- 用于收容输入数据的工作缓冲区($hin$)。
- 用于提取输入数据的工作缓冲区($sin$)。
- 用于收容输出数据的工作缓冲区($hout$)。
- 用于提取输出数据的工作缓冲区($sout$)。
- 输入进程请求输入数据:从空缓冲队列中取出一块作为收容输入数据的工作缓冲区($hin$)。冲满数据后将缓冲区挂到输入队列队尾。
- 计算进程想要一块输入数据:从输入队列中取得一块冲满输入数据的缓冲区作为提取输入数据的工作缓冲区($cin$)。缓冲区读空后挂到空缓冲区队列。
- 计算进程将准备好的数据冲入缓冲区:从空缓冲队列中取出一块作为收容输出数据的工作缓冲区($hout$)。数据冲满后将缓冲区挂到输出队列队尾。
- 输出进程请求输出数据:从输出队列中取得一块冲满输出数据的缓冲区作为提取输出数据的工作缓冲区($sout$)。缓冲区读空后挂到空缓冲区队列。
| 高速缓存 | 缓冲区 | |
|---|---|---|
| 存放数据 | 存放的是低速设备上的某些数据的复制数据,即高速缓存上有的,低速设备上面必然有 | 存放的是低速设备传递给高速设备的数据(或相反),而这些数据在低速设备(或高速设备)上却不一定有备份,这些数据再从缓冲区传送到高速设备(或低速设备) |
| 目的 | 高速缓存存放的是高速设备经常要访问的数据,若高速设备要访问的数据不在高速缓存中,则高速设备就需要访问低速设备 | 高逑设备和低速设备的通信都要经过缓冲区,高速设备永远不会直接去访问低速设备 |
设备分配回收
设备分配方法:
- 静态分配:主要是独占设备的分配,在用户作业开始前,由系统一次性分配,直到作业完成才会取消占用,不会死锁。
- 动态分配:主要是共享设备的分配,进程执行期间进行,通过系统调用提出设备请求,可能死锁。
- $SPOOLing$技术:主要是虚拟设备的分配,实现了虚拟设备,让设备可同时被分配给多个进程。
或者:
- 独享分配。
- 共享分配。
- 虚拟分配。
设备分配考虑因素
- 固有属性:
- 独占设备:同时只能被一个进程访问。如打印机、磁带机。
- 共享设备:同时能被多个进程访问,不会死锁。如磁盘。可寻址和可随机访问。
- 虚拟设备:将独占设备改造成共享的虚拟设备。
- 分配算法:
- 先请求先分配。
- 优先级高者优先。
- 安全性:
- 安全分配方式:
- 为进程分配一个设备后就将进程阻塞,本次$I/O$完成后才将进程唤醒。一个时段内每个进程只能使用一个设备。
- 优点:破坏了“请求和保持”条件,不会死锁。
- 缺点:对于一个进程来说,$CPU$和$I/O$设备只能串行工作。
- 不安全分配方式:
- 进程发出$I/O$请求后,系统为其分配$I/O$设备,进程可继续执行,之后还可以发出新的$I/O$请求。只有某个$I/O$请求得不到满足时才将进程阻塞。一个进程可以同时使用多个设备。
- 优点:进程的计算任务和$I/O$任务可以并行处理,使进程迅速推进。
- 缺点:有可能发生死锁(死锁避免、死锁的检测和解除)。
- 安全分配方式:
- 独立性。
设备分配数据结构
- 一个通道可控制多个设备控制器,每个设备控制器可控制多个设备。
- 设备控制表($DCT$),系统为每个设备配置一张$DCT$,用于记录设备情况:
- 设备类型:如打印机/扫描仪/键盘。
- 设备标识符:即物理设备名,系统中的每个设备的物理设备名唯一。
- 设备状态:忙碌/空闲/故障……。
- 指向控制器表的指针:每个设备由一个控制器控制,该指针可找到相应控制器的信息。
- 重复执行次数或时间:当重复执行多次$I/O$操作后仍不成功,才认为此次$I/O$失败。
- 设备队列的队首指针:指向正在等待该设备的进程队列(由进程$PCB$组成队列)。
- 控制器控制表($COCT$),每个设备控制器都会对应一张$COCT$。操作系统根据$COCT$的信息对控制器进行操作和管理,$CHCT$和$COCT$是一对多的关系:
- 控制器标识符:各个控制器的唯一$ID$。
- 控制器状态:忙碌/空闲/故障……
- 指向通道表的指针:每个控制器由一个通道控制,该指针可找到相应通道的信息。
- 控制器队列的队首指针:指向正在等待该控制器的进程队列(由进程$PCB$组成队列)。
- 控制器队列的队尾指针:指向控制器的队尾。
- 通道控制表($CHCT$),每个通道都会对应一张$CHCT$。操作系统根据$CHCT$的信息对通道进行操作和管理:
- 通道标识符:各个通道的唯一ID。
- 通道状态:忙碌/空闲/故障……
- 与通道连接的控制器表首址:可通过该指针找到该通道管理的所有控制器相关信息($COCT$)。
- 通道队列的队首指针:指向正在等待该通道的进程队列(由进程$PCB$组成队列)。
- 通道队列的队尾指针:指向通道队列的队尾。
- 系统设备表($SDT$),整个系统只有一张,记录了系统中全部设备的情况,每个设备对应一个表目:
- 设备类型:打印机/扫描仪/键盘。
- 设备标识符:物理设备名。
- $DCT$(设备控制表)。
- 驱动程序入口:对应设备驱动的程序地址。
设备名映射
为了提高分配灵活性,使用了设备独立性,使用逻辑设备名来使用设备。
所以系统中设置了一张逻辑设备表$LUT$。包括设备逻辑名、物理逻辑名、设备驱动程序入口。
有两种方式设置$LUT$:
- 系统只有一张,所以只适合单用户系统。
- 每个用户一张,当用户登录,系统就为用户创建一个进程并建立一张$LUT$并放入$PCB$中。
优点:
- 逻辑设备表($LUT$)建立了逻辑设备名与物理设备名之间的映射关系。
- 某用户进程第一次使用设备时使用逻辑设备名向操作系统发出请求,操作系统根据用户进程指定的设备类型(逻辑设备名)查找系统设备表,找到一个空闲设备分配给进程,并在$LUT$中增加相应表项。
- 如果之后用户进程再次通过相同的逻辑设备名请求使用设备,则操作系统通过$LUT$表即可知道用户进程实际要使用的是哪个物理设备了,并且也能知道该设备的驱动程序入口地址。
设备分配过程
- 根据进程请求的物理设备名查找$SDT$(物理设备名是进程请求分配设备时提供的参数)。
- 根据$SDT$找到$DCT$,若设备忙碌则将进程$PCB$挂到设备等待队列中,不忙碌则将设备分配给进程。
- 根据$DCT$找到$COCT$,若控制器忙碌则将进程$PCB$挂到控制器等待队列中,不忙碌则将控制器分配给进程。
- 根据$COCT$找到$CHCT$,若通道忙碌则将进程$PCB$挂到通道等待队列中,不忙碌则将通道分配给进程。
- 只有设备、控制器、通道三者都分配成功时,这次设备分配才算成功,之后便可后动$I/O$设备进行数据传送。
缺点:
- 用户编程时必须使用“物理设备名”,底层细节对用户不透明,不方便编程。
- 若换了一个物理设备,则程序无法运行。
- 若进程请求的物理设备正在忙碌,则即使系统中还有同类型的设备,进程也必须阻塞等待这个名字设备。
改进方法:建立逻辑设备名与物理设备名的映射机制,用户编程时只需提供逻辑设备名。
- 根据进程请求的逻辑设备名查找$SDT$(用户编程时提供的逻辑设备名其实就是“设备类型”)。
- 查找$SDT$,找到用户进程指定类型的、并且空闲的设备,将其分配给该进程。操作系统在逻辑设备表($LUT$)中新增一个表项。
- 根据$DCT$找到$COCT$,若控制器忙碌则将进程$PCB$挂到控制器等待队列中,不忙碌则将控制器分配给进程。
- 根据$COCT$找到$CHCT$,若通道忙碌则将进程$PCB$挂到通道等待队列中,不忙碌则将通道分配给进程。
假脱机技术
也称为$SPOOLing$技术。
脱机技术
- 脱机处理是一种计算机技术,是指在不受主机控制的外部设备上进行数据处理,或与实时控制系统、主机不直接相连的数据处理。常用于主机速度不高的数据处理中提高设备的利用率。
- 如输入输出设备速度慢,远小于$CPU$处理速率,而$CPU$要处理就必须等待输入输出设备,导致$CPU$资源浪费,而脱机技术能让数据更快进出$CPU$,从而速度加快。
假脱机技术实现
- “假脱机技术”,又称“$SPOOLing$技术”是用软件的方式模拟脱机技术。
- $SPOOLing$系统组成:
- 输入井:在磁盘上,磁盘固定区域,模拟脱机输入时的磁带,用于收容$I/O$设备输入的数据。
- 输出井:在磁盘上,磁盘固定区域,模拟脱机输出时的磁带,用于收容用户进程输出的数据。
- 输入进程:在内存中,模拟脱机输入时的外围控制机。
- 输出进程,在内存中,模拟脱机输出时的外围控制机。
- 输入缓冲区与输出缓冲区:在内存中,用于暂存输入的数据转存到输入井中,或暂存输出的数据转存到输出井中。
- 由预输入程序、井管理程序、缓输出程序管理。
- 用户进程实际分配的是外存区,即虚拟设备。
- 必要条件:
- 大容量、高速度的外存作为输入井和输出井。
- $SPOOLing$软件。
- 由于需要对设备进行虚拟,所以需要独占设备。
共享打印机
打印机是一种独占式设备,而通过假脱机技术变成共享设备。
当多个用户进程提出输出打印的请求时,系统会答应它们的请求,但是并不是真正把打印机分配给他们,而是由假脱机管理进程处理:
- 在磁盘输出井中为进程申请一个空闲缓冲区(也就是说,这个缓冲区是在磁盘上的),并将要打印的数据送入其中。
- 为用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中(其实就是用来说明用户的打印数据存放位置等信息的),再将该表挂到假脱机文件队列(打印任务队列)上。
- 当打印机空闲时,输出进程会从文件队列的队头取出一张打印请求表,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印。用这种方式可依次处理完全部的打印任务。
磁盘系统
磁盘概念
磁盘结构
- 磁盘由空气过滤片、主轴、音圈马达、永磁铁、磁盘、磁头、磁头臂组成。
- 磁盘的表面由一些磁性物质组成,可以用这些磁性物质来记录二进制数据。
- 磁盘由多个盘片构成,盘片保存数据的一面就是盘面。一个盘片有一个或两个盘面。
- 磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道。
- 一个磁道又被划分成一个个扇区,每个扇区就是一个“磁盘块”。各个扇区存放的数据量相同。
- 最内侧磁道上的扇区面积最小,因此数据密度最大。硬盘的存储能力也受限于最内侧的最大记录密度。
- 磁头用于读写盘面数据,需要把磁头移动到想要读/写的扇区所在的磁道。磁盘会转起来,让目标扇区从磁头下面划过,才能完成对扇区的读/写操作。
- 每个盘面对应一个磁头。
- 所以磁头都是链接在一个磁臂上,所有磁头的移动方向都是一致的。
- 所有盘面中相对位置相同的磁道组成柱面。
- 可用(柱面号,盘面号,扇区号)来定位任意一个磁盘块。
- 地址读取方式:
- 根据“柱面号”移动磁臂,让磁头指向指定柱面。
- 激活指定盘面对应的磁头。
- 磁盘旋转的过程中,指定的扇区会从磁头下面划过,这样就完成了对指定扇区的读/写。
- 许多操作系统位改善磁盘访问时间,不以扇区为单位,而是以簇为单位近空间分配。
磁盘类别
磁盘的分类:
- 磁头可以移动的称为活动头磁盘。磁臂可以来回伸缩来带动磁头定位磁道。
- 磁头不可移动的称为固定头磁盘。这种磁盘中每个磁道有一个磁头。
- 盘片可以更换的称为可换盘磁品。
- 盘片不可更换的称为固定盘磁品。
固态硬盘$SSD$基于闪存技术,是一种容量更大的$U$盘。
- 由一个或多个闪存芯片和闪存翻译层构成。
- 一个闪存由$B$块组成,每块由$P$页组成。存取以页为单位,一般每页$512B\sim4KB$,每块$32\sim128$页,每块$16KB\sim512KB$。
- 闪存磨损速度很快,为了弥补寿命缺陷其磨损均衡技术分为两种:
- 动态磨损均衡:自动选择较新块写入。
- 静态磨损均衡:$SSD$自动检测并数据分配。(更好)
磁盘操作时间
基本时间度量
- 寻找时间(寻道时间)$T_s=s+m\times n$:在读/写数据前,将磁头移动到指定磁道所花的时间:
- 启动磁头臂是需要时间的。假设耗时为$s$。
- 移动磁头也是需要时间的。假设磁头匀速移动,每跨越一个磁道耗时为$m$,总共需要跨越$n$条磁道。
- 延迟时间$T_r=\dfrac{1}{2}\times\dfrac{1}{r}=\dfrac{1}{2r}$:通过旋转磁盘,使磁头定位到目标扇区所需要的时间。
- 磁盘转速为$r$(单位:转/秒,或转/分)。
- $\dfrac{1}{r}$就是转一圈需要的时间。
- 找到目标扇区平均需要转半圈,因此再乘以$\dfrac{1}{2}$。
- 传输时间$T_t=\dfrac{b}{rN}$:从磁盘读出或向磁盘写入数据所经历的时间。
- 假设磁盘转速为$r$,此次读/写的字节数为$b$,每个磁道上的字节数为$N$。
- 每个磁道要可存$N$字节的数据,因此$b$字节的数据需要$\dfrac{b}{N}$个磁道才能存储。而读/写一个磁道所需的时间刚好又是转一圈所需要的时间$\dfrac{1}{r}$,$T_t=\dfrac{1}{r}\times\dfrac{b}{N}$。
- 操作时间=寻道时间$T_s$+延迟时间$T_r$+传输时间$T_t$。
- 延迟时间和传输时间都与磁盘转速相关,且为线性相关。而转速是硬件的固有属性,因此操作系统也无法优化延迟时间和传输时间,操作系统只能通过磁盘调度算法优化寻道时间。
优化方法
- 提前读:在读磁盘当前块时,把下一磁盘块也读入内存缓冲区。
- 延迟写:仅在缓冲区首部设置延迟写标志,然后释放此缓冲区并将其链入空闲缓冲区链表的尾部,当其他进程申请到此缓冲区时,才真正把缓冲区信息写入磁盘块。
- 虚拟盘:是指用内存空间去仿真磁盘,又叫$RAM$盘。虚拟盘是一种易失性存储器。虚拟盘常用于存放临时文件。
磁盘调度算法
磁盘调度算法用来优化寻道时间。
假设某磁盘的磁道为$0\sim200$号,磁头的初始位置是$100$号磁道,此时磁头正在往磁道号增大的方向,有多个进程先后陆续地请求访问$55$、$58$、$39$、$18$、$90$、$160$、$150$、$38$、$184$号磁道。
先来先服务算法
- 即$FCFS$算法,根据进程请求访问磁盘的先后顺序进行调度。
- 优点:
- 公平。
- 如果请求访问的磁道比较集中的话,算法性能还算过的去。
- 缺点:如果有大量进程竞争使用磁盘,请求访问的磁道很分散,则$FCFS$在性能上很差,寻道时间长。
按照$FCFS$的规则,移动顺序为$55$、$58$、$39$、$18$、$90$、$160$、$150$、$38$、$184$号磁道。一共移动了$498$个磁道。平均寻找长度为$55.3$。
最短寻找时间优先算法
- 即$SSTF$算法,会优先处理的磁道是与当前磁头最近的磁道。可以保证每次的寻道时间最短,但是并不能保证总的寻道时间最短。(其实就是贪心算法的思想,只是选择眼前最优,但是总体未必最优)。
- 优点:性能较好,平均寻道时间短。
- 缺点:
- 可能产生“饥饿”现象。产生饥饿的原因在磁头可能在一个小区域内来回来去地移动。
- 对于全局而言未必最优。
按照$SSTF$的规则,首先需要将号码排序,$100$在$90$和$150$之间,离$90$更近,所以向更小方向移动,移动顺序为$90$、$58$、$55$、$39$、$38$、$18$、$150$、$160$、$184$。一共移动了$248$个磁道。平均寻找长度为$27.5$。
扫描算法
- 也叫电梯算法,即$SCAN$算法,规定只有磁头移动到最外侧磁道的时候才能往内移动,移动到最内侧磁道的时候才能往移动。
- 优点:
- 性能较好,平均寻道时间较短。
- 不会产生饥饿现象。
- 缺点:
- 只有到达最边上的磁道时才能改变磁头移动方向,事实上,处理了最大和最小的磁道的访问请求之后就不需要再往两边移动磁头了。
- 对于各个位置磁道的响应频率不平均。(如假设此时磁头正在往右移动,且刚处理过$90$号磁道,那么下次处理$90$号磁道的请求就需要等磁头移动很长一段距离,而响应了$184$号磁道的请求之后,很快又可以再次响应$184$号磁道的请求了)。
对于例题,按照$SCAN$规则,因为磁头向增大的方向移动,所以应该最开始访问$150$号,而$SCAN$规定只有到了最边上的磁道才能改变磁头移动方向,所以移动到$184$号后还要移动到$200$号才能往小方向移动磁头,移动顺序为$150$、$160$、$184$、$200$、$90$、$58$、$55$、$39$、$38$、$18$。一共移动了$282$个磁道,平均寻找长度为$31.3$。
LOOK调度算法
- 为了解决必须移动到两边磁道的缺点,$LOOK$规定如果在磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向。
- 优点:比起$SCAN$算法来,不需要每次都移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短。
对于例题,按照$LOOK$规则,到了$184$就可以立刻回头,所以移动顺序为$150$、$160$、$184$、$90$、$58$、$55$、$39$、$38$、$18$。一共移动了$250$个磁道,平均寻找长度为$27.5$。
循环扫描算法
- 即$C-SCAN$算法,为了解决每个位置磁道的响应频率不平均,规定只有磁头朝某个特定方向移动时才处理磁道访问请求,而返回时直接快速移动至起始端而不处理任何请求。
- 优点:比起$SCAN$来,对于各个位置磁道的响应频率很平均。
- 缺点:
- 平均寻道时间更长。
- 只有到达最边上的磁道时才能改变磁头移动方向,事实上,处理了$184$号磁道的访问请求之后就不需要再往右移动磁头了。
- 磁头返回时其实只需要返回到$18$号磁道即可,不需要返回到最边缘的磁道。
对于例题,按照$C-SCAN$规则,先访问$150$号,然后移动到$200$达到边缘,立刻返回到$0$的位置不处理,从$0$开始向右扫描,所以移动顺序为$150$、$160$、$184$、$200$、$0$、$18$、$38$、$39$、$55$、$58$、$90$。一共移动了$390$个磁道,平均寻找长度为$43.3$。
C-LOOK调度算法
- 为了解决必须移动到两边磁道的缺点,$C-LOOK$基于$C-SCAN$,规定如果在磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向,且磁头只用返回到有磁道访问请求的位置即可。
- 优点:比起$C-SCAN$算法来,不需要每次都移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短.
对于例题,按照$C-LOOK$规则,先访问$150$号,然后移动到$184$,立刻返回到最靠左的$18$号,开始向右扫描,所以移动顺序为$150$、$160$、$184$、$18$、$38$、$39$、$55$、$58$、$90$。一共移动了$322$个磁道,平均寻找长度为$35.8$。
延迟时间处理
磁头在读取一块内容后需要一段时间处理,由于盘片不断旋转,从而在处理本块内容时,回错过相邻扇区的处理,从而只能等待下次再旋转到此扇区进行读取,所以如果逻辑上相邻的扇区在物理上也相邻,则读入几个连续的逻辑扇区,可能需要很长的延迟时间。
磁盘地址结构设计
- 为什么磁盘的物理地址是(柱面号,盘面号,扇区号)而不是(盘面号,柱面号,扇区号)。
- 读取地址连续的磁盘块时,采用(柱面号,盘面号,扇区号)的地址结构可以减少磁头移动消耗的时间。
- (柱面号,盘面号,扇区号)若要连续读取物理地址$(000,00,000)\sim(000,01,111)$的扇区,读取完$(000,00,000)\sim(000,00,111)$由于柱面号/磁道号相同,只是盘面号不同,因此不需要移动磁头臂。只需要激活相邻盘面的磁头即可。
- 若物理地址结构是(盘面号,柱面号,扇区号),且需要连续读取物理地址$(00, 000,000)\sim(00,001,111)$的扇区,则$(00,000,000)\sim(00,000,111)$转两圈可读完,之后再读取物理地址相邻的区域,即$(00,001,000)\sim(00,001,111)$,需要启动磁头臂,将磁头移动到下一个磁道,花费时间更多。
交替编号
让逻辑上相邻的扇区在物理上有一定的间隔,可以使读取连续的逻辑扇区所需要的延迟时间更小。
错位命名
若相邻的盘面相对位置相同处扇区编号相同,则会出现不能连续读取的问题。所以使用错位命名,同一柱面不同盘面的扇区编号不同,从而有足够的时间来处理。
磁盘的管理
安装操作系统顺序
- $ROM$引导程序。
- 磁盘引导程序。
- 分区引导程序。
- 操作系统初始化程序。
磁盘初始化
- 进行低级格式化(物理格式化),将磁盘的各个磁道划分为扇区。一个扇区通常可分为头、数据区域(如$512B$大小)、尾三个部分组成。管理扇区所需要的各种数据结构一般存放在头、尾两个部分,包括扇区校验码(如奇偶校验、$CRC$循环冗余校验码等,校验码用于校验扇区中的数据是否发生错误)。
- 将磁盘分区,每个分区由若干柱面组成(即分为我们熟悉的$C$盘、$D$盘、$E$盘)。将每个分区的起始扇区和大小都记录在磁盘主引导记录$MBR$的分区表中。
- 进行逻辑格式化,创建文件系统。包括创建文件系统的根目录、初始化存储空间管理所用的数据结构(如位示图、空闲分区表)。其中操作系统将相邻的多个扇区组合称为簇($Linux$为块),文件内容占用空间为簇的整数倍。
引导块
- 计算机开机时需要进行一系列初始化的工作,这些初始化工作是通过执行初始化程序(自举程序)完成的。
- 初始化程序可以放在$ROM$(只读存储器)中。$ROM$中的数据在出厂时就写入了,并且以后不能再修改。
- 一般$ROM$因为无法修改所以只会存放很小的自举装入程序。
- 完整的自举程序放在磁盘的启动块(即引导块/启动分区)上,启动块位于磁盘的固定位置。
- 开机时计算机先运行自举装入程序出通过执行该程序就可找到引导块,并将完整的自举程序读入内存,完成初始化。
- 拥有启动分区的磁盘称为启动磁盘或系统磁盘($C$盘)。
- 引导控制块记录系统从该分区引导操作系统所需要的信息,若没有操作系统这块内容为空,一般为分区的第一块。$UFS$为引导块,$NTFS$为分区引导扇区。
- 分区控制块包括分区详细信息。$UFS$为超级块,而$NTFS$称为主控文件表。
坏块管理
- 坏了、无法正常使用的扇区就是“坏块”。这属于硬件故障,操作系统是无法修复的。应该将坏块标记出来,以免错误地使用到它。
- 对于简单的磁盘,可以在逻辑格式化时(建立文件系统时)对整个磁盘进行坏块检查,标明哪些扇区是坏扇区,比如在$FAT$表上标明。在这种方式中,坏块对操作系统不透明。
- 对于复杂的磁盘,磁盘控制器(磁盘设备内部的一个硬件部件)会维护一个坏块链表。
- 在磁盘出厂前进行低级格式化(物理格式化)时就将坏块链进行初始化。
- 操作系统会保留一些“备用扇区”,用于替换坏块。这种方案称为扇区备用。且这种处理方式中,坏块对操作系统透明。