wywwzjj's Blog

CSAPP 系统级 IO 笔记

字数统计: 3.3k阅读时长: 11 min
2019/11/25 Share

Unix I/O

所有的 I/O 设备(例如网络、磁盘和终端)都被模型化为文件,而所有的输入和输出都被当作相应文件的读和写来执行。这种将设备优雅地映射为文件的方式,允许 Linux 内核引出一个简单、低级的应用接口,称为 Unix I/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行。

文件

硬盘 => chs => 盘块 => 文件

文件:建立字符流(序列)到盘块集合的映射关系,由操作系统维护这个映射关系。

FCB 以块号为单位,会不会太大,比如单个位的编辑?

inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。

目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。

文件系统:一种用于持久性存储的系统抽象。

文件:文件系统中一个单元的相关数据在操作系统中的抽象。

文件系统提供了按名存取功能,使用户能透明地访问文件。

文件分类:

  • 目录文件:用于保存文件目录的文件
  • 普通文件
  • 设备文件

这里引出了交换区和文件区。

文件区主要用于存放文件,追求存储空间的利用率,因此对文件区空间的管理采用离散分配方式;

交换区只占磁盘空间的小部分,被换出的进程数据就存放在这里,追求换入换出的速度,因此对交换区采用连续分配方式。

虚拟文件系统

image.png

目的:对所有不同文件系统的抽象

文件系统主要功能:

  • 文件的按名存取
  • 文件目录的建立和维护
  • 文件的组织
  • 文件存储空间的管理
  • 提供各种操作文件的方法

逻辑结构

流式文件

有序的字符流,内部无结构划分

记录式文件

