持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
标*证明目前没有,以后可能添加
如果有符号并且没排版表示这些内容不需要记住,不太重要
*I/O硬件(计组内容)
I/O软件
I/O 软件的目标
Device Independence 设备独立性:从软盘、磁盘、CD-ROM读写,无需修改。(程序可以访问任何输入/输出设备,无需事先指定设备。) 输入/输出软件应抽象设备详细信息。
Uniform Naming 统一命名 我们指定文件或设备的方式应该以相同的方式完成。 文件或设备的名称是字符串或整数,不取决于哪台机器:相同类型的不同设备具有相似的名称。 在UNIX中,所有I/O都与文件系统集成。
Error Handling 错误处理 尽可能靠近硬件处理错误。 仅当下层无法处理错误时,才向上传播错误。 尽可能隐藏错误许多硬件错误是暂时的。
Synchronous vs. Asynchronous Transfers 同步与异步传输 即阻塞传输与中断驱动interrupt-driven 大多数输入/输出硬件都是异步操作的。 应用程序级同步读/写。 同步(阻塞)读/写更易于编程。 由操作系统来执行实际上是中断驱动的I/O操作,以阻止用户程序。
Buffering 缓冲 来自设备的数据不能存储在最终目标中。
Sharable vs. Dedicated Devices 可共享与专用设备 E、 g.磁盘可共享。 E、 g.磁带机是专用的,可能会带来各种问题,例如死锁。 操作系统必须能够以避免问题的方式处理共享和专用设备。 使专用设备显示为可共享,如打印机
I/O软件(I/O三种实现)
用户空间中的系统调用,数据从用户空间复制到内核空间。
输入/输出软件可以在多种模式下运行:
- 编程输入/输出: 轮询/忙等待设备。
- 中断驱动输入/输出: 操作由中断程序完成。
- 基于DMA的输入/输出: 设置控制器并让其处理传输。
Programmed I/O 程序控制I/O
CPU总是忙于I/O,直到I/O完成(同步、阻塞)。适用于单流程系统,但对于多编程和分时系统来说,这不是一个好方法
output操作实现:
- 数据从用户空间复制到内核空间,供CPU访问
- 然后,操作系统紧循环(轮询)设备(通常检查状态寄存器),查看设备是否准备好接收更多数据。
- 一旦设备准备好接受更多数据,操作系统将把数据复制到设备寄存器。
- 复制完所有数据后,控制将返回给用户程序。
优点:易于实现。
缺点:“忙等待”状态,CPU将忙于检查打印机(控制器)的状态寄存器,这是对CPU的浪费。
Interrupt Driven I/O 中断驱动I/O
中断驱动流程:
- CPU中的中断驱动初始化I/O
- 初始化I/O
- 输入准备或者输出完毕时,产生中断信号给CPU
- CPU收到中断,控制权给中断服务程序
- 中断服务程序处理完后,返回给CPU
- 中断之前运行的进程,进程从停止的地方继续运行
打印字符串示例的改动:
- 如果是中断驱动,在上述示例当中,打印机将字符打印完并准备好接受下一字符时,产生中断,中断将停止进程并保存状态,然后运行中断服务过程。
- 一个中断服务过程:
- 若没有更多字符打印,将用户进程解除阻塞
- 若继续,输出下一字符,应答中断,返回到中断之前运行的进程,进程从停止的地方继续运行。
打印字符串流程:
- 用户程序进行系统调用,告诉操作系统打印字符串。
- 将应用程序缓冲区内容复制到内核缓冲区并向打印机发送1个字符后:
-
CPU不会等待打印机再次就绪,而是调用scheduler()并运行其他进程。
-
当前进程将处于阻塞状态,直到打印整个字符串。
-
当打印机打印完字符并再次准备就绪时,打印机控制器生成硬件中断。
-
优点:它比Programmed I/O更快,效率也很高。
缺点:如果使用低级语言,编写可能会很复杂、 中断发生在每个字符上,中断费CPU时间。
I/O Using DMA 使用DMA的I/O
实际上,DMA本身是Programmed I/O,改进思路是让DMA控制器代替CPU完成硬件端操作
打印字符串示例:
- DMA控制器将字符从内核缓冲区送到打印机控制器(缓冲区和设备控制器之间的事不用CPU操心)。
- CPU在此传输过程中不受干扰,整个缓冲区(字符串)传输完成后,CPU中断。
好处:节省CPU时间
坏处:DMA本身比CPU慢,如果CPU本身闲的没事干反而背离使用DMA的初心
I/O Software Layers I/O软件层次
目的是抽象、封装和分层:软件工程问题,可以独立修改层,而不影响上面和下面的层次
Interrupt Handlers 中断处理程序
- 隐藏中断处理程序,避免影响OS其他部分,最好的隐藏方法是让驱动程序阻塞I/O操作,直到中断通知完成。
- 中断处理程序执行工作后取消阻塞启动它的驱动程序。
- 如果设备驱动程序是内核中的线程,则该机制工作得最好。
中断处理程序例程:
- 中断(异步,进程外部)基本上与异常和陷阱(同步,进程内部)使用相同的机制。
- 当中断发生时,CPU保存少量状态并跳转到内存中固定地址的中断处理程序例程。
- 中断例程的位置由中断向量确定。
经典步骤(可忽略): 1、保存中断硬件尚未保存的regs。2、设置中断服务程序的上下文:TLB、MMU和页表。3、为中断服务程序设置堆栈。4、Ack中断控制器,可重入中断。5、将寄存器从保存位置复制到流程表。6、运行维修程序。7、选择下一步要运行的进程。8、为下一个要运行的进程设置MMU上下文。9、加载新进程寄存器。10、开始运行新流程。 中断处理是一项复杂的操作,需要大量的CPU周期,尤其是对于虚拟内存。
Device Drivers 设备驱动
设备驱动程序是管理设备控制器和操作系统之间交互的特定模块。每个驱动程序可以处理一种类型的设备或一个类(例如SCSI)
驱动程序通常是操作系统内核的一部分Unix–使用设备驱动程序编译的内核。Linux–使用可加载模块,这些模块是系统运行时加载到内核中的代码块。Windows–在启动和即插即用时动态加载到系统中。
驱动程序有几个功能:
- 接受来自上述独立于设备的软件的抽象读/写请求,并将其转换为特定于输入/输出模块的具体命令。
- 调度请求:优化排队的请求顺序以获得最佳的设备利用率(例如:磁盘arm)。
- 如果需要,初始化设备。
- 管理电源需求并记录设备事件。
- 管理数据传输。
- 维护驱动程序和内核数据结构的完整性。
设备驱动程序的典型代码组织 检查上述输入参数的有效性。 如果有效,请转换为具体命令,例如,将块号转换为磁盘几何体中的磁头、磁道和扇区。 检查设备当前是否在使用中;如果是,队列请求;如果没有,可能会打开设备、预热、初始化等。 向控制器发出适当的命令序列。 如果需要等待,请阻止。 阻塞中断后,检查错误并将数据传回。 处理下一个排队的请求。
驱动程序和设备控制器之间的通信通过总线进行
操作系统和驱动程序通信:操作系统和设备驱动程序之间的命令和数据。
驱动程序和硬件通信:驱动程序和硬件之间的命令和数据。
设备驱动程序类型:
- 块:固定大小的块数据传输。
- 字符:可变大小的数据传输。
- 终端:具有终端控制的字符驱动程序。
- 网络:用于联网的流。 根据传输的流的类型也分成块设备和字符设备
大多数操作系统都为设备驱动程序定义了标准接口。该接口由许多操作系统其余部分可以调用的过程组成。分成块接口(设备地址转缓存地址)和字符接口(字符流存缓存地址)
驱动程序代码需要处理可插拔设备。
不允许驱动程序进行系统调用,但它们可以调用内核过程。如管理MMU、定时器、DMA控制器、中断控制器等。
Device-Independent I/O Software 与设备无关的I/O软件
设备驱动程序和设备无关软件之间的界限因系统和设备而异。
功能:
- 与设备驱动程序的统一接口
- 缓冲
- 错误报告
- 分配和释放专用设备
- 提供与设备无关的块大小
Uniform Interfacing
- 内核代码的统一设备接口
- 允许以相同的方式使用不同的设备。
- 无需重写文件系统即可在SCSI、IDE或RAM磁盘之间切换。
- 允许对设备驱动程序进行内部更改,以免破坏内核代码。
- 设备代码的统一内核接口
- 驱动程序使用定义的内核服务接口(例如kmalloc、install IRQ handler等)
- 允许内核在不破坏现有驱动程序的情况下发展。
- 这两个统一接口一起避免了大量实现新接口的编程
输入/输出设备如何命名?
- 独立于设备的软件将符号设备名称映射到正确的驱动程序上。
- 在Unix中,设备被建模为特殊文件。
- 通过使用系统调用(如open()、read()、write()、close()、ioctl()等)来访问它们。
- 文件名与每个设备关联。
- 主设备编号可找到相应的驱动程序。
- 次要设备编号(存储在i节点中)作为参数传递给驱动程序,以指定要读取或写入的单元。
- 通常的文件保护规则也适用于I/O设备。
buffering 缓冲
在设备和应用程序之间传输数据时,将数据存储在内核空间的内存区域。
目的/功能:
- 应对生产者和消费者之间的速度不匹配。
- 例如调制解调器(Modem)的速度比磁盘慢千倍。
- 适应不同数据传输大小的服务。
- 例如网络数据包的碎片化和重组。
缓冲演进: 无缓冲输入->用户级缓冲(解决上述问题)->单缓冲:在内核中进行缓冲,需要时复制到用户空间(内存中为I/O申请缓冲区,避免分页到磁盘)->双缓冲(解决内核缓冲区已满,用户缓冲区被调出)->循环缓冲Circular Buffer(2个以上,因为2个应对突发流量有时还不够)
缓冲、双缓冲和循环缓冲都是有界缓冲问题(生产者-消费者问题)。
Error Reporting 错误报告
某些错误由设备控制器处理,如校验和不正确,使用冗余位重新更正块。 有些是通过设备派生程序,如无法读取磁盘块,从磁盘重新发出块的读取操作。 有些是由独立于设备的软件层操作系统实现的: 重试输入/输出或向用户报告错误代码。
错误类型:编程错误与输入/输出错误
- 编程错误:如尝试写入只读设备。
- 实际输入/输出错误,如摄像机已关闭,因此我们无法阅读。向调用应用程序返回此错误的指示。
Allocating& Releasing Dedicated Devices 分配与释放专用设备
不允许同时访问专用设备,如CD-RW。 要求进程直接对设备的特殊文件执行open()。 如果open()失败,进程将重试。 具有请求和释放专用设备的特殊机制。 试图获取不可用的设备会阻止调用者。
Device-independent Block Size 与设备无关的块大小
有不同种类的磁盘驱动器。每个都可能有不同的物理扇区大小。 文件系统在将文件映射到逻辑磁盘块时使用块大小。 该层可以隐藏不同磁盘的物理扇区大小,并为更高的层(如文件系统)提供固定且统一的磁盘块大小 可以将多个扇区视为单个逻辑块。
User-Space I/O Software 用户空间I/O软件
- 提供I/O函数实现的I/O库,这些函数反过来调用各自的I/O系统调用。
- 这些库还实现了格式化的I/O函数,如printf()和scanf()
- 某些程序不直接写入输入/输出设备,但写入后台处理程序。
小结
Disks(盘,并不特指磁盘)
磁盘
组织成圆柱体:每个柱面都包含磁道(track),磁道的数量等于磁盘驱动器中磁头的数量。每条磁道分为多个扇区。
Disk Formatting - Low-level Formatting(只阐述低级格式化)
目的:将磁盘划分为磁盘控制器可以读写的扇区。
每个磁道被格式化为扇区和扇区之间的间隙:
Cylinder Skew 柱面斜进
读取顺序块时,寻道时间(从一个磁道到另一个磁道)可能导致读取下一个磁道时错过该磁道第0扇区。 可以使用柱面倾斜来格式化磁盘,以避免这种情况。
柱面斜进:在不同点启动圆柱体,使头部有时间从一个点跳到下一个点。
例如:10000rpm磁盘驱动器,每条磁道300个扇区,寻道时间800us,柱面倾斜为40个扇区
解析:10000转/min表示驱动器在6 ms内旋转,轨道有300个扇区表示每20μs新扇区,寻道时间800μs推出寻道时旋转通过40个扇区
Interleaving 交错
高速连续读磁盘要求Disk Controller中有一个扇区缓冲区,在将一个扇区的数据从硬盘传输到控制器缓冲区后,我们将把控制器缓冲区复制到内存中。但在此期间,磁头将通过下一个扇区的起始位置。 因此,下一个逻辑扇区不应是硬盘中的下一个物理扇区
因此将扇区编号交错:
现代驱动器只需将整个磁道(或其中的一部分)读取到磁盘控制器中并对其进行缓存,即可克服交错类型的问题。
*Disk Partitioning 分区
属于高级格式化操作
*Disk Queues
Disk Arm Scheduling 磁盘臂调度
读取一个块(扇区)需要多长时间?
- 数据传输时间
- 定位时间
- 寻道时间Seek Time(主导):将臂移到正确的柱面上。
- 旋转延迟Rotational Delay:等到正确的扇区到达头部下方。
假设磁盘负载很重:
- 有很多对磁盘块的请求到达硬盘驱动程序。
- 驱动程序将请求排队。
- 驱动程序知道每个块请求,块应该存储在硬盘中的什么位置柱面号。
磁盘驱动程序:
- 保留请求表。
- 表由柱面号索引。
- 对同一柱面的Blocks请求被放入一个链表中。
调度算法
- First Come First Served(FCFS)
- 优势:公平
- 缺点:寻道成本和轮换率高
- 最短寻道优先Shortest Seek First(SSF)
- 优点:减少手臂移动(寻道时间)
- 缺点:不公平,可能导致某些请求无法满足
- 电梯算法(SCAN):就像电梯一样,向一个方向移动,直到该方向的所有请求都得到满足
- 优点:对请求更公平,性能与SSTF相似
- C-SCAN:循环扫描,扫完回到开头
- 提供比扫描更均匀的等待时间。