操作系统 持久性
本文将介绍操作系统对持久性的支持。
一、I/O 设备
1. 系统架构
典型系统的架构如图:
- CPU 通过某种内存总线或互联电缆连接到系统内存
- 显卡或者其它高性能 I/O 设备通过常规的 I/O 总线连接到系统
- SCSI、SATA、USB 接口的设备通过外围 I/O 总线连接到系统
之所以这么做的原因是:考虑物理布局及造价成本。
首先,越快的总线越短,高性能的内存总线没有足够的空间连接太多设备;其次,高性能总线的造假非常贵。
因此,系统的设计采用分层架构,让要求高性能的设备离 CPU 更近,让要求较低的设备离 CPU 更远。
2. 标准设备及其接口
一个标准设备可以拆分如下:
硬件接口
- 状态寄存器:用于读取并查看设备的当前状态
- 命令寄存器:用于通知设备执行某个具体任务
- 数据寄存器:用于将数据传给设备或从设备读取数据
同软件一样,硬件也需要一些接口,让系统软件可以对它进行控制
内部接口
3. 交互 - 轮询
操作系统通知设备进行某项工作,并通过轮询的方式查询设备的处理状态,交互流程如下:
- 操作系统反复读取状态寄存器,直到设备处于可以接受命令的就绪状态
- 操作系统发送数据至数据寄存器
- 操作系统将命令写入命令寄存器
- 操作系统再次反复读取状态寄存器,直到设备执行完成命令
4. 交互 - 中断
通过中断这一机制,操作系统与设备交互时不再需要轮询,交互流程如下:
- 操作系统通知设备进行某项工作
- 操作系统让对应进程睡眠,切换进程进行其它任务
- 当设备完成工作后,会抛出一个硬件中断,硬件中断将引发 CPU 跳转执行操作系统预先定义好的中断处理程序,该程序将唤醒处于睡眠状态的进程
5. 中断和轮询的优劣
中断并非总是比轮询好。
如果设备的速度较快,使用轮询,通常几次轮询就可以返回结果;使用中断,线程切换、中断处理都需要消耗不少的代价。
如果设备的速度较慢,此时使用中断更好。
由于无法预知设备的速度,可以考虑使用混合策略,先尝试轮询一小段时间,若未完成再使用中断。
二、简单文件系统
1. 文件系统的组成
简单文件系统由两部分组成:
- 数据结构
- 访问方法
2. 数据结构
简单文件系统的数据结构主要包含以下几个部分:
- S:superblock;超级块,包含某些特定信息,例如文件系统类型、inode 表起始位置等
- i、d:inode 位图、数据位图;用于指示 inode、数据块是否空闲
- inodes:inode 表;用于存放每个文件的信息,包括文件放置于哪些数据块、文件大小、所有者、访问权限、修改时间等
- 数据区域:用于存放用户数据的区域
3. 访问方法
(1) 读取文件
打开文件:
接收 open 指令
查找文件的 inode,将其读入内存
由于文件、文件夹的数据结构是树形的,因此查找是逐层查找
在 inode 中读取文件的基本信息(权限信息、文件大小、数据块等)
文件状态标为已打开
读取文件:
- 接收 read 指令
- 从文件中读取
(2) 写入文件
打开文件:
同上
写入文件:
- 读取数据位图,获取未被使用的数据块
- 将数据块的新使用情况写入数据位图
- 将数据块的新信息写入 inode
- 将数据写入数据块
参考
- 操作系统导论