操作系统中的设备管理,Linux下的I/O

news2025/6/7 2:10:00

1. I/O软件分层

I/O 层次结构分为五层:

  • 用户层 I/O 软件
  • 设备独立性软件
  • 设备驱动程序
  • 中断处理程序
  • 硬件

   

        其中,设备独立性软件、设备驱动程序、中断处理程序属于操作系统的内核部分,即“I/O 系统”,或称“I/O 核心子系统”。

2.用户层 I/O软件

主要是分为三部分:

  • 系统调用
  • 库函数
  • 假脱机系统(Spooling)

2.1 系统调用

为使诸进程能有条不紊的使用 I/O 设备,因此不允许在用户态的应用进程去直接调用运行在核心态的 OS 过程,而应用进程在运行时,又必须取得OS所提供的服务
于是,OS 在用户层中引入了系统调用,应用程序可以通过它,间接调用 OS 中的 I/O 过程,对 I/O 设备进行操作
当应用程序需要咨询某种 I/O 操作时,在应用程序中必须执行相应的系统调用,当 OS 捕获到系统调用命令后,会从用户态转为核心态,执行系统调用。执行完毕后,再返回用户程序

2.1.1 字符设备接口

  • get/put 系统调用:向字符设备缓冲区读/写一个字符。

2.1.2 块设备接口

  • read/write 系统调用:向块设备的读/写指针位置读/写多个字符。
  • seek 系统调用:修改读/写指针位置。

2.1.3 网络设备(网络套接字)接口

  • socket 系统调用:创建一个网络套接字,需指明网络协议。
  • bind 系统调用:将套接字绑定在某个本地端口。
  • connect 系统调用:将套接字连接到远程地址。
  • read/write 系统调用:从套接字读/写数据。

2.1.4 阻塞/非阻塞 I/O

  • 阻塞 I/O:应用程序发出 I/O 系统调用,进程需转为阻塞态等待。例如,字符设备接口的 get 调用(从键盘读一个字符);C 语言中的 scanf 函数。
  • 非阻塞 I/O:应用程序发出 I/O 系统调用,系统调用可迅速返回,进程无需阻塞等待。例如,块设备接口的 write 调用(往磁盘写数据);C 语言中的 printf 函数。

2.2 库函数

​​1. 库函数必归于系统调用​​(底层调用):所有资源操作终将穿透用户态壁垒(例如内存分配器 malloc 落地为 mmap 系统调用)
​​2. 系统调用经库函数封装:原始接口经标准库包装方成可移植组件(如 Linux clone() 被封装为跨平台的 pthread_create)

Linux下的C库 GNU C library

GNU C 库项目为 GNU 系统和 GNU/Linux 系统,以及许多其他 使用 Linux 作为内核。这些库提供关键 API 包括 ISO C11、POSIX.1-2008、BSD、特定于作系统的 API 等。这些 API 包括 open、read、write、malloc、printf、getaddrinfo、dlopen、pthread_create、crypt、login、exit 等基础工具。

GNU C 库被设计为向后兼容、 便携式和高性能 ISO C 库。它旨在遵循所有 相关标准包括 ISO C11、POSIX.1-2008 和 IEEE 754-2008。

2.3 假脱机(SPOOLing)技术

2.3.1 虚拟化的引入

        虚拟性是操作系统的一大重要特性,它通过某种技术将物理实体转化为多个逻辑实体,两种技术是:时分复用和空分复用,不做过多赘述。而虚拟化,举个例子,(单处理机系统下)在生活中,我们同时在计算机上运行多个进程,比如:一边玩游戏一边使用微信聊天一边听音乐,感觉像是拥有多个CPU一样,但是实际是单处理器,正式通过虚拟化使得用户在逻辑上感觉有多个CPU使得多个进程在同时运行,而事实是同一时刻CPU只能运行一个进程。这种虚拟化技术极大地提高了我们生活的便利性和CPU的利用率。

