6.5 与设备无关的I/O软件

L37

学习目标

流式/记录式;单级/树形目录;路径名解析。

  • 目录是特殊文件。
  • 绝对/相对路径。
  • 磁盘柱面磁道扇区。
  • Flash 需磨损均衡(概念)。
  • 按名访问、持久性。
  • 教学可选 RAMFS 后续扩展。
  • RAMFS 的数据在 SRAM 里,掉电就没了;适合日志、配置草稿,不适合当唯一的长期仓库。
  • 最小接口通常是 create、open/close、read/write、list;下面是文件控制块和一块连续或分块的内存池。

原理 · 深入理解

6.5 与设备无关的I/O软件

本节概览:先建立「与设备无关的I/O软件」的框架,再依次展开下列小节。

  1. 与设备无关(Device Independence)软件的基本概念
  2. 与设备无关的软件
  3. 设备分配
  4. 逻辑设备名到物理设备名映射的实现

6.5.1 与设备无关(Device Independence)软件的基本概念

为实现与设备的无关性而引入了逻辑设备和物理设备两个概念。逻辑设备是抽象的设备名。

如果在应用程序中使用逻辑设备名称请求使用某类设备,系统进行设备分配时只要有一台尚未分配,进程就不会被阻塞。

在应用程序中用逻辑设备名称使用设备虽然方便了用户,但系统只识别物理设备名称,实际执行时还必须使用物理名称。因此系统中必须具有将逻辑设备名称转换为某物理设备名称的功能。

与设备无关软件还可实现I/O重定向:用于I/O操作的设备可以更换(即重定向),而不必改变应用程序。

在早期OS中,应用程序使用I/O设备时都使用设备的物理名称,使应用程序与系统中的物理设备直接相关。

当应用进程运行时,如果所请求的物理设备(独占设备类型)已分配给其他进程,即使还有几台相同的设备空闲可用,系统也只能根据物理名分配,无法将另外相同的设备(但具有不同物理设备名)分配给它。

6.5.2 与设备无关的软件

系统中有两类设备:独占设备和共享设备。对于独占设备,为避免各进程争夺,必须由系统统一分配,不允许进程自行使用。

每当进程需要使用某独占设备时必须先提出申请。OS接到请求后先检查所请求的独占设备是否空闲,若空闲才把该设备分配给请求进程。

不同类型的设备数据交换单位不同,读取和传输速率也各不相同;即使同一类型设备,数据交换单位大小也有差异。设备独立性软件应能隐藏这些差异,向高层软件提供大小统一的逻辑数据块。

无论是字符设备还是块设备,运行速度都远低于CPU速度。为缓和CPU和I/O设备之间的矛盾、提高CPU利用率,现代OS都分别为字符设备和块设备配置了相应的缓冲区。

缓冲区有多种形式,如单缓冲区、双缓冲区、循环缓冲区、公用缓冲池等,以满足不同情况的需要。

由于设备中有很多机械和电气部分,比主机更容易出现故障,因此I/O操作中的绝大多数错误都与设备有关。可分为如下两类。

  1. 暂时性错误:因发生暂时性事件引起,可通过重试操作纠正
  2. 持久性错误:由持久性故障引起

为使所有设备驱动程序有统一接口,一方面要求每个设备驱动程序与OS之间有相同或相近的接口;另一方面要将抽象设备名映射到适当的驱动程序上(将抽象设备名转换为具体物理设备名)并进一步找到相应物理设备的驱动程序入口;此外还应对设备进行保护,禁止用户直接访问设备,防止无权访问的用户使用。

图6-16 与设备无关软件的功能层次 统一命名 / 保护 块大小无关 缓冲 · 分配
图6-16 与设备无关软件的功能层次

6.5.3 设备分配

用于设备分配的数据结构记录了对设备或控制器进行控制所需的信息。系统为每一个设备都配置了一张设备控制表(DCT),用于记录设备情况。

