一、I/O系统模型、接口和功能
计算机中三个最基本的物质基础是CPU、内存和 I/O 设备
CPU的管理实际上是对进程的管理,进程的执行涉及到内存管理,进程执行的过程需要输入输出数据,涉及到文件系统和设备管理,与I/O设备相比,文件系统是一种逻辑意义上的存在,使对设备的操作更为方便、有效、更有组织(open、write、read),文件操作是对设备操作的组织和抽象,设备操作则是对文件操作的最终实现
I/O系统是操作系统中最具多样性和复杂性的部分,OS大部分代码专门用于I/O管理
通过CPU向外设发出指令,CPU转身执行其他进程(外设运行速度慢),外设控制器控制外设完成输入输出,当外设完成输入输出后,向CPU发出中断请求,这时CPU执行中断处理程序,将数据从外存读入内存
OS让外设工作有三件事:
系统调用是以文件系统的接口提供给用户的,Unix/Linux类操作系统为了方便管理,把所有的设备都看成文件,给每个设备对应一个文件名,因此对设备和文件提供统一的接口
在Unix/Linux系统中,把设备也当做文件来看待,设备与文件系统的系统调用接口是一致的,CPU通过out指令将控制命令送到控制器来启动外设工作,相应的控制器对命令字进行解释,形成相应的控制信息控制外设进行工作,等完成相应操作后就做中断操作处理
I/O系统可划分为三个层次:
定义:对块设备来说,数据的存取和传输是以数据块为单位,块设备接口是块设备管理程序与高层间的接口,其反映了大部分磁盘存储器和光盘存储器的本质特征,用于控制块设备的输入和输出,磁盘设备的I/O常采用DMA(直接存储访问)方式
I/O命令:read/write
定义:对流设备来说,数据的存取和传输是以字符为单位,流设备接口是流设备管理程序与高层间的接口,反映了大部分字符设备的本质特征,用于字符设备的输入和输出,基本特征是传输速率低、不可寻址、常采用中断处理方式
I/O命令:get/put
定义:OS提供相应的网络软件和网络通信接口
I/O命令:send/receive
I/O系统的主要管理对象是I/O设备和相应的设备控制器,其最主要的任务是:
设备管理的功能:
按速率分类:低速(键盘、显示器等)、中速(激光打印机)、高速设备(磁盘)
按信息交换单位分类:块设备、字符设备
按设备的共享属性:独占设备、共享设备(可寻址、可随机访问)、虚拟设备(通过虚拟技术将一台独占设备改造为若干台供多个用户使用的逻辑设备,SPOOLing技术)
I/O设备通过接口与控制器相连,再由控制器与总线相连
设备控制器由如下三部分组成:
设备控制器主要职责是控制一个或多个I/O设备,以实现I/O设备和计算机之间的数据交换,是CPU与I/O设备之间的接口,接收从CPU发来的命令,控制I/O设备工作,基本功能如下:
控制寄存器、数据寄存器、状态寄存器位于控制器内,从编址方式来说:
I/O设备的寻址方式就是I/O端口的编号方式:
Linux内核访问I/O内存的函数:ioremap(将外设卡上的存储器映射到内存空间,虚拟空间)、inb(port参数指定I/O端口空间的端口地址)等,端口地址的类型是由I/O端口空间的大小来决定的,可以通过访问proc下的ioports来获取设备当前的端口号
设备控制器可以大大减少CPU对I/O的干预,但主机配置外设很多时,CPU负担仍然很重,因此在CPU和设备控制器之间又增设了通道
通道类型:
通道“瓶颈”问题:通道价格昂贵,致使机器中设置的通道数量较小,进而造成整个系统吞吐量的下降
解决方案:增加设备到主机间的通路,把一个设备连接到多个控制器上,而一个控制器上又连接多个通道
设备驱动程序是I/O系统的高层与设备控制器之间的通信程序,其主要任务是接收上层软件发来的抽象要求,如read或write命令,文件系统把这些请求转化为具体的要求后,发送给设备控制器,启动设备去执行;反之,也将设备控制器发来的信号传送给上层软件
设备驱动程序应具备以下功能:
三类处理方式:
不同类型的设备应有不同的设备驱动程序,大体分为两部分,第一部分,能够驱动I/O设备工作的驱动程序,第二部分,设备中断处理程序,以下是设备驱动程序的处理过程:
4.1 程序直接控制方式
由于CPU速度远远快于I/O设备,CPU需要不断的检测I/O设备,CPU利用率相当低,绝大部分时间都在测试设备是否已经完成数据的传输
中断硬件支持,CPU与I/O设备可以并行工作,但存在问题是每输入输出一个字节都要求中断,中断次数太多,不适用于高速设备
与中断驱动方式相比,DMA方式有了以下几个改进:
DMA控制器由三部分组成:
内存地址寄存器MAR:在设备内存输入数据,MAR表示输入数据应该存放在设备位置;在内存输出数据给二手设备 |
---|
命令寄存器CR:用于存放CPU发送来的命令或设备状态信息
进一步减少CPU对I/O操作的干预,通道控制方式也是一种一内存为中心,实现设备与内存直接数据交换的控制方式,与DMA方式相比,CPU对I/O操作的干预更少,只有完成这一组数据块的读或者是写之后,才需要发出中断信号,请求CPU干预,而且可以做到一个通道控制多台设备
通道本质是一个简单的处理器,有自己的指令系统(数据传送指令、设备控制指令等),通过执行通道程序来控制I/O操作。
以数据输入为例,当用户进程需要输入数据时,CPU发出启动指令,指明要执行的I/O操作所使用的设备和通道,当对应通道接收到CPU发来的启动指令后,把存放在内存中的通道程序读出,并执行通道程序,控制设备将数据传送到内存中指定的区域,在设备进行输入时,CPU可以做其他事情;当数据传送结束后,设备控制器向CPU发送一个中断请求,CPU收到中断信号后转去执行中断处理程序,之后返回被中断的程序
字符设备是指只能一个字节一个字节进行读写操作的设备,字符设备是面向流的设备(鼠标、键盘、串口、控制台等),一般每个字符设备或者块设备都会在/dev目录下对应一个设备文件,Linux用户层程序通过设备文件来使用驱动程序操作字符设备或者块设备
sudo mknod /dev/mycdev c 231 0
该命令第一个参数为设备文件名,第二个参数为设备类型,三四个参数为设备文件的主设备号和次设备号,同一个设备不同类型的主设备号是一样的,次设备号不同(一个硬盘的多个分区,只需要一个驱动程序)Linux内核中使用cdev结构体描述字符设备,cdev定义于<linux/cdev.h>中,在Linux内核中
cdev结构体:dev定义设备号,以确定字符设备的唯一性;file_operation来定义字符设备驱动,提供给虚拟文件系统的接口
struct cdev {
struct kobject kobj; //内嵌内核对象
struct module *owner; //该字符设备所在的内核模块
const struct file_operations *ops;//文件操作结构体
struct list_head list;//已注册字符设备链表
dev_t dev; //由主、次设备号构成的设备号
unsigned int count;//同一主设备号的次设备号的个数
};
AI写代码c运行12345678
文件操作集file_operation结构:
file_operation数据结构位于fs.h中,每一个字段都对应一个系统调用,是一个指向函数的指针,对其实现就是驱动程序要做的工作(如read、write、mmap、open等)
字符设备驱动程序是以内核模块的形式加载到内核中
① 驱动初始化 ②实现设备操作 ③驱动注销
序号 | 函数名 | 功能 |
---|---|---|
1 | cdev_alloc() | 动态申请(构造)cdev内存(设备对象) |
2 | cdev_init() | 初始化cdev的成员,并建立起cdev和file_operations之间的关联 |
3 | cdev_add() | 注册cdev设备对象,添加到系统字符设备列表 |
4 | cdev_del() | 将cdev对象从系统中移除(注销) |
5 | cdev_put() | 释放cdev内存 |
宏或者函数名 | 功能 |
---|---|
MAJOR宏 | 从设备号中提取主设备号 |
MINOR宏 | 从设备号中提取次设备号 |
MKDEV宏 | 将主次设备号拼凑成设备号 |
register_chrdev_region()函数 | 静态申请设备号 |
alloc_chrdev_region() | 动态申请设备号 |
unregister_chrdev_region() | 释放设备号 |
调用函数时,如read()函数,要陷入内核空间,通过内核的copy_to_user()函数将内核空间缓冲区中的数据拷贝到用户空间的缓冲区
调用write函数时,内核调用copy_from_user()函数将用户空间的缓冲区中的数据拷贝到内核空间缓冲区
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。