2.3.2 SPOOLing 技术

        SPOOLing 技术是用于将 I\O 设备进行虚拟化的技术,这个技术可不像 CPU 的虚拟化能欺骗我们人类,它是专门用于欺骗进程的。就拿打印机举栗吧,我就买了一台打印机,但此时我打开了 word 和 pdf,想要打印 word 和 pdf 中的内容;此时计算机中有2个进程,word 进程和 pdf 进程,这两个进程都认为自己拥有一个打印机,那么是否此时我作为计算机的主人就拥有2台打印机了呢?当然不是啊,我又不是睁眼瞎,我就看到了一台打印机啊这就是通过虚拟化技术欺骗了2个无知的进程。
        SPOOLing技术也就是通过使用一个进程模拟脱机任务,以此实现独享设备到共享设备的虚拟化。

2.3.3 SPOOLing的组成

        SPOOLing 技术系统由预输入程序、井管理程序(本质上可以理解成目录)和缓输出程序组成。预输入程序、井管理程序和缓输出程序合起来也叫守护进程。

  • 输入井:模拟脱机输入时的磁带,用于收容 I/O 设备输入的数据,是在磁盘上开辟出的存储区域。
  • 输出井:模拟脱机输出时的磁带,用于收容用户进程输出的数据,是在磁盘上开辟出的存储区域。
  • 输入缓冲区:位于内存,在输入进程的控制下,“输入缓冲区”用于暂存从输入设备输入的数据,之后再转存到输入井中。
  • 输出缓冲区:位于内存,在输出进程的控制下,“输出缓冲区”用于暂存从输出井送来的数据,之后再传送到输出设备上。

2.3.4 SPOOLing 假脱机管理进程的工作原理

        用户进程提出输出打印的请求时,由假脱机管理进程为每个进程做两件事:

  1. 在磁盘输出井中为进程申请一个空闲缓冲区,并将要打印的数据送入其中;
  2. 为用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中,再将该表挂到假脱机文件队列上。

        打印机空闲时,输出进程会从文件队列的队头取出一张打印请求表,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印。

3.设备驱动程序,中断处理程序

        设备驱动程序是一种软件,用于控制计算机上的硬件设备(如打印机、键盘、鼠标、音频/视频设备等),以便它们能够与计算机系统协调工作。设备驱动程序通常由设备制造商提供,并与操作系统紧密集成,以便系统可以识别和使用设备。设备驱动程序提供与设备交互所需的指令,允许设备与计算机通信,从而使设备能够正常工作。

                                

        虽然设备控制器屏蔽了设备的众多细节,但每种设备的控制器的寄存器、缓冲区等使用模式都是不同的,所以为了屏蔽「设备控制器」的差异,引入了设备驱动程序。

        ‘设备完成了事情,则会发送中断来通知操作系统。那操作系统就需要有一个地方来处理这个中断,这个地方也就是在设备驱动程序里,它会及时响应控制器发来的中断请求,并根据这个中断的类型调用响应的中断处理程序进行处理。 通常,设备驱动程序初始化的时候,要先注册一个该设备的中断处理函数。

        中断处理程序的处理流程:

  1. 在 I/O 时,设备控制器如果已经准备好数据,则会通过中断控制器向 CPU 发送中断请求;
  2. 保护被中断进程的 CPU 上下文;
  3. 转入相应的设备中断处理函数;
  4. 进行中断处理;
  5. 恢复被中断进程的上下文;

4.设备控制器

        为了屏蔽设备之间的差异,每个设备都有一个设备控制器的组件,作为计算机主机和外部设备之间的桥梁,比如:硬盘由硬盘控制器、显示器由视频控制器。设备控制器是硬件组件,负责管理该类型设备的所有通信。


       每个设备控制器都会有一个应用程序与之对应,设备控制器通过应用程序的接口通过中断与操作系统进行通信。设备控制器是硬件,而设备驱动程序是软件。 CPU通过设备控制器来和设备连接,设备控制器里有芯片,它可以执行自己的逻辑,也有自己的寄存器,用来和CPU进行通信,比如:

  • 通过写入这些寄存器,操作系统可以命令设备发送数据、接受数据、开启或关闭、或者执行某些其他操作。
  • 通过读取这些寄存器,操作系统可以了解设备的状态,是否准备号接受一个新的命令等。