文件内的数据被划分为具有逻辑完整性的单元,每个单元称作一条记录,每条记录可以包含若干个数据项。(CSV

物理结构

连续

  • 为文件分配的必须是连续的盘块
  • 顺序存取速度快,可以随机访问
  • 会产生碎片,不利于文件扩展

链接

  • 用链表的形式把盘块串起来
  • 可以解决碎片问题,外存利用率高,扩展性高
  • 只能顺序访问,不能随机访问

索引

  • 为文件数据块建立索引表,非连续存储分配,提高了空间的利用率
  • 支持随机访问,易扩展
  • 索引表本身占空间,访问数据块前需要读取索引块,增加了检索的开销

目录

文件系统通过文件的物理结构和目录文件实现按名存取功能。

FCB

描述信息

  • 文件名
  • 文件的逻辑结构信息
  • 文件的物理结构信息

管理信息

  • 存取控制信息,包括读、写、执行
  • 使用信息,包括创建、修改、访问文件的时间

inode

包含文件的元信息(无文件的名称):

  • 文件字节数
  • 文件拥有者的 User ID
  • 文件的 Group id
  • 文件的读、写、执行权限
  • 文件的时间戳:ctime 指 inode 上一次变动的时间,mtime 指文件内容上一次变动的时间,atime指文件上次被打开的时间
  • 链接数,即有多少文件名只想这个 inode
  • 文件数据 block 的位置

每个inode都有一个号码,操作系统用inode号码来识别不同的文件,系统内部不使用文件名。

对于系统来说,文件名只是inode号码便于识别的别称或者绰号。

表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。

目录结构

文件存储空间管理

主要就是空闲区管理

成组链接法

结构

分配、回收算法

空闲表法

空闲链表法

空闲盘块链

空闲盘区链

位示图法

共享

类型

  • 基于索引结点(硬链接)

    计数器为0才真正删除文件

  • 基于符号链(软链接)

共享方法

  • 绕道法
  • 链接法
  • 基本文件目录法

保护采用保护键法。

安全性

文件保护

  • 口令保护

  • 加密保护

  • 访问控制

    用一个访问控制表(ACL)记录各个用户(或各组用户)对文件的访问权限

保密安全策略分为 MAC(强制访问策略,安全性更高)、DAC(自主访问策略,更加灵活)

设备管理

主机对设备的访问表现为使用基本的端口通讯指令(in、out)与这组 IO 地址通讯。

设备相关层

  • 设备驱动程序
  • 中断处理程序

设备无关层

设备独立性:操作系统提供了物理设备到逻辑设备的抽象,用户或程序中使用的设备与具体的设备无关,不再需要关注设备的细节,方便用户使用。

I/O 控制

CPU 无法直接控制I/O设备的机械部件,因此I/O设备还要有一个电子部件作为 CPU 和 I/O 设备机械部件之间的“中介”,用于实现 CPU 对设备的控制。这个电子部件就是 I/O 控制器,又称设备控制器,CPU 可控制 I/O 控制器,又由 I/O 控制器来控制设备的机械部件。

I/O 控制器功能点:

  • 接受和识别CPU发出的指令(要有控制寄存器)
  • 向CPU报告设备的状态(要有状态寄存器)
  • 数据交换(要有数据寄存器,暂存输入、输出的数据)
  • 地址识别(由I/O逻辑实现)

两种寄存器编制方式

  • 内存映射
    • 控制器中的寄存器与内存统一控制
    • 可以采用对内存进行操作的指令对控制器进行操作
  • 寄存器独立编制
    • 需要专门的指令来操作控制器

目标:减少 CPU 等待时间、减轻 CPU 负担、提高系统并行性

程序查询

进程提出 IO 请求并获得设备后,IO 子程序将不断循环检测设备的状态,直到设备能够满足 IO 操作的要求时实施传输动作。

设备《=》CPU《=》内存

中断

与异常的关系?

1.进程提出 IO 请求并获得设备后,若设备未就绪,则阻塞进程。

2.当设备进入就绪状态时,发出中断信号,已在系统中注册的中断处理函数唤醒进程以启动一个传输动作,而后再阻塞进程直到设备再次就绪。

设备《=》CPU《=》内存

DMA

1.进程提出 IO 请求并获得设备后,将数据(或接收缓冲区)安置在内存中的位置和大小写入 DMA 控制器的寄存器内,启动 DMA 过程并阻塞进程。

2.DMA 控制器控制指定内存区域同设备之间的数据交换。其间需要使用总线时,总线控制权将供DMA使用(硬件机制)。

3.当原进程请求的IO操作全部完成时,DMA 控制器发出中断,中断处理程序唤醒进程。

DMA 中两个主要寄存器:

  • 基址寄存器,指示当前读或写的内存地址
  • 计数寄存器,表示传输数据的字节数

数据的传送单位是“块”。

设备《=》内存

通道

在DMA方式的基础上,通道方式中使用通道处理器替代DMA控制器来实施传输动作。

通道处理器是一个简单的专用处理器,具有自身的指令系统,可按程序完成传输动作。这使得通道处理器较只能进行单纯传输动作的DMA控制器具有更强大的功能,例如传输纠错、数据格式转换、数据预处理 等。

对于系统中的每一个通道,内存中有两个固定的专用存储单元分别存储通道程序的首地址(CAW通道地址字)和状态信息(CSW通道状态字)。

数据的传送单位是“一组数据块”

通道方式的运作过程:

➢ 进程提出IO请求并获得设备后,根据所要求的IO操作,生成由通道指令组成的通道程序,并将程序首地址写入CAW中。然后启动通道并阻塞进程。

➢ 通道处理器从CAW中找到通道程序,并按通道程序的指令完成数据传输过程。每条指令执行之后都将通道状态写入CSW中,使得主机能够随时掌握通道运行情况。

➢ 若通道程序执行中出现错误,通道处理器将发出错误中断,交由中断处理程序处理错误;若通道程序顺利执行完毕也将发出完成中断,由中断处理程序唤醒原进程。

I/O 缓冲

缓冲技术一般应用于两种速度不一致的部件之间的协作。一般形式是以缓冲区来暂时存放需要交换的信息。

  • 保证正确性:避免部件间速度不一致造成的信息缺失
  • 缓解 CPU 与设备的速度矛盾
  • 减少对 CPU 的中断频率
  • 解决数据粒度不匹配问题
  • 提高 CPU 与 I/O 设备之间的并行性

使用缓冲技术的输出(Write)的一般过程:

  1. 用户提出Write请求后,缓冲管理模块检查进程是否已取得相应的输出缓冲区,若已取得,则使用此缓冲区,否则申请一个空缓冲区,将其更改为该进程对该设备的输出缓冲区(可能阻塞原进程)。
  2. 缓冲管理模块使用访存指令将数据写入缓冲区内。
  3. 其间若达到一定的缓冲条件,则缓冲管理模块启动上层驱动程序,将整个缓冲区内的数据写入设备(冲洗,可能阻塞原进程),之后再继续步骤2,直到数据写入完成。

使用缓冲技术的输入(Read)的一般过程:

  1. 用户提出Read请求后,缓冲管理模块检查进程是否已取得相应的输入缓冲区,若已取得,则使用此缓冲区,否则申请一个空缓冲区,将其更改为该进程对该设备的输入缓冲区(可能阻塞原进程)。
  2. 缓冲管理模块使用访存指令从缓冲区内读出数据。
  3. 其间若缓冲区为空,则缓冲管理模块启动上层驱动程序,从设备读出数据到缓冲区(可能阻塞原进程),直至达到一定的缓冲条件后再继续步骤2,直到数据读出完成。

磁盘

一次磁盘读/写操作需要的时间 = 寻道时间(大头) + 旋转延迟时间 + 传输时间

减少延迟时间方法:

  • 交替编号
  • 错位命名
  • 磁盘地址结构的设计

驱动调度:

  • 移臂调度
  • 旋转调度

调度算法:

  • 先来先服务(FCFS)

  • 最短寻找时间优先(SSTF)

    优先调度附近磁道。磁头在一个小区域内来来回回移动,可能产生饥饿

  • 扫描算法(SCAN)

    为了杜绝上面的饥饿现象,加了点限定,只有磁头移动到最外侧了才能调头

  • 电梯算法

    再扫描算法上又加了点限定,不用完全到磁道尽头,一旦反方向有请求,可直接响应

  • 循环扫描算法(C-SCAN)

    从内到外,依次响应距离磁头最近的操作,到最外层柱面后立即回到最内柱面,继续之前的操作

存储空间管理数据结构:

  • 位示图
  • 空闲块表
  • 空闲块链表

磁盘管理:

  • 磁盘初始化
  • 引导块
  • 坏块的管理

I/O 重定向

标准 I/O

创建进程时,会打开三个文件,其文件描述符为 0、1、2,分别表示标准输入、标准输出以及标准错误流。

CATALOG
  1. 1. Unix I/O
  2. 2. 文件
    1. 2.1. 虚拟文件系统
  3. 3. 逻辑结构
    1. 3.1. 流式文件
    2. 3.2. 记录式文件
  4. 4. 物理结构
    1. 4.1. 连续
    2. 4.2. 链接
    3. 4.3. 索引
  5. 5. 目录
    1. 5.1. FCB
    2. 5.2. inode
    3. 5.3. 目录结构
  6. 6. 文件存储空间管理
    1. 6.1. 成组链接法
    2. 6.2. 空闲表法
    3. 6.3. 空闲链表法
    4. 6.4. 位示图法
  7. 7. 共享
  8. 8. 安全性
  9. 9. 设备管理
  10. 10. I/O 控制
    1. 10.1. 程序查询
    2. 10.2. 中断
    3. 10.3. DMA
    4. 10.4. 通道
  11. 11. I/O 缓冲
  12. 12. 磁盘
  13. 13. I/O 重定向
  14. 14. 标准 I/O