设备控制表中除了设备类型字段type和设备标识字段deviceid外,还应包含如下字段。

  1. 设备队列队首指针
  2. 忙/闲标志
  3. 与设备连接的控制器表指针
  4. 重复执行次数
图6-17 设备控制表 设备名 状态 队列 tty P2 disk0
图6-17 设备控制表

系统在分配设备时应考虑如下几个因素。设备的固有属性可分成三种,对它们应采取不同的分配策略。

对设备分配的算法通常只采用以下两种。

  1. 独占设备的分配策略
  2. 共享设备的分配策略
  3. 虚拟设备的分配策略(虚拟设备属于可共享设备,可同时分配给多个进程使用)
  4. 先来先服务
  5. 优先级高者优先

设备的固有属性

设备分配算法

图6-18 COCT、CHCT和SDT表 COCT CHCT SDT 控制器表、通道表、系统设备表
图6-18 COCT、CHCT和SDT表

当某进程提出I/O请求后,系统的设备分配程序可按下述步骤进行设备分配。

  1. 分配设备
  2. 分配控制器
  3. 分配通道

基本的设备分配程序

设备分配程序的改进:为获得设备的独立性,进程应使用逻辑设备名请求I/O。系统首先从SDT中找出第一个该类设备的DCT,若该设备忙又查找第二个该类设备的DCT,仅当所有该类设备都忙时才把进程挂在该类设备的等待队列上。只要有一个该类设备可用,系统便进一步计算分配该设备的安全性,如安全便可把设备分配给它。

从进程运行的安全性上考虑,设备分配有以下两种方式。

  1. 安全分配方式:每当进程发出I/O请求后便进入阻塞状态,直到I/O操作完成时才被唤醒
  2. 不安全分配方式:进程发出I/O请求后仍继续运行,需要时又发出第二个、第三个I/O请求等,仅当所请求设备已被另一进程占用时才进入阻塞状态

设备分配中的安全性

控制器控制表、通道控制表和系统设备表。

  1. 通道控制表(CHCT):每个通道都有一张通道控制表
  2. 控制器控制表(COCT):系统为每一个控制器都设置了用于记录控制器情况的控制器控制表
  3. 系统设备表(SDT):系统范围的数据结构,记录系统中全部设备的情况,每个设备占一个表目,包括设备类型、设备标识符、设备控制表及设备驱动程序的入口等项

6.5.4 逻辑设备名到物理设备名映射的实现

逻辑设备表LUT(Logical Unit Table)用于实现逻辑设备名到物理设备名的映射。

图6-19 逻辑设备表 逻辑名 物理设备 lpr printer0 disk sda
图6-19 逻辑设备表

逻辑设备表的每个表目中包含三项:逻辑设备名、物理设备名和设备驱动程序的入口地址。

在系统中可采取两种方式设置逻辑设备表。

  1. 第一种方式:在整个系统中只设置一张LUT
  2. 第二种方式:为每个用户设置一张LUT

做 · 交互动画

  • 根据「学习目标」列出 3 个关键词,对照原理段落解释给自己听。
  • 写出 RAMFS 的最小 API 列表与数据结构草图。

与设备无关的I/O软件

fs-overview

用控件单步操作;日志区记下每一步发生了什么。

总结与提升

  • 能解释路径名解析步骤。
  • 能用自己的话复述学习目标,并指出概念与板上实验的对应。
  • 能指出 Flash 与磁盘的一个关键差异。
  • 能说出文件相对「裸扇区」的好处。
  • 设计稿含 create/read/write/list。
  • 能说明双缓冲的好处。
  • 能区分 moduleName 与 serviceName。

延伸思考

  • 扁平「对象键值存储」算目录吗?
  • 如果把本节机制拿到 Linux 或完整 OpenHarmony 上,会多出哪些硬件假设?
  • 小文件用连续分配的问题?
  • 配置参数用文件还是 Kconfig?

← 本阶段封面 · 课程列表