控制器有三类寄存器,分别是状态寄存器、命令寄存器以及数据寄存器,这三个寄存器的作用:

  • 数据寄存器:CPU向I/O设备写入需要传输的数据
  • 命令寄存器:CPU发送一个命令,通知I/O设备,要继续输入/输出操作,于是就交给I/O设备去工作,任务完成后,会把状态寄存器里面的状态标记为完成
  • 状态寄存器:通知CPU设备的状态,直到前面的工作已经完成,状态寄存标记或已完成,CPU才能发送下一个字符和命令。

        设备控制器是处理 CPU 传入和传出信号的系统。设备通过插头和插座连接到计算机,并且插座连接到设备控制器。设备控制器从连接的设备处接收数据,并将其存储在控制器内部的一些特殊目的寄存器(special purpose registers) 也就是本地缓冲区中。

        1.特殊用途寄存器——仅为一项任务而设计的寄存器,例如:cs,ds,ss,es,fs,gs,eip,flag

        2.通用目的寄存器——可以无限制使用的寄存器,例如:eax,ecx,edx,ebx,esi,edi,ebp,esp

5. 设备驱动程序和设备控制器的区别联系

联系:

  • 通信中介:设备驱动程序充当着操作系统和设备控制器之间的通信中介,通过驱动程序,操作系统可以发出指令给控制器,同时也能接受到来自控制器状态更新或结果反馈。
  • ​​抽象封装​​:控制器对驱动隐藏物理细节:硬盘驱动无需知道碟片转速→控制器处理马达控制;显卡驱动输出渲染指令→GPU控制器管理晶体管开关
  • 协同工作:为使设备正常工作,设备驱动程序必须准确地理解和响应设备控制器产生的行为,反之亦然。意味着驱动程序需要针对特定型号的控制器编写,以便充分利用其特性并保证稳定性

6.Linux下的内存映射I/O

        每个控制器都会有几个寄存器来和CPU进行通信。通过写入这些寄存器,操作系统可以命令设备发送数据,接受数据、开启或者关闭设备等。通过从这些寄存器中读取信息,操作系统能够知道设备的状态,是否准备接受一个新命令等。
        为了控制寄存器 ,许多设备都会有数据 缓冲区(data buffer),来提供读写。例如:在屏幕 上显示一个像素的常规方法是使用一个视频RAM,这一RAM基本上是一个数据缓冲区,用来供程序和操作系统进行写入。
        CPU与设备寄存器和设备数据缓冲区进行通信的方式有两种:

  1. 每个控制寄存器都被分配一个I/O端口号(I/O port),这是一个8位或16位的整数。所有I/O端口的集合形成了受保护的I/O端口空间,只有操作系统才能进行访问,使用特殊的I/O指令如:

    IN REG,PORT --CPU可以读取控制寄存器PORT中的内容并将结果放在CPU寄存器REG中
    OUT PORT,REG --CPU可以将REG的内容写到控制寄存器中.
    

    在这一方式中,内存地址空间的I/O地址空间是不相同的,如图:

  2. 使用PDP-11,它将所有控制寄存器映射到内存空间中

内存映射I/O的优点和缺点

以上两种寻址控制器的方式具有不同的优缺点,优点:

  1. 如果需要特殊的I/O指令进行读写设备控制器,那么访问这些寄存器需要使用汇编代码,因为在C或C++中不存在执行IN和OUT指令的方式,调用这样的过程增加了I/O的开销。在内存映射中,控制寄存器只是内存中的变量,在C语言中可以可以和其他变量一样进行寻址。
  2. 对于内存映射I/O,无需特殊的保护机制就能够阻止用户进程执行I/O操作。操作系统需要保证的是禁止把控制寄存器的地址空间放在用户的虚拟地址中即可。
  3. 对于内存映射I/O,可以引用内存的每一条指令也可以引用控制寄存器,便于引用

缺点:

  1. 大部分计算机现在都会有一些对于内存字的缓存。缓存一个设备控制器的代价是很大的。为了避免这种内存映射I/O的情况,硬件必须有选择性的禁用缓存。
  2. 如果仅仅只有一个地址空间,那么所有的内存模块(memory modules, 在计算机中,存储器模块是其上安装有存储器集成电路的印刷电路板)和所有的I/O设备都必须检查所有的内存引用来推断谁来进行响应。

