目录
I/O软件的层次结构
一、用户层软件
二、设备独立性软件(属于操作系统内核)
三、设备驱动程序(属于操作系统内核)(与硬件直接相关)
四、中断处理程序(属于操作系统内核)(与硬件直接相关)
I/O软件的设计目标:
I/O软件的设计思路:把软件组织成层次结构,低层软件用来屏蔽硬件细节,高层软件向用户提供简洁、友善、统一的界面。
用户层软件:实现了与用户交互的接口(用户可直接使用I/O操作相关的库函数对设备进行操作),将用户请求翻译成格式化的I/O请求,通过“系统调用”请求操作系统内核的服务,SPOOLing技术(假脱机技术)也在该层实现。
1、库函数:一部分I/O软件可以使用库函数实现,放在操作系统内核之外,由用户层软件提供,运行时与应用程序链接。库函数是对设备独立性软件提供的系统调用进一步封装,便于用户直接使用。
2、假脱机技术(SPOOLing技术):Simultaneous Peripheral Operation On-Line (即外部设备联机并行操作)的缩写,是关于慢速字符设备如何与主机交换信息的技术。
在通道技术和多道程序技术的基础上,用软件的方式实现脱机技术,用一类物理设备模拟另一类物理设备,将一个独占设备虚拟成多个共享设备。
- 解决CPU和低速设备的速度不匹配问题:在高速设备(通常是磁盘)上开劈区域暂存与低速设备传送的数据,CPU与磁盘进行数据传送。
- 实现了脱机技术:低速设备的输入输出过程,通过“外围控制机”控制,不需要CPU干涉;CPU处理时只需和已暂存在磁盘的数据传送;对于用户来说看似是脱机输入输出。
- 实现了虚拟设备功能:多个进程“同时”使用一个独占设备,并认为自己独占了设备。实际上设备并没有分配给任何进程,只是给每个进程在磁盘中分配了存储空间(相当于分配了一个逻辑设备)和建立一张I/O请求表。
低速设备通过通道(硬件)和缓冲区(主存中的一部分区域)与高速设备相联,高速设备中划分出两个区域:(输入井)用于存放从低速设备读取的数据和(输出井)存放应用程序输出的数据。
一般,低速设备与主存之间数据传送通过通道控制方式,高速设备与主存之间数据传送通过DMA控制方式。参考:I/O控制方式
从设备输入数据:
- 收到输入请求信号后,系统为其在输入井分配空白存储空间,输入进程负责将设备的数据读入主存中的输入缓冲区,缓冲区满后,写入磁盘的输入井,读写反复直到输入完毕(即读到硬件结束标志,发送中断处理程序,结束此次输入)。
- 系统为其建立一张I/O请求表,并填写该表,将该表放入相应的队列。
- 等待调度后进入主存运行。
向设备输出数据:
- 系统在磁盘的输出井中为进程分配空白存储空间,将应用程序的数据放入输出井。
- 系统为进程建立一张I/O请求表,并填写该表,将该表放入相应的队列。
- 由输出进程控制,依次从队列中取出申请表,根据表中内容将数据从磁盘的输出井取出放入主存的输出缓冲区,再输出到设备。
守护进程(Daemon)是Linux 中在后台运行的独立于控制终端的一种特殊进程。生存期较长(一般是系统启动到系统停止运行),周期性地执行某种任务或等待处理某些发生的事件。 大多数服务都是通过守护进程实现的,它执行一部分原来由假脱机管理进程实现的功能。
设备独立性:建立逻辑设备和物理设备之间的映射关系,提供逻辑设备名和物理设备名的对应表。用户通常不指定具体物理设备,而是指定逻辑设备,使得用户进程和物理设备分离开。
设备独立性的优点:
设备独立性软件:独立于设备的软件。向上层(用户层软件)提供统一的系统调用接口,并执行适用于所有设备的常用I/O功能:设备的保护(设置设备访问权限,一般以文件形式管理设备),差错处理(对设备的错误进行处理),设备的分配与回收,数据缓冲区管理,建立逻辑设备名到物理设备名的映射关系(根据设备类型选择调用功能相应的驱动程序)。
1、系统调用
系统调用由设备独立性软件提供,向上层(用户层软件)提供统一的调用接口。
但设备有字符设备、块设备、网络设备。应用程序不能用统一的系统调用接口完成所有类型的设备I/O。因此,输入/输出应用程序接口有字符设备接口、块设备接口、网络设备接口。
- 字符设备:以字节为单位顺序处理数据,没有缓冲区,不支持随机读写。常见的字符设备如普通打印机、系统的串口、终端显示器、鼠标、键盘、手写板等。
- 块设备:以块为单位传送数据,一般都采用缓冲技术,支持数据的随机读写。典型的块设备有硬盘、光驱等。
- 字符设备和块设备面向的上一层是文件系统层。对用户来说,块设备和字符设备的访问接口,都是一组基于文件的系统调用,如read, write等。都有一个对应的设备文件(即设备节点,包含了设备的类型、主/次设备号以及设备的访问权限控制等 )。
- 网络设备:网络设备面向的上一层是网络协议层。应用程序通过socket(套接字)来访问网络设备。在文件系统中不存在对应的节点项。常见网络设备有:交换机、路由器、防火墙、集线器、网关、网络控制器(网卡)等。
字符设备接口 | get/put系统调用 | 向字符设备读/写一个字符 |
---|---|---|
块设备接口 | read/write系统调用 | 向块设备的读写指针位置读/写多个字符 |
seek系统调用 | 修改读写指针位置 | |
网络设备接口 | socket系统调用 | 创建一个网络套接字,需指明网络协议(TCP或者UDP) |
bind系统调用 | 将套接字绑定到某个本地“端口” | |
connect系统调用 | 将套接字连接到远程地址 | |
read/write系统调用 | 从套接字读/写数据 |
阻塞I/O | 应用程序发出I/O系统调用后,进程进入阻塞态等待 | 例如:字符设备接口,get系统调用,从键盘读一个字符 |
---|---|---|
非阻塞I/O | 应用程序发出I/O系统调用后,系统调用可迅速返回,进程无需阻塞等待 | 例如:块设备接口,write系统调用,往磁盘写数据 |
2、设备的保护
一般设备以文件的形式管理。类似于文件保护的功能。通过设置设备的访问权限,限制用户对设备的访问,来实现对设备的保护。
3、逻辑设备名到物理设备名的映射
逻辑设备表(LUT,Logical Unit Table):逻辑设备名到物理设备名的映射关系,即逻辑设备到物理设备的对应表,操作系统通过逻辑设备名(其实是设备类型)选择调用功能相应的驱动程序。
单用户操作系统:整个系统只有一张LUT,LUT中的逻辑设备名不允许重复。
多用户操作系统:每个用户一张LUT,LUT存放在用户管理进程的PCB中,不同用户的逻辑设备名可以重复。
4、设备的分配与回收
进程向系统发出I/O请求,申请使用设备,系统按一定策略将设备(以及相应的控制器和通道)分配给进程。
设备分配时应考虑的因素:设备的固有属性(独占设备,共享设备,虚拟设备),设备分配算法,设备分配中的安全性(安全分配方式,不安全分配方式)。
设备分配算法:与进程调度算法类似。
设备分配方式:
静态分配:进程运行前分配所有资源,运行结束后归还资源。
动态分配:进程运行中动态申请分配。
设备分配管理中的数据结构:
① 系统设备表(SDT):记录系统中所有设备的情况。每个设备对应一个表目。一个表目包含设备类型、设备标识符、DCT指针、驱动程序入口。
② 设备控制表(DCT):每个设备对应一张DCT,记录设备情况。根据DCT表中的指向控制器表的指针找到对应控制器的信息。
③ 控制器控制表(COCT):每个设备控制器对应一张COCT。根据COCT表中的指向通道表的指针可以找到相应通道的信息。
④ 通道控制表(CHCT):每个通道对应一张CHCT。
设备分配过程:
只有设备、控制器、通道都分配成功,则设备分配才算成功,才与设备进行数据传送。
若用户再次使用逻辑设备名(设备类型)申请使用设备,操作系统会直接查找逻辑设备表(LUT)找到对应驱动程序。
5、数据缓冲区管理
缓冲区:一个存储区域。可以用寄存器实现,也可以在主存划分出一部分区域。寄存器价格贵容量小,快表是在寄存器中,但多数是用主存作为缓冲区。
I/O缓冲区是在主存中开辟的存储区,专门用于临时存放I/O操作的数据。
设置I/O缓冲的目的:
注:缓冲区非空时,不能往缓冲区输入数据,只能从缓冲区把数据传出;缓冲区为空时,可以往缓冲区输入数据;缓冲区充满以后,才能从缓冲区把数据传出。
① 单缓冲(Single Buffer):操作系统在主存中分配一个缓冲区。
输入:I/O设备 --> 缓冲区 ,(缓冲区满)缓冲区 --> 用户进程的工作区,应用程序处理数据。
输出:用户进程的工作区 --> 缓冲区,(缓冲区满)缓冲区 --> I/O设备,应用程序继续请求输出数据。
注:工作区满,缓冲区空,则CPU处理数据和设备向缓冲区输入数据可同时进行。
② 双缓冲(Double Buffer):操作系统在主存中分配两个缓冲区。
输入:I/O设备 --> 缓冲区1,(缓冲区1满)缓冲区1 --> 用户进程的工作区(同时:I/O设备 --> 缓冲区2),应用程序处理数据。
输出:用户进程的工作区 --> 缓冲区1,(缓冲区1满)缓冲区1 --> I/O设备(同时:用户进程的工作区 --> 缓冲区2)。
注:工作区空,一个缓冲区满,一个缓冲区空,则满的缓冲区将数据传送到工作区和设备向空的缓冲区输入数据可同时进行。工作区满,一个缓冲区满,一个缓冲区空,则CPU处理数据和设备向空的缓冲区输入数据可同时进行。
③ 循环缓冲
操作系统在主存中分配一组大小相等的缓冲区,每个缓冲区有指向下个缓冲区的链接指针,构成循环缓冲。有两个指针(一般in指针和out指针),一个指向下一个空的缓冲区,一个指向下一个满的缓冲区。
输入:输入进程不断往空的缓冲区输入数据,用户进程不断从满的缓冲区读取数据。
输出:用户进程不断往空的缓冲区冲入输出数据,输出进程不断从满的缓冲区向设备输出数据。
④ 缓冲池:由系统中共用的缓冲区组成。3个队列:空缓冲队列,输入队列,输出队列。4个工作缓冲区:用于收容输入数据的工作缓冲区,用于提取输入数据的工作缓冲区,用于收容输出数据的工作缓冲区,用于提取输出数据的工作缓冲区。
输入:输入进程请求输入数据时,从空缓冲队列中取出一块空缓冲区作为收容输入数据的工作缓冲区,将数据输入,冲满后挂入输入队列;用户进程需要使用已存入的输入数据时,从输入队列取出一块缓冲区作为提取输入数据的工作缓冲区,将数据读取到用户进程,读空后挂入空缓冲队列。
输出:用户进程请求输出数据时,从空缓冲队列中取出一块空缓冲区作为收容输出数据的工作缓冲区,冲满输出数据后,挂入输出队列;输出进程将数据输出到设备时,从输出队列取出一块缓冲区作为提取输出数据的工作缓冲区,读空后,挂入空缓冲队列。
不同的设备,内部硬件特性不同(I/O控制器不同),操作系统规定统一标准的设备驱动程序接口(不同操作系统的标准不同),设备的厂家根据操作系统的标准来提供相对应的驱动程序,驱动程序相当于硬件设备的接口,CPU通过这个接口才能控制设备的工作。
若设备的驱动程序没有正确安装,这个设备就不能正常工作。但有些设备不需要安装驱动程序也可以使用,例如磁盘、鼠标、键盘、显示器等,这些都可以用操作系统自带的标准驱动程序来驱动。
每个设备驱动程序原则只处理一种设备,或者一类紧密相关的设备。
设备驱动程序(Device Driver):负责对硬件设备的具体控制,将上层(设备独立性软件)发出的命令转化成具体要求,发送给设备控制器,由设备去执行。
设备驱动程序的功能:
设备驱动程序可以分层实现:
中断:在多道程序系统中,一个程序执行时,因某些情况,需暂停当前程序去执行其他程序。
中断处理程序进行中断处理:保护被中断进程的CPU环境,转入相应的中断处理程序进行处理,处理完并恢复被中断进程的现场后,返回到被中断进程。
I/O中断处理程序:
I/O中断处理程序的功能:
检查设备状态寄存器,判断中断原因,根据I/O操作完成情况进行相应处理。
I/O系统
磁盘、固态硬盘