操作系统之输入输出系统

汇总:Android小白成长之路_知识体系汇总【持续更新中…】

I/O硬件原理

I/O设备

大致可以分为两类:

  • 块设备:把信息存储在固定大小的块中,每个块有自己的地址,通常块的大小在512字节至65536字节之间,所有传输以一个或多个完整的(连续的)块为单位,每个块都能独立于其他块而读写,硬盘、蓝光光盘和USB盘等是最常见的块设备
  • 字符设备:以字符为单位发送或接收一个字符流,而不考虑任何块结构,字符设备是不可寻址的,大多数与磁盘不同的设备都可看作字符设备,例如打印机、网络接口和鼠标等

还有一些其他设备不包括在这两类里,例如时钟、显示器等

设备控制器

I/O设备一般由机械部件和电子部件两部分组成,电子部件称作设备控制器或适配器,机械部件则是设备本身。控制器卡上通常有一个连接器,通向设备本身的电缆可以插入都这个连接器中,很多控制器可以操作2个、4个甚至8个相同的设备。控制器和设备之间通常是一个很低层次的接口,控制器的任务是把串行的位流转换成字节快,并进行必要的粗偶校正工作,字节块通常首先在控制器内部的一个缓冲区中安位进行组装,然后再对校验和进行校验并验证字节块没有错误后,再将它复制到主存中。

内存映射I/O

每个控制器有几个寄存器用来与CPU进行通信,通过写入这些寄存器,操作系统可以命令设备发送数据、接收数据、开启或关闭,或者执行某些其他操作,通过读取这些寄存器,操作系统可以了解设备的状态是否准备好接收一个新的命令等。许多设备还有一个操作系统可以读写的数据缓冲区,可供程序或操作系统写入数据。

有两个方法可以让CPU和设备的控制寄存器和数据缓冲区进行通信:

  • I/O端口:每个控制寄存器被分配一个I/O端口,所有I/O端口形成I/O端口空间,并且受到保护,只有操作系统可以访问
  • 内存映射I/O:将所有控制寄存器映射到内存空间中,每个控制寄存器被分配唯一的一个内存地址,并且不会有内存被分配到这个地址上,这样的系统成为内存映射I/O。当CPU想要读入一个字节的时候,不论是从内存中还是I/O端口中读入,它都要将需要的地址放到总线的地址线上,然后再总线的一条控制线上置起一个READ信号,还要用到第二条信号线来表明需要的是I/O空间还是内存空间,如果是内存空间,内存将响应请求,如果是I/O空间,I/O设备将响应请求。如果只有内存空间,那么每个内存模块和每个I/O设备都会将地址线和它所服务的地址范围进行比较,如果地址落在这一范围内,就会响应请求。

直接存储器存取

在这里插入图片描述

无论一个CPU是否具有内存映射I/O,它都需要寻址设备控制器以便与它们交换数据,CPU可以从I/O控制器每次请求一个字节的数据,但是这样做浪费CPU时间,所以经常用到一种称为直接存储器读取的方案。

CPU通过设置DMA控制器的寄存器对它进行编程,所以DMA控制器知道什么数据传送到什么地方,DMA控制器还要向磁盘控制器发出一个命令,通知它从磁盘读数据到其内部的缓冲区中,并且对校验和进行校验。DMA控制器通过在总线上发出一个读请求到磁盘控制器而发起DMA传送,这一读请求和其他读请求看起来差不多,磁盘控制器并不知道或者并不关心它来自CPU还是来自DMA控制器,一般情况下,要写的内存地址在总线的地址线上,所以当磁盘控制器从其内部缓冲区中读取一个字的时候,它知道将该字写到什么地方。写到内存是另一个标准的总线周期,当写操作完成时,磁盘控制器在总线上发出一个应答信号到DMA控制器。于是DMA控制器步增要使用的内存地址,并且步减字节计数。如果字节计数仍大于0,则重复图中第2步和第4步,直到字节计数到达0。

许多总线能以两种模式操作:每次一字模式和块模式,某些DMA控制器也能够以这两种模式操作,在字模式中,DMA控制器请求传送一个字并得到这个字,如果CPU也想使用总线,它必须等待,这一机制称为周期窃取,因为设备控制器偶尔偷偷溜入并且从CPU偷走一个临时的总线周期,从而轻微地延迟CPU。在块模式中,DMA控制器通知设备获得总线,发起一连串的传送,然后释放总线,这一操作模式成为突发模式,比周期窃取效率更高,因为获得总线占用了时间,并且以一次总线获得的代价能够传送多个字。缺点是如果正在进行的是长时间突发传送,有可能将CPU和其他设备阻塞相当长的周期。

I/O软件原理

I/O软件的目标

在设计I/O软件时一个关键的概念是设备独立性,比如说一个文件作为输入的程序,应该能够读取硬盘、DVD或者USB盘上的文件,而不需要给每一种设备编写专用的程序。

I/O软件设计有几个关键的目标:

  • 统一命名:与设备独立性密切相关,一个文件或一个设备的名字应该是一个简单的字符串或一个整数,不应该依赖于设备。比如按照路径名进行寻址。
  • 错误处理:一般来说,错误应该尽可能地在接近硬件的层面得到处理。当控制器发现一个读错误时,如果它能够处理则自行纠正错误,如果控制器处理不了,那么设备驱动程序应当予以处理
  • 同步和异步传输:大多数物理I/O是异步的,CPU启动传输后便转去做其他工作,直到中断发生
  • 缓冲:数据离开设备之后通常并不能直接存放到其最终的目的地,必须放到输出缓冲区中。
  • 共享设备和独占设备:有些I/O设备(如磁盘)能够同时让多个用户使用,多个用户同时在同一磁盘上打开文件不会引起什么问题。其他设备(如磁带机)则必须由单个用户使用,直到该用户使用完,另一个用户才能拥有该磁带机

I/O实现

  • 程序控制I/O:I/O的最简单形式是让CPU做全部工作,例如一个用户进程想通过串行接口在打印机上打印一串字符,首先,字符数据被复制到内核空间,然后操作系统进入一个循环,一次输出一个字符,CPU要不断地查询设备以了解它是否就绪准备接受下一个字符,这一行为称为轮询或忙等待
  • 中断驱动I/O:在打印字符的过程中,CPU将搁置在等待中,浪费了时间。可以使用中断让CPU在等待打印机变成就绪状态的时候做其他事情。当打印字符串的系统调用被发出时,字符串缓冲区被复制到内核空间,并且接收字符复制到打印机中。这时候CPU调用调度程序,使某个其他进程开始运行,请求打印的进程将阻塞。当打印机当前字符打印完毕后,进入就绪状态,将产生一个中断,将停止正在执行的其他进程并且保存其状态没然后继续打印机的进程执行。
  • 使用DMA的I/O:中断驱动I/O的一个明显缺点是中断发生在每个字符上,中断需要花费时间,所以这一方法将浪费一定数量的CPU时间。解决方案是使用DMA,让DMA控制器一次给打印机提供一个字符,而不必打扰CPU

I/O的软件层次

在这里插入图片描述

I/O软件通常组织成四个层次,每一层具有一个要执行的定义明确的功能和一个定义明确的与相邻层次的接口,功能和接口随系统的不同而不同

  • 中断处理程序:当中断发生时,中断处理程序将做一系列工作以便对中断进行处理,然后它可以启动中断的驱动程序解除阻塞,中断的最终结果是使之前被堵塞的驱动程序现在能够继续运行,中断处理顺序
    1. 保存没有被中断硬件保护的所有寄存器,包括PSW
    2. 为中断服务过程设置上下文,可能包括设置TLB、MMU和页表
    3. 为中断服务过程设置堆栈
    4. 应答中断控制器,如果不存在集中的中断控制器,则再次开放中断
    5. 将寄存器从它们被保存的地方复制到进程表中
    6. 运行中断服务过程,从发出中断的设备控制器的寄存器中提取信息
    7. 选择下一次运行哪个进程,如果中断导致某个被阻塞的高优先级进程变为就绪,则可能选择它现在就运行
    8. 为下一次要运行的进程设置MMU上下文,也许还需要设置某个TLB
    9. 装入新进程的寄存器,包括其PSW
    10. 开始运行新进程
  • 设备驱动程序:每个连接到计算机的I/O设备都需要某些特定的代码程序来对其进行控制,一般由设备的制造商编写并随同设备一起交付,每个设备驱动程序通常处理一种类型的设备。操作系统通常将驱动程序归类于块设备和字符设备。块设备(如磁盘)包括多个可以独立寻址的数据块,字符设备(如键盘、打印机)则生成或接收字符流
  • 与设备无关的I/O软件:基本功能是执行所有设备公共的I/O功能,并且向用户层软件提供一个统一的接口。要负责把符号化的设备名映射到适当的驱动程序上,它包括:
    • 提供设备驱动程序统一接口
    • 缓冲
    • 错误报告
    • 分配与释放专用设备
    • 提供与设备无关的块大小
  • 用户空间的I/O软件:尽管大部分I/O软件都在操作系统内部,但仍然有一小部分在用户空间,包括与用户程序连接在一起的库,甚至完全运行于内核之外的程序。系统调用(包括I/O系统调用)通常由库过程实现。

猜你喜欢

转载自blog.csdn.net/Nbin_Newby/article/details/117669334