7.直接内存访问(DMA)

        无论一个CPU是否具有内存映射I/O,它都需要寻址设备以便进行数据交换。CPU可以从I/O控制器每次请求一个字节的数据,但是会浪费CPU时间,所以经常使用的方式是——直接内存访问(DMA)。如图,为了简化,假设CPU通过单一的系统总线访问所有设备和内存,该总线连接CPU、内存和I/O设备。

        不论DMA控制器的物理地址在哪,它都能够独立于CPU从而访问系统总线,它包含几个可由CPU读写的寄存器,其中一个包括一个内存地址寄存器,字节计数寄存器和一个或多个控制寄存器。控制寄存器指定要使用的I/O端口,传送方向(从I/O设备读或写到I/O设备)、传送单位(每次一个字节或者一个字)以及在以此突发传送中的要传送的字节数。

        DMA的原理:如果按数据块进行I/O,即需要传输大量数据时,就无须CPU的介入。在这种情况下,我们可以让I/O设备与计算机内存进行直接数据交换。而CPU则可以去忙别的事情。这种将CPU的介入减少的I/O模式称为直接内存访问。

参考引用:

设备控制器 | 小白的编程之路

操作系统中 设备驱动程序和设备控制器之间的关系 - guanyubo - 博客园

linux_kernel_wiki/文章/Linux操作系统IO机制原理(流程图详解).md at main · 0voice/linux_kernel_wiki

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2402341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW与Modbus/TCP温湿度监控系统

基于LabVIEW 开发平台与 Modbus/TCP 通信协议,设计一套适用于实验室环境的温湿度数据采集监控系统。通过上位机与高精度温湿度采集设备的远程通信,实现多设备温湿度数据的实时采集、存储、分析及报警功能,解决传统人工采集效率低、环境适应性…

Cursor 1.0 版本 GitHub MCP 全面指南:从安装到工作流增强

Cursor 1.0 版本 GitHub MCP 全面指南:从安装到工作流增强 简介 GitHub MCP (Machine Coding Protocol) 是一种强大的工具,能够自动化代码生成、管理和分析,从而显著提升开发效率。本文将全面介绍 GitHub MCP 的安装、配置、使用以及如何将其融入您的工作流。 本文介绍两种…

自主设计一个DDS信号发生器

DDS发生器 DDS信号发生器是直接数字频率合成技术,采用直接数字频率合成(Direct Digital Synthesis,简称DDS)技术,把信号发生器的频率稳定度、准确度提高到与基准频率相同的水平,并且可以在很宽的频率范围内进行精细的频率调节。采…

鸿蒙UI(ArkUI-方舟UI框架)- 使用弹框

返回主章节 → 鸿蒙UI(ArkUI-方舟UI框架) 文章目录 弹框概述使用弹出框(Dialog)弹出框概述不依赖UI组件的全局自定义弹出框(openCustomDialog)(推荐)生命周期自定义弹出框的打开与关闭更新自定义弹出框内容更新自定义弹出框的属性完整示例 基础自定义弹…

学习笔记(24): 机器学习之数据预处理Pandas和转换成张量格式[2]

学习笔记(24): 机器学习之数据预处理Pandas和转换成张量格式[2] 学习机器学习,需要学习如何预处理原始数据,这里用到pandas,将原始数据转换为张量格式的数据。 学习笔记(23): 机器学习之数据预处理Pandas和转换成张量格式[1]-CSDN博客 下面…

在不同型号的手机或平板上后台运行Aidlux

在不同型号的手机或平板上后台运行Aidlux 一、鸿蒙/HarmonyOS手机与平板 二、小米手机与平板 三、OPPO手机与平板 四、vivo手机与平板 一、鸿蒙/HarmonyOS手机与平板 (系统版本有差异,但操作原理相通) 第一步:点击设置——应用和…

【SSM】SpringBoot学习笔记1:SpringBoot快速入门

前言: 文章是系列学习笔记第9篇。基于黑马程序员课程完成,是笔者的学习笔记与心得总结,供自己和他人参考。笔记大部分是对黑马视频的归纳,少部分自己的理解,微量ai解释的内容(ai部分会标出)。 …

