Chapter 8 设备管理
8.1 设备管理概念
设备:计算机中除了CPU和内存外其他设备一般统称为外部设备
设备分类:
- 按照交互对象分类:
- 人机交互设备,如显示设备、键盘、鼠标、打印机
- 与CPU等交互的设备:磁盘、磁带、传感器、控制器
- 计算机间的交互设备:网卡、调制解调器
- 按照交互方向分类
- 输入设备,如键盘、扫描仪
- 输出设备,如显示设备、打印机
- 双向设备:输入/输出,如硬盘、软盘、网卡
- 存储型设备:硬盘、软盘、光盘、U盘
- 按数据传输速率分类:
- 低速设备:一般速度在1KB/s以下的设备,如键盘
- 中速设备:1KB/s到1MB/s之间的设备,如打印机
- 高速设备,超过1MB/s的设备
- 按照信息组织特征分类
- 字符设备:传输的基本单位是字符,如键盘、串口
- 块设备:设备存储和传输的基本单位,基本是存储型设备
- 网络设备:采用socket套接字接口访问,在全局具有唯一的名字,如eth0
设备管理的功能
设备管理的目标:
- 提高设备的利用率
- 提高设备的读写效率
- 提高CPU与设备并行速度
- 为用户提供统一接口
- 实现设备对用户透明
设备管理功能
- 状态跟踪
- 设备分配
- 设备映射
- 设备控制/设备驱动
- 缓冲区管理
设备控制块(DCB)
记录设备的基本属性、状态、操作接口以及进程与设备之间的交互信息等。包含设备名、设备属性、命令转换表(记录设备相关的I/O函数例程地址,不具备相应功能的设备在其例程地址上可以填-1)等。
设备分配
需要按照一定策略安全地分配和管理各种设备。
- 按照相应分配算法把设备分配给请求该设备的进程,并把未分配到设备的进程放入设备等待队列。
设备映射
设备具有一个逻辑名,用户可以为设备起一个友好名便于使用。
在Windows上通过加前缀\.\可访问设备,在Linux上所有设备均处于/dev/文件夹中,通过访问文件的方式访问设备即可。
设备物理名是I/O系统中实际安装的设备,可以为ID或字符串或主/次设备号。设备映射就是逻辑设备到物理设备的转换。用户使用逻辑设备的统一接口去访问设备,而无需考虑物理设备复杂的内部构成。
设备驱动
- 对物理设备进行控制,实现I/O操作
- 将应用服务请求转换为I/O指令
- 向用户提供统一的设备使用接口,将外设作为特别文件处理
设备驱动程序的特点:
- 介于应用程序与设备I/O操作命令之间
- 设备驱动程序与硬件密切相关
- 每一类设备都要配置特定的驱动程序
- 驱动程序一般由设备厂商根据操作系统要求编写
I/O缓冲区管理
设备可以开辟和管理I/O缓冲区,可以提高读写效率。
8.2 缓冲技术
缓冲区的作用:
- 连接不同传输速度的设备。一般情况下CPU的处理速度比设备快很多,在进程空间和设备存储空间之间添加一块内存作为缓冲区将二者进行连接。
- 协调数据记录大小的不一致,如果两个设备或设备与CPU之间记录的大小不一致,则可以通过添加缓冲区暂存避免丢失较大的数据记录。如网络消息的包和帧。
- 正确执行应用程序的语义拷贝。如写入时能够保证写入的数据是调用时刻的数据。如果没有缓冲区,应用程序等待内核写完之后再返回,速度可能比较慢,实时性差。因此加入缓冲区,首先将数据写到缓冲区之后,进程立即返回,不影响进程的执行,之后才由内核将缓冲区写入到磁盘,这能够确保事后拷贝的数据是正确版本。
- 提高CPU和外设之间的并发性。提高并行程度、吞吐量和设备的利用率。
四种缓冲形式
- Cache高速缓冲存储器
- 设备内部缓冲区(外部设备或I/O接口内部的缓冲区)
- 内存缓冲区(内存开辟,应用广泛,使用灵活,可以提前读/延后写)
- 辅存缓冲区(开辟在辅存上)
常用的缓冲技术
- 单缓冲(一个缓冲区,读和写互斥)
- 双缓冲(两个缓冲区)
- 环形缓冲(多个缓冲区,让首尾两个单元在逻辑上相连,有起始指针pStart、输入指针pWrite和输出指针pRead)
- 缓冲池(多个缓冲区,可供多个进程共享,提高缓冲区的利用率减少内存浪费)
提前读和延后写技术
- 该技术针对磁盘类的块设备
- 可以提高进程与设备之间的数据传输效率
- 可以减少访问目标设备次数,提高设备访问的效率
提前读:进程需要从外设读取的数据事先已经被读取到了缓冲区中(需要读取几个字节时将一整块数据全部读取),不需要继续启动外设执行读取操作。
延后写:进程需要向外设写入数据,缓冲区首先将这些数据缓存起来,延迟到特定事件发生或足够时间后再启动外设,完成数据真正写入,即几次写入一次完成。
Linux缓冲机制
- 设置内存高速缓冲区
- 高速缓冲区被划分为缓冲块。每一个缓冲块与一个磁盘块对应,每一个缓冲块用一个叫缓冲头buffer_head的结构体描述,其中包含数据区指针、块号、设备号等
- 缓冲块中保存最近访问磁盘的数据
8.3 设备分配
设备分配被分为独享设备、共享设备和虚拟设备。
- 独享设备:不可抢占设备,每一次只供一个进程使用,如键盘、打印机等
- 共享设备:可抢占设备,允许多个作业或进行同时使用,如存储设备,随时申请随时可得
- 虚拟设备:借助虚拟技术,在共享设备上模拟独占设备
设备分配方法:
- 独享分配,进程使用设备前首先申请,申请成功后开始使用,直到使用完之后释放。如果设备已经被占用,则进程会被阻塞。
- 共享分配,进程申请使用共享设备时操作系统能够立即分配共享设备的一块空间,不会让进程阻塞。共享分配使得进程使用设备十分简单和高效,随时申请,随时可得。
- 虚拟分配,在一类物理设备上模拟另一类物理设备的技术,通常借助辅存部分区域模拟独占设备,将独占设备转化为共享设备。用来模拟独占设备的辅存区域称为虚拟设备,其中有输入井和输出井模拟输入输出设备的辅存区域。
虚拟分配过程:
- 当进程需要与独占设备交换信息时,采用虚拟技术将与该独占设备所对应的虚拟设备分配给它。首先采用共享分配为进程分配虚拟独占设备,然后将虚拟设备与指定的独占设备关联。
- 进程运行过程中直接与虚拟设备进行交互,传输速度快。
SPOOLing系统(Simultaneous Peripheral Operations Online)
- 是虚拟技术和虚拟分配的实现
- 外部设备同时联机操作
- 假脱机输入/输出
输入井和输出井是磁盘上开辟的两个存储区域。输入缓冲区是内存中开辟的存储区域。输入缓冲区暂存到输入数据,再传送到输入井;输出缓冲区暂存输出数据,以后再传送到输出设备。
软件有:
-
预输入程序,控制信息从独占设备输入到辅存
-
预输入表,从哪一台设备输入,存放在输入井的位置
-
缓输出程序,控制信息从辅存输出到独占设备
-
缓输出表,输出信息在输出井的位置,从哪台设备输出
-
井管理程序,控制用户程序和辅存之间的信息交换
-
预输入进程,模拟脱机输入的卫星机,将用户要求的数据从输入设备通过输入缓冲区传送输入井,当用户进程需要数据时直接从输入井读入所需数据。
-
缓输出进程模拟脱机输出的卫星机,用户进程将输出数据从内存先传送到输出井,当输出设备空闲时将输出井的内容输出到输出设备中。
-
任务执行前,预先将程序和数据输入到输入井中
-
任务运行时,使用数据时从输入井中取出
-
任务运行时,输出数据时将数据写入输出井
-
任务运行完,外设空闲时输出全部数据和信息
SPOOLing优点:
提高了I/O速度,将独占设备改造为了共享设备(实现了虚拟设备功能)
8.4 I/O控制
无条件传送方式
工作过程:
- 进程I/O时无需查询外设状态,直接进行。
- 主要用于外设时钟固定且已知的场合。
- 当程序执行I/O指令时,外设必定已经为传送数据做好了准备。
查询方式
- 在传送数据之前,CPU先对外设状态进行检测,知道外设准备好才开始传输,否则将一直检测等待。
- I/O操作由程序发起并等待完成,每一次读写必须通过CPU。
中断方式
- 外设数据准备好或准备好接收时,产生中断信号
- CPU收到中断信号之后,停止当前工作,处理该中断,完成数据传输
- CPU处理完成后继续原来的工作
- 缺点是降低CPU效率,适合少量数据低速传输
通道方式
- 通道是用来控制外设和内存数据传输的专门部件
- 通道有独立的指令系统,既能够受控于CPU又能独立于CPU
- I/O处理机
DMA(直接内存访问)方式
- Direct Memory Access
- 外设和内存之间直接进行数据交换,不需要CPU干预。
- 只有数据传送开始(初始化)和结束时(反初始化)需要CPU参与,传输过程不需要CPU参与。
- DMA控制器:DMAC,可以代替CPU控制内存和设备之间成块的数据交换,在微机中广泛采用。
- 局限性:不能完全脱离CPU(传送方向、内存地址、数据长度由CPU控制),每一台设备需要一个DMAC(设备较多时不经济)
I/O控制特点
- 在应用层为用户提供I/O接口,对设备的控制和操作则由内核I/O子系统来实施
- 每个通用设备类型都通过一组标准函数(及接口)来访问。具体的差别被I/O子系统中的内核模块(内核驱动程序)所封装,设备驱动程序层的作用是为内核I/O子系统隐藏设备控制器之间的差异,将I/O子系统与硬件分离,简化了操作系统开发人员的任务,也有利于设备的设计和制造。
控制I/O核心模块的方式
- 以设备驱动进程的方式
- 为每一类设备设置一个设备驱动进程,当有I/O请求到来时该进程被唤醒进行设备驱动工作。当没有I/O请求时该进程睡眠,否则由I/O控制模块的接口程序负责解释用户的I/O系统调用,将其转换为I/O控制模块认识的命令形式后将I/O请求发送给对应的设备驱动进程。
- 将设备与文件一样对待
- 使用文件系统的系统调用命令进行设备的读写。
8.5 设备驱动程序
8.5.1 Linux模块
LKM:可加载的内核模块,是一种未经连接的可执行代码,可以动态地加载或卸载模块,经过连接可称为内核的一部分。设备驱动可以通过模块的方式添加到内核。
Linux设备的分类:
- 字符设备:
- 以字节为单位进行I/O操作
- 字符设备中的缓存是否可有可无
- 不支持随机访问
- 如串口设备
- 块设备
- 存取通过buffer、cache进行
- 可以进行随机访问
- 如IDE硬盘设备
- 支持可安装文件系统
- 网络设备
- 通过BSD套接口访问(SOCKET)
用户态和内核态
- Linux的两种运行方式:内核态、用户态
- 驱动程序工作在内核态
- 应用程序和驱动程序之间传送数据函数:
- get_user
- put_user
- copy_from_user
- copy_to_user
主设备号和次设备号
- 主设备号:表示设备种类,表示驱动程序,范围为1-255,支持动态分配主设备号
- 次设备号:标识同一个设备驱动程序的不同硬件设备