ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

图解 Linux 设备管理:从键盘敲入 A 字母到操作系统 I/O 全流程解析

图解 Linux 设备管理:从键盘敲入 A 字母到操作系统 I/O 全流程解析 文档教程知识库【免费下载链接】CS-Base图解计算机网络、操作系统、计算机组成、数据库共 1000 张图 50 万字破除晦涩难懂的计算机基础知识让天下没有难懂的八股文 在线阅读https://xiaolincoding.com项目地址https://gitcode.com/GitHub_Trending/cs/CS-Base点击查看免费下载键盘是我们每天接触最多的输入设备但很少有人能完整讲清楚当你敲下字母A的那一刻操作系统内部到底发生了什么。要回答这个问题得先理解操作系统是如何屏蔽千差万别的硬件设备、把它们统一管理起来的。本篇技术指南以 图解系统 · 设备管理章节 为核心结合本仓库中关于中断、文件系统、磁盘调度等模块的配套资料完整梳理「设备控制器 → I/O 控制方式 → 设备驱动程序 → 通用块层 → 存储 I/O 分层 → 键盘中断处理」这条主线。读完你不仅能讲清楚键盘输入的全链路还能透彻理解 DMA、中断上下半部、块设备与字符设备、I/O 调度算法这些高频面试点与实战概念。一、设备控制器操作系统与设备打交道的桥梁电脑可以外接非常多输入输出设备键盘、鼠标、显示器、网卡、硬盘、打印机、音响等每个设备的用法和功能都各不相同。操作系统不可能为每类设备单独定制一套交互逻辑于是硬件上引入了一个统一组件——设备控制器Device Controller硬盘有硬盘控制器、显示器有视频控制器、键盘有键盘控制器、网卡有网卡控制器。这些控制器很清楚地知道对应设备的用法和功能因此CPU 从不直接操作设备而是通过设备控制器与设备打交道。设备控制器本质上是一块带有芯片的小型处理器板卡芯片可执行自己的逻辑同时还带有自己的寄存器用来与 CPU 通信通过写入这些寄存器操作系统可以命令设备发送数据、接收数据、开启或关闭或执行某些其他操作通过读取这些寄存器操作系统可以了解设备的状态比如是否准备好接收一个新的命令。1. 控制器里的三类寄存器设备控制器内部有三类寄存器分工非常明确寄存器类型作用数据寄存器Data RegisterCPU 向 I/O 设备写入需要传输的数据。比如要打印的内容是「Hello」CPU 就要先把H字符发送到对应的 I/O 设备命令寄存器Command RegisterCPU 发送命令告诉 I/O 设备要进行输入/输出操作设备接手工作任务完成后把状态寄存器里的状态标记为「完成」状态寄存器Status Register告诉 CPU 设备当前正在工作中还是工作已完成。若设备正在工作CPU 再发送数据或命令都是无效的必须等状态标记为完成CPU 才能发送下一个字符和命令从源码结构看这套命令 / 状态 / 数据三寄存器的模型正是后来所有设备驱动程序访问硬件的基础范式驱动代码向命令寄存器写命令、轮询或等待状态寄存器、通过数据寄存器搬运数据。2. 块设备与字符设备按数据传输的单位I/O 设备可分为两大类块设备Block Device把数据存储在固定大小的块中每个块有自己的地址可以随机访问。硬盘、USB 是常见的块设备字符设备Character Device以字符为单位发送或接收字符流不可寻址也没有任何寻道操作。鼠标、键盘是常见的字符设备。由于块设备通常传输的数据量非常大控制器为此设立了一个可读写的数据缓冲区CPU 向控制器的缓冲区写入数据时只有当缓冲区囤够一部分数据才会发给设备CPU 从控制器的缓冲区读取数据时也需要缓冲区攒够一部分才拷贝到内存。这样做的根本目的是减少对设备的频繁操作——设备的读写是缓慢的物理动作攒批发送比一次一字节高效得多。3. CPU 如何访问控制器的寄存器和缓冲区存在两种主流方法端口 I/OPort I/O每个控制寄存器被分配一个 I/O 端口通过特殊的汇编指令操作这些寄存器例如in/out指令内存映射 I/OMemory-Mapped I/OMMIO将所有控制寄存器映射到内存地址空间中这样 CPU 就可以像读写内存一样读写数据寄存器与缓冲区无需专门指令。内存映射的方式在现代系统中更为普遍因为驱动程序可以用普通的指针读写来操控硬件简化了内核编程模型。二、I/O 控制方式轮询、中断与 DMA设备控制器相当于一个小 CPU可以自行处理一些事情。但当 CPU 给控制器下发读取指令后控制器读完数据时如何通知 CPU是 I/O 系统设计的核心问题。控制器的状态寄存器一般有标记位来标识输入/输出操作是否完成由此演化出三种控制方式。1. 轮询等待Polling傻瓜但简单第一种方法是让 CPU 一直查询状态寄存器直到状态标记为「完成」。这种方式非常傻瓜——它会占用 CPU 的全部时间。在设备响应慢如磁盘寻道、网络包到达的场景下CPU 空转浪费严重。2. 中断Interrupt异步通知第二种方法引入硬件中断控制器设备完成任务后触发中断中断控制器通知 CPU 产生了一个中断CPU 停下当前手里的事情来处理中断。这彻底解放了 CPU使其在设备工作期间可以继续执行其他任务。中断按来源分为两种详见本仓库 什么是软中断软中断由代码显式触发例如执行INT指令硬件中断由硬件通过中断控制器触发设备完成 I/O 时就是这种。3. DMA让数据绕过 CPU 直通内存中断方式对频繁读写数据的磁盘并不友好——设备每完成一次小传输就打一次中断CPU 频繁被打断、占用大量时间。解决办法是引入DMADirect Memory Access直接内存访问它允许设备在 CPU 不参与的情况下自行把 I/O 数据放入内存。要实现 DMA需要「DMA 控制器」这个硬件组件的支持。DMA 的工作流程如下CPU 下发指令给 DMA 控制器告诉它想读取多少数据读完后把数据放在内存的某个位置即可DMA 控制器向磁盘控制器发指令通知它从磁盘读数据到其内部缓冲区接着磁盘控制器把缓冲区数据传输到内存磁盘控制器发确认信号当数据拷贝到内存的操作完成后磁盘控制器在总线上发出一个成功信号到 DMA 控制器DMA 控制器发中断收到信号后DMA 控制器向 CPU 发出中断通知指令完成CPU 就可以直接使用内存里现成的数据。可以看到CPU 读取磁盘数据时只需在传送开始和结束时各参与一次下发指令 接收完成中断中间大块数据搬运完全由 DMA 控制器与磁盘控制器在总线上完成CPU 可以返回去做其他事情。这正是现代高速存储与网卡能够实现高吞吐的基础。三、设备驱动程序屏蔽控制器差异的软件层设备控制器虽然屏蔽了设备本身的众多细节但每种设备控制器的寄存器、缓冲区使用模式依然各不相同。为了屏蔽「设备控制器」的差异操作系统引入了设备驱动程序。这里需要厘清一个边界设备控制器属于硬件不属于操作系统范畴设备驱动程序属于操作系统的一部分是面向设备控制器的代码它发出操控设备控制器的指令后才可以操作设备控制器操作系统内核代码可以像本地调用代码一样使用设备驱动程序的接口。不同设备控制器功能不同但设备驱动程序会向上提供统一的接口这样不同设备的驱动程序就可以以相同的方式接入操作系统。这是屏蔽差异思想的第二层第一层由硬件控制器屏蔽设备差异第二层由驱动屏蔽控制器差异。中断处理程序与驱动注册设备完成了事情会发送中断通知操作系统操作系统必须有一个地方来响应中断——这个地方就在设备驱动程序里驱动程序会及时响应控制器发来的中断请求并根据中断类型调用相应的中断处理程序。通常设备驱动程序初始化的时候要先注册一个该设备的中断处理函数。中断处理程序的处理流程I/O 时设备控制器准备好数据后通过中断控制器向 CPU 发送中断请求保护被中断进程的 CPU 上下文保存寄存器现场转入相应的设备中断处理函数进行中断处理读取数据、响应设备等恢复被中断进程的上下文让进程从被打断的位置继续执行。硬中断与软中断中断的上半部与下半部中断处理程序要短且快因为执行期间可能临时关闭中断处理程序执行过长会导致其他中断丢失。Linux 为此将中断处理拆成两个阶段详细图解见 什么是软中断上半部硬中断由硬件触发快速处理与硬件紧密相关、时间敏感的事比如禁止设备再次发中断下半部软中断由内核触发以内核线程方式延迟处理耗时较长的剩余工作每个 CPU 对应一个软中断内核线程名字形如ksoftirqd/0。以网卡收包为例网卡通过 DMA 把数据写入内存后发硬件中断内核上半部先禁止网卡中断、触发软中断下半部的软中断处理程序再从内存中按网络协议栈逐层解析数据并送给应用程序。Linux 中可通过以下文件实时观察中断情况cat /proc/interrupts查看硬中断累计次数cat /proc/softirqs查看软中断累计次数如NET_RX网络接收、NET_TX网络发送、TIMER定时、SCHED内核调度、RCU锁等类型watch -d cat /proc/softirqs查看中断次数的变化速率定位到底是哪种软中断在快速增长。四、通用块层统一管理块设备的抽象层对于块设备为了减少不同设备之间的差异带来的影响Linux 通过一个统一的**通用块层Generic Block Layer**来管理它们。通用块层处于文件系统和磁盘驱动程序之间主要有两个功能向上提供标准接口为文件系统和应用程序提供访问块设备的标准接口向下把各种不同的磁盘设备抽象为统一的块设备并在内核层面提供一个框架来管理这些设备的驱动程序I/O 请求排队与调度把文件系统和应用程序发来的 I/O 请求排队对队列重新排序、请求合并也就是 I/O 调度目的是提高磁盘读写效率。Linux 的 5 种 I/O 调度算法Linux 支持 5 种 I/O 调度算法各有适用场景调度算法核心思想适用场景没有调度算法None不对 I/O 做任何处理虚拟机 I/O磁盘 I/O 调度交由物理机系统负责先入先出FIFO先进入 I/O 队列的请求先处理最简单的调度适用于对公平性无特殊要求的场景完全公平CFQ为每个进程维护一个 I/O 队列按时间片均匀分布各进程的 I/O 请求大部分系统的默认 I/O 调度器优先级调度优先级高的 I/O 请求先发生运行大量进程的系统如桌面环境、多媒体应用最终期限Deadline分别为读、写请求创建不同队列确保达到最终期限的请求被优先处理I/O 压力较大的场景如数据库其中最终期限调度算法尤为值得关注它把读请求和写请求分开排队读请求通常被赋予更短的期限因为读操作直接阻塞依赖它的进程。这种设计既能提高机械磁盘的吞吐量又能保证临界请求不被饿死因此在数据库这类高 I/O 压力场景下表现更好。补充说明本仓库的 磁盘调度算法 一节还给出了物理层面的磁盘调度磁头寻道优化全景包括先来先服务、最短寻道时间优先SSF、扫描算法SCAN即电梯算法、循环扫描C-SCAN以及 LOOK / C-LOOK 优化变体。这里的通用块层 I/O 调度与磁盘磁头调度是两个不同层面前者在内核软件层面对 I/O 请求排序合并后者在硬件设备层面对磁头寻道顺序进行优化两者协同提升磁盘访问性能。五、存储系统 I/O 软件分层三层结构透视结合文件系统原理Linux 存储系统的 I/O 由上到下可分为三个层次文件系统层、通用块层、设备层。层次包含内容职责文件系统层虚拟文件系统VFS和其他文件系统的具体实现向上为应用程序统一提供标准的文件访问接口向下通过通用块层来存储和管理磁盘数据通用块层块设备的 I/O 队列和 I/O 调度器对文件系统的 I/O 请求排队再通过 I/O 调度器选择一个 I/O 发给下一层的设备层设备层硬件设备、设备控制器和驱动程序负责最终物理设备的 I/O 操作关于虚拟文件系统VFS的细节可参见本仓库 文件系统全家桶VFS 定义了一组所有文件系统都支持的数据结构和标准接口这样程序员不需要了解文件系统的工作原理只要掌握 VFS 提供的统一接口即可。设备在 Linux 下只是一个特殊的文件有了文件系统接口之后不但可以通过文件系统的命令行操作设备也可以通过应用程序调用read、write函数像读写文件一样操作设备——这就是 Linux 那句名言一切皆文件的落地设备在 Linux 下也只是一个特殊的文件。但除了读写操作还需要检查特定于设备的功能和属性于是有了ioctl接口Input/Output Control它是用于配置和修改特定设备属性的通用接口。ioctl是设备管理中最常用的旁路通道设备的专属能力如设置终端参数、调节声卡音量、查询磁盘容量都是通过它实现的。缓存机制为最慢的环节加速存储系统的 I/O 是整个系统最慢的一个环节Linux 为此提供了不少缓存机制来提高 I/O 效率为了提高文件访问的效率使用**页缓存Page Cache、索引节点缓存inode cache、目录项缓存dentry cache**等多种缓存机制目的是减少对块设备的直接调用为了提高块设备访问的效率使用**缓冲区Buffer Cache**来缓存块设备的数据。关于二者的关系本仓库 进程写文件时进程发生了崩溃已写入的数据会丢失吗 有更深入的解读Page Cache 用于缓存文件的页数据buffer cache 用于缓存块设备如磁盘的块数据。在 Linux 2.4 内核之后两者近似融合——文件页加载进 Page Cache 后buffer cache 只需维护块指向页的指针只有没有文件表示的块、或绕过文件系统直接操作的块才会真正放到 buffer cache。文件 I/O 的分类也与缓存机制密切相关默认的非直接 I/O会经过内核页缓存write先把数据写入 page cache把页标记为 dirty再由内核按时机落盘而指定O_DIRECT标志的直接 I/O则绕过页缓存直接经文件系统访问磁盘读写真正落盘/真正从盘读。非直接 I/O 下内核把脏页刷入磁盘的时机包括缓存数据过多、用户主动调用sync、内存紧张、缓存时间超限等。六、键盘敲入 A 字母时操作系统期间发生了什么有了前面的铺垫现在可以完整回答开头的问题了。先看 CPU 的硬件连接架构CPU 的内存接口直接与系统总线通信系统总线接入I/O 桥接器桥接器一边接入内存总线CPU 与内存通信另一边接入 I/O 总线连接键盘、显示器等 I/O 设备。整个过程的完整时序如下键盘控制器产生扫描码用户敲下字母键键盘控制器产生扫描码数据并将其缓冲在键盘控制器的寄存器中发送中断请求键盘控制器通过总线向 CPU 发送中断请求保存被中断进程的 CPU 上下文CPU 收到中断请求后操作系统保存当前正在执行的进程的 CPU 上下文寄存器现场调用键盘中断处理程序该处理程序是在键盘驱动程序初始化时注册的。它的核心功能是从键盘控制器的寄存器缓冲区读取扫描码根据扫描码找到用户在键盘上输入的字符如果输入的是显示字符就把扫描码翻译成对应字符的ASCII 码例如敲下字母 A翻译成字符A的 ASCII 码 65放入读缓冲区队列得到显示字符的 ASCII 码后将其放入「读缓冲区队列」显示设备驱动搬运数据显示设备的驱动程序定时从「读缓冲区队列」读取数据放入「写缓冲区队列」再把「写缓冲区队列」中的数据逐个写入显示设备控制器的寄存器中的数据缓冲区最终将字符显示在屏幕上恢复被中断进程的上下文显示完成后操作系统恢复之前保存的进程上下文被打断的进程继续运行。这条链路里隐藏的所有知识点把上面 7 步与前面的章节一一对应会发现这条链路几乎用上了设备管理的全部机制设备控制器键盘控制器、显示控制器各司其职它们的寄存器完成扫描码缓冲与数据写入中断机制键盘通过硬件中断打断 CPU中断处理程序短且快——只做读扫描码 翻译 ASCII的轻量工作后续的队列搬运交给驱动与设备异步完成这正是中断上半部快处理思想的体现设备驱动程序键盘驱动负责注册中断处理函数显示驱动负责定时把数据从读缓冲区搬到写缓冲区再刷到控制器缓冲区与队列读缓冲区队列 / 写缓冲区队列的存在让字符的到达速率与屏幕的刷新速率解耦避免设备频繁被打断上下文保护与恢复进程被打断时现场被完整保存与恢复这是操作系统得以边打字边干其他事的根本保障。更宏观地看这条链路还可以延伸如果输入的是数据而非显示字符如密码、文本内容ASCII 码最终会通过内核的输入子系统进入进程的输入缓冲区被正在等待read的应用程序读取——于是一次键盘敲击最终变成了一次普通的文件式读取Linux一切皆文件的设备抽象在此闭环。七、总结本篇文章以「键盘敲入 A 字母」为引完整梳理了操作系统设备管理的知识体系设备控制器用三类寄存器数据 / 命令 / 状态 数据缓冲区屏蔽设备差异CPU 通过端口 I/O 或内存映射 I/O 访问它们设备可分为块设备与字符设备块设备通过缓冲区攒批传输以减少频繁操作I/O 控制方式从轮询演进到中断再到DMADMA 让数据在传送期间完全绕过 CPU仅在开始和结束时各打断一次设备驱动程序在软件层屏蔽控制器差异、注册中断处理函数配合中断上半部 下半部硬中断 软中断机制保证系统响应性通用块层统一管理块设备并提供 I/O 调度Linux 支持无调度、FIFO、完全公平、优先级、最终期限五种算法按场景各取所需存储 I/O 按文件系统层 → 通用块层 → 设备层三层分层设备以特殊文件形式暴露给用户配合页缓存、目录项缓存与 buffer cache 加速最慢的 I/O 环节。如果把这一整套知识再放回仓库的完整图谱中中断机制可与 什么是软中断 交叉阅读文件系统层细节见 文件系统全家桶缓存与 I/O 模型深入分析见 进程写文件时进程发生了崩溃已写入的数据会丢失吗磁盘磁头调度算法见 磁盘调度算法。设备管理是操作系统五大核心结构进程管理、内存管理、文件系统、设备管理、网络系统的底座之一吃透这条主线后续理解网络系统里的零拷贝、I/O 多路复用参见 I/O 多路复用select/poll/epoll 与 什么是零拷贝也就水到渠成了。赞分享文档教程知识库【免费下载链接】CS-Base图解计算机网络、操作系统、计算机组成、数据库共 1000 张图 50 万字破除晦涩难懂的计算机基础知识让天下没有难懂的八股文 在线阅读https://xiaolincoding.com项目地址https://gitcode.com/GitHub_Trending/cs/CS-Base点击查看免费下载相关推荐CS-Base 图解操作系统Linux 文件系统全家桶——从 inode、目录项到文件存储与文件 I/O 全解析CS Base 图解操作系统Linux 文件系统全家桶——从 inode、目录项到文件存储与文件 I/O 全解析 本篇技术指南以 CS Base 仓库《图解系文档教程知识库Linux系统I/O性能瓶颈深度解析从/proc/diskstats到块设备驱动Linux系统I/O性能瓶颈深度解析从/proc/diskstats到块设备驱动 你是否曾经面对服务器I/O性能问题束手无策当应用程序响应缓慢磁盘使用率居操作系统内核驱动驱动开发虚拟化嵌入式网络存储Spring Cloud与gRPC集成终极指南构建高性能微服务通信架构Spring Cloud与gRPC集成终极指南构建高性能微服务通信架构 在当今微服务架构盛行的时代 Spring Cloud与gRPC集成 已成为构建高性能上一篇PHP开发者必备spatie/ssl-certificate API完全参考手册下一篇终极GHelper完全指南华硕笔记本性能控制神器从入门到精通创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表