1.企业可观测性监控三大支柱及开源方案的横评对比

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] 📢 大家好,我是 WeiyiGeek,一名深耕安全运维开发(SecOpsDev)领域的技术从业者,致力于探索DevOps与安全的融合(De…

双空间知识蒸馏用于大语言模型

Dual-Space Knowledge Distillation for Large Language Models 发表:EMNLP 2024 机构:Beijing Key Lab of Traffic Data Analysis and Mining 连接:https://aclanthology.org/2024.emnlp-main.1010.pdf 代码:GitHub - songmz…

OpenCV CUDA模块特征检测------角点检测的接口createMinEigenValCorner()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数创建一个 基于最小特征值(Minimum Eigenvalue)的角点响应计算对象,这是另一种经典的角点检测方法&…

8天Python从入门到精通【itheima】-69~70(字符串的常见定义和操作+案例练习)

目录 69节-字符串的定义和操作 1.学习目标 2.数据容器视角下的字符串 3.字符串的下标索引 4.字符串是一个无法修改的数据容器 5.字符串的常用操作 【1】index方法 【2】replace方法:进过替换,得到一个新的字符串 【3】split方法:将字…

GC1809:高性能音频接收与转换芯片

GC1809 是一款高性能音频接收与转换芯片,适用于多种音频设备,如 A/V 接收器、多媒体音响设备、机顶盒等。本文将简要介绍该芯片的主要特性、性能参数及应用。 主要特性 多协议兼容:兼容 IEC60958、S/PDIF、EIAJ CP1201 和 AES3 协议。 多种…

项目实战——C语言扫雷游戏

这是一款9*9的扫雷游戏 扫雷游戏 1.需求分析2.程序框架设计3.分函数实现打印游戏菜单界面游戏主逻辑函数程序主入口初始化游戏棋盘随机布置地雷显示当前棋盘状态计算指定位置周围的地雷数量玩家排雷主逻辑 4.分文件实现(1)test.c(2&#xff0…

【Java】CopyOnWriteArrayList

一,概述 CopyOnWriteArrayList作为List接口的实现之一,它区分于ArrayList在于它是线程安全的。如它名字一样,所有的写操作均复制了原数组的值,虽说代价较大,但读多写少的环境下,是可接受的。笔者在此简单看…

C#入门学习笔记 #8(委托)

欢迎进入这篇文章,文章内容为学习C#过程中做的笔记,可能有些内容的逻辑衔接不是很连贯,但还是决定分享出来,由衷的希望可以帮助到你。 笔记内容会持续更新~~ 本章介绍C#中的委托,本章难度较大... 委托 C#中的委托是C语言、C++中函数指针的升级版。接下来介绍一个概念—…

CSS 3D 变换中z-index失效问题

CSS 3D 变换中 z-index 失效问题 1. z-index 失效了 在 CSS 中,z-index 通常用于控制元素的层叠顺序,数值越大,元素越靠前显示。在 3D 变换(如 rotateX、translateZ) 中使用 z-index 时,可能会发现z-inde…

Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(七):消息框交互功能添加

Tailwind CSS 实战,基于Kooboo构建AI对话框页面(一) Tailwind CSS 实战,基于Kooboo构建AI对话框页面(二):实现交互功能 Tailwind CSS 实战,基于 Kooboo 构建 AI 对话框页面&#x…

【计算机网络】网络层IP协议与子网划分详解:从主机通信到网络设计的底层逻辑

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:计算机网络 🌹往期回顾🌹: 【计算机网络】传输层TCP协议——协议段格式、三次握手四次挥手、超时重传、滑动窗口、流量控制、 &…

基于WSL搭建Ubnutu 20.04.6 LTS(二)-部署Docker环境

Docker是一组平台即服务(PaaS)的产品。它基于操作系统层级的虚拟化技术,将软件与其依赖项打包为容器。托管容器的软件称为Docker引擎。Docker能够帮助开发者在轻量级容器中自动部署应用程序,并使得不同容器中的应用程序彼此隔离&a…

【图像处理入门】6. 频域图像处理:傅里叶变换与滤波的奥秘

摘要 频域图像处理通过傅里叶变换将图像从空间域转换到频率域,为图像增强、去噪、压缩等任务提供全新视角。本文将深入解析傅里叶变换原理,介绍低通、高通滤波的实现方式,结合OpenCV和Python代码展示频域滤波在去除噪声、增强边缘中的应用,帮助读者掌握图像频域处理的核心…