输入/输出

操作系统IO接口对于所有设备都应该是相同的,即设备无关性

I/O 硬件管理

I/O设备

  • 块设备:以块为单位进行读写
  • 字符设备:以字符为单位发送或接收字符流

设备控制器

IO设备由机械部件与电子部件构成 电子部件称为 设备控制器 或者 适配器

控制器的任务 : 将串行的比特流转换为字节块,并完成纠错工作

内存映射IO

控制器使用寄存器或者一块操作系统可以操作的RAM进行通信

给控制寄存器分配一个IO端口,所有IO端口形成IO端口空间吗,可以通过一条特殊的指令来来对控制寄存器进行读取或写入

IN REG, PORT ; CPU从指定IO端口读取数据到REG寄存器
OUT PORT, REG ; CPU写入数据

另外一种方式是将IO设备寄存器映射到内存上,对内存的读写都会通过总线信号映射到IO设备的寄存器。内存映射IO优点:

  • 无需使用特殊指令读取IO设备寄存器,映射后能直接通过访问内存你的指令读写
  • 不需要特殊保护机制阻止用户进程进行IO操作,操作系统只需要避免把映射的那块内存暴露在用户地址空间就能避免用户进程进行IO操作
  • 可以应用于内存的指令也能应用于控制寄存器

缺点:

  • 不能使用高速缓存,对IO映射内存做缓存的后果是灾难性的

计算机如何确定一个内存地址对应的是内存还是IO设备寄存器?现代的计算机大都包含高速内存总线,对内存的读写可以通过专用总线来进行,而对IO设备的读写则可以通过通用总线。

第二种设计是通过一个内存总线探查设备,该设备会对IO设备访问放行。

第三种设计则是对内存地址进行过滤,规定一个区域的地址为IO内存映射。

直接存储器存取(DMA)

屏幕截图 2021-01-07 162819

加入一个中间层 从CPU-设备 变成 CPU - DMA - 设备

  • 突发模式:DMA直接让设备获得总线发起一连串传送,然后再释放总线
    • 如果传送时间较长 有可能阻塞CPU或者其他设备
  • 飞越模式: 让设备控制器将数据直接写到主存

设备控制器内部缓存区存在的原因

  • 校验数据
  • 总线可能忙

中断

屏幕截图 2021-01-07 163944

当设备发起一个中断信号,这个信号会被中断控制器芯片检测到。如果有设备同时发起中断,此时该设备中断不会被处理,不被处理的设备会不断发起信号,直至得到CPU的服务。

中断控制器在放置一个数字信号表明需要处理哪个设备,这个数字信号被称为 中断向量 ,中断向量是一个服务过程的程序地址,CPU需要保存相关好相关信息,如PC,然后跳转到指定地址指向相应的服务过程。

由于现代CPU都会采用流水线技术,所以中断后一些指令执行了一部分,怎么确保这个状态是明确的

屏幕截图 2021-01-07 164930

  • 精确中断 :机器停留在一个明确状态的中断

    • 程序计数器保留在一个已知的地方
    • 所指向的指令之前的所有指令已执行完毕
    • 所执行的指令之后的所有指令都还未执行
    • 所指向的指令的执行状态是已知的
  • 不精确中断

IO软件原理

IO软件的目标

  • 设备独立性:面向接口编程
  • 统一命名:设备的命名映射为一个简单的字符串或数字,不依赖于设备
  • 错误处理:低层能处理的问题,就不要交给高层
  • 同步与异步:大多数物理IO是异步的,只是read系统调用后,进程被挂起直至数据到达,如果IO是同步的,用户程序编写器就会很容易
  • 缓冲:数据通常不能直接从源传输到目的地,所以需要缓冲区

程序控制IO

让CPU做全部工作 程序控制IO伪代码:

copy_from_user(buffer,p,count);
for(i = 0;i<count;i++){ // 循环写操作
    while (*p_regs != READY){ // 检查IO设备是否就绪
        *p_regd = p[i]; // 向IO设备写入数据
    }
}
return_to_user();

这种IO模型好处在与简单,缺点在于在IO操作完成之前,要占用全部CPU时间

中断驱动IO

程序控制IO浪费的地方在于如果IO设备不就绪,CPU的时间就浪费在无谓的循环的上面了。

中断驱动IO改进的地方在于当IO设备就绪,由IO设备主动产生一个中断,CPU在中断之前可以去调度其他进程。

使用DMA的IO

让DMA控制数据传输,而不必打扰CPU。本质上还是程序控制IO,只不过使用了DMA后CPU可以每次写入一整个缓冲区的数据。

IO软件层次

屏幕截图 2021-01-13 162227

中断处理程序

在响应一个特定中断的时候,内核会执行一个函数,该函数叫中断处理程序

隐藏中断的最好方式是将会引起中断的操作阻塞起来。但中断处理需要花费相当多的CPU指令。

设备驱动程序

每个链接到计算机上的IO设备都需要某些设备特定代码进行控制,称之为 设备驱动程序

USB设备驱动通过堆栈式来达到不同的设备基于同样的技术效果。为了访问设备的硬件,大多数操作系统都要求驱动程序运行在内核中,这也是系统崩溃的一个源头之一。

可重入性 :驱动必须意识到第一次调用完成之前第二次调用会到来

与设备无关的IO软件

  • 设备驱动程序的统一接口

对于每种设备类型类型,操作系统定义一组驱动程序必须支持的函数,设备名可以使用设备类型+次版本号来编码,同样,对文件系统的保护规则也适用于设备。

  • 缓冲

屏幕截图 2021-01-14 155141

双缓冲:使用两个缓冲区交替使用,当一个满了之后直接复制到用户空间,另外一个接替上

环形缓冲:通过两个前后指针不断往前走实现一个逻辑上无限的缓冲区

  • 错误报告

对于编程错误,如向一个输入设备发出了一个输出请求,操作系统直接返回错误码即可。

但对于实际的IO错误,应由驱动程序决定做什么,驱动程序解决不了,再向高层传递。但错误抛到高层,操作系统实际上除了返回一个错误码并失败外,并不存在其他多少事情可以做。

  • 分配与释放专用设备

对于只允许有限数量进程使用的设备,操作系统必须对设备的使用请求进行检查,可以将得不到设备的进程调用失败掉。另外一种方式可以对得到设备的进程调用进行阻塞,而不是让其失败。

  • 提供与设备无关的块大小

上层软件屏蔽掉不同设备的的块大小不一致

用户空间的IO软件

部分IO操作在用户空间完成,这是通过库过程来实现,也有通过假脱机的方式及守护进程的方式实现。

假脱机:IO设备通过一个文件来代表IO处理,用户进程直接处理这个文件来实现IO。

守护进程:用户进程通过将文件放置于某个目录下的,该目录称为假脱机目录,只有一个允许访问IO设备的进程,来读取这些文件进行操作,这个进程就是守护进程。

屏幕截图 2021-01-14 170929

磁盘

磁盘驱动器不本身就包含一个微控制器,这允许磁盘驱动器发出一些诸如高速缓存、坏块重映射等高级命令

结构

2020321928

  • 盘面(Platter):一个磁盘有多个盘面
  • 磁道(Track):盘面上的圆形带状区域,一个盘面可以有多个磁道
  • 扇区(Track Sector):磁道上的一个弧段,一个磁道可以有多个扇区,它是最小的物理储存单位,目前主要有 512 bytes 与 4 K 两种大小
  • 磁头(Head):与盘面非常接近,能够将盘面上的磁场转换为电信号(读),或者将电信号转换为盘面的磁场(写)
  • 制动手臂(Actuator arm):用于在磁道之间移动磁头
  • 主轴(Spindle):使整个盘面转动

RAID

Redundant Array of Independent Disks,独立磁盘冗余阵列。通过将多个磁盘组合起来,使用RAID控制器代替磁盘驱动器以完成常规的操作。

  • RAID0:将磁盘划分为多个条带,若读取多个条带的数据,可以实现并行IO,但对于每次读取一个条带的操作系统,性能不仅同普通磁盘,而且还有故障率更高的风险
  • RAID1: 在RAID0的基础上整个数据复制一份,写性能比单个磁盘差,但读性能很高,并且拥有容错性,一旦一个磁盘挂掉,使用副本代替即可
  • RAID2:工作在字的基础上,使用了汉明码来进行纠错,即使一个磁盘挂掉,也能恢复出正确数据
  • RAID3:在2的基础上,使用奇偶校验码。如果磁盘挂掉,由于挂掉的磁盘位置已知,所以可以推算出丢失的数据位为0还是0 2和3的性能都不比单个磁盘好
  • RAID4:重新使用了条带,使用一个驱动器专门存放前面4个条带的奇偶校验。但这种设计对小更新的性能很差,因为每次更新都需要更新校验和。
  • RAID5:在4的基础上将校验和平均分布到各个磁盘,但如果某个磁盘挂掉,那就不好恢复了
  • RAID6:在5的基础上使用额外的校验块。

屏幕截图 2021-01-15 161911

磁盘格式化

低级格式化:对每个扇区设置前导码,ECC,由于前导码与ECC需要占用一定空间,所以可用磁盘容量总比宣传的小

磁盘分区:0扇区包含主引导记录(MBR),MBR包含一些引导代码及分区表

高级格式化:设置引导块、空闲存储管理、根目录、文件系统

系统的启动流程:BIOS运行->读入MBR并跳转->执行引导程序->找到操作系统内核载入内存执行

磁盘臂调度算法

读写磁盘块所需要的时间多少由以下三个因素决定:

  • 旋转时间:主轴转动盘面,使得磁头移动到适当的扇区上需要的时间
  • 寻道时间:制动手臂移动,使得磁头移动到适当的磁道上需要的时间
  • 数据传输时间

调度算法:

  • 先来先服务算法
    • 按照磁盘请求的顺序进行调度
    • 公平简单,但是没有对寻道做任何优化,平均寻道时间较长
  • 最短寻道优先
    • 优先调度距距离磁头最近的磁道
    • 不够公平,如果一个请求距离当前磁头比较远,会出现饥饿现象 屏幕截图 2021-01-18 151803
  • 电梯算法
    • 总是保持一个方向运行,直到该方向没有请求为止,然后改变运行方向 20203219747

旋转时间与寻道时间十分影响性能,所以一次只读取一个或者两个扇区效率很低。现代的磁盘控制器都拥有高速缓存,每次读取多个扇区,并将其缓存。

错误处理

对于磁盘坏块的处理,可以在控制器或者在操作系统对他们进行处理。

在控制器中,处理的思想都是一样的,都是使用备用块来替代坏块。

而在操作系统级别进行处理,操作系统必须获的所有坏块列表,并将其进行重映射。

稳定存储器

保持磁盘的数据一致性。

  • 稳定写:对每个磁盘驱动器轮流进行重复写操作
  • 稳定读:如果有稳定写总是成功,并且一段时间内数据不会自己变坏的前提下,稳定写就总是成功的
  • 崩溃恢复:当写的过程中发生崩溃,后续恢复的原则
    • 两块都是好的且一样,什么也不做
    • 一块有ECC错误,则好的覆盖掉有ECC错误的
    • 两块都是好的但不一样,用第一块覆盖第二块

屏幕截图 2021-01-18 155800

时钟

时钟硬件

可编程时钟:石英晶体每次震荡会将递减计数器,计数器到0时会触发一个中断,软件可以自定义这个计数器来实现对时钟的编程。

屏幕截图 2021-01-18 160445

  • 一次完成模式:中断发生后等待软件显式启动
  • 方波模式:中断一次之后,又重新开始循环

时钟软件

  • 维护日时间

通过时钟来维护现在的时间,为了防止32位内存溢出,可以使用64位计数器,但代价过高。也可使用以秒为单位。

  • 防止进程超时运行

时钟的每次中断就将时间片-1,当时间片为0,就得重新调度程序。

  • 对CPU使用情况进行记账

每次滴答对进程表项的某个域+1来实现记录进程运行时间。

  • 处理alarm系统调用

进程可以请求操作系统在一定的时间间隔后向它报警。

一个物理时钟为了模拟出多个时钟,可以通过维护一张表,每次时间发生更新就查找是否达到表中所需要的时刻,如果达到了,就进行触发。然后继续重复这个步骤。

  • 为系统各部分提供监视定时器

检测死机之类的问题。如果操作系统可以定时清除计数器,当某个时刻计数器超过某个阈值,就可以确定已经死机了,此时软件介入处理。

  • 完成信息收集

软定时器

IO有两种方式:中断和轮询。

现代CPU的中断开销是很大的,但轮询的响应时间又会比较高。

所以为了达到一个取舍,可以使用一个软定时器定时中断来进行IO。

外设

输入软件

键盘软件

  • 原始模式:向用户提供原始的ASCII码序列
  • 加工模式:由键盘驱动处理全部行内编辑,将编辑结果存储在缓冲区回车后写入

鼠标软件

鼠标发送的消息包含:$\Delta$x $\Delta$y 按钮 ,通常为3字节

鼠标单击与双击则是由GUI来进行区分的

输出软件

  • 文本窗口

为了控制终端进行文字输出,程序使用了一种被称为“转义序列”的东西来控制终端。

  • X窗口系统
  • 图形用户界面
  • 位图
  • 字体
  • 触摸屏

瘦客户机

电源管理

有两种方法减少电量消耗:

  1. 关闭不用的某些计算机硬件
  2. 使应用程序耗能更低

硬件问题

  • 操作系统问题

    • 显示器
    • 硬盘
    • CPU
    • 内存
    • 无线通信
    • 热量管理
    • 电源管理
    • 驱动程序接口
  • 应用程序问题

results matching " "

No results matching " "

results matching " "

No results matching " "