【操作系统】键盘敲入字母时,操作系统期间发生了什么?

news2024/11/17 7:43:24

【操作系统】键盘敲入字母时,操作系统期间发生了什么?

参考资料:

键盘敲入 A 字母时,操作系统期间发生了什么?

【操作系统】浅谈 Linux 中的中断机制

文章目录

  • 【操作系统】键盘敲入字母时,操作系统期间发生了什么?
    • 设备控制器
    • I/O 控制方式
    • 设备驱动程序
    • 存储系统 I/O 软件分层
    • 键盘敲入字母时,期间发生了什么?

键盘可以说是我们最常使用的输入硬件设备了,但身为程序员的你,你知道「 键盘敲入字母时,操作系统期间发生了什么吗」?

那要想知道这个发生的过程,我们得先了解了解「操作系统是如何管理多种多样的的输入输出设备」的,等了解完这个后,我们再来看看这个问题,你就会发现问题已经被迎刃而解了。

设备控制器

我们的电脑设备可以接非常多的输入输出设备,比如键盘、鼠标、显示器、网卡、硬盘、打印机、音响等等,每个设备的用法和功能都不同,那操作系统是如何把这些输入输出设备统一管理的呢?

为了屏蔽设备之间的差异,每个设备都有一个叫设备控制器(*Device Control*) 的组件,比如硬盘有硬盘控制器、显示器有视频控制器等。

image-20230701155812327

因为这些控制器都很清楚的知道对应设备的用法和功能,所以 CPU 是通过设备控制器来和设备打交道的。

设备控制器里有芯片,它可执行自己的逻辑,也有自己的寄存器,用来与 CPU 进行通信,比如:

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

另外, 输入输出设备可分为两大类 :块设备(*Block Device*)**和**字符设备(*Character Device*)

  • 块设备,把数据存储在固定大小的块中,每个块有自己的地址,硬盘、USB 是常见的块设备。
  • 字符设备,以字符为单位发送或接收一个字符流,字符设备是不可寻址的,也没有任何寻道操作,鼠标是常见的字符设备。

块设备通常传输的数据量会非常大,于是控制器设立了一个可读写的数据缓冲区

  • CPU 写入数据到控制器的缓冲区时,当缓冲区的数据囤够了一部分,才会发给设备。
  • CPU 从控制器的缓冲区读取数据时,也需要缓冲区囤够了一部分,才拷贝到内存。

这样做是为了,减少对设备的频繁操作。

那 CPU 是如何与设备的控制寄存器和数据缓冲区进行通信的?存在两个方法:

  • 端口 I/O,每个控制寄存器被分配一个 I/O 端口,可以通过特殊的汇编指令操作这些寄存器,比如 in/out 类似的指令。
  • 内存映射 I/O,将所有控制寄存器映射到内存空间中,这样就可以像读写内存一样读写数据缓冲区。

I/O 控制方式

在前面我知道,每种设备都有一个设备控制器,控制器相当于一个小 CPU,它可以自己处理一些事情,但有个问题是,当 CPU 给设备发送了一个指令,让设备控制器去读设备的数据,它读完的时候,要怎么通知 CPU 呢?

控制器的寄存器一般会有状态标记位,用来标识输入或输出操作是否完成。于是,我们想到第一种轮询等待的方法,让 CPU 一直查寄存器的状态,直到状态标记为完成,很明显,这种方式非常的傻瓜,它会占用 CPU 的全部时间。

那我们就想到第二种方法 —— 中断,通知操作系统数据已经准备好了。我们一般会有一个硬件的中断控制器,当设备完成任务后触发中断到中断控制器,中断控制器就通知 CPU,一个中断产生了,CPU 需要停下当前手里的事情来处理中断。

另外,中断有两种,一种软中断,例如代码调用 INT 指令触发,一种是硬件中断,就是硬件通过中断控制器触发的。

但中断的方式对于频繁读写数据的磁盘,并不友好,这样 CPU 容易经常被打断,会占用 CPU 大量的时间。对于这一类设备的问题的解决方法是使用 DMA(*Direct Memory Access*) 功能,它可以使得设备在 CPU 不参与的情况下,能够自行完成把设备 I/O 数据放入到内存。那要实现 DMA 功能要有 「DMA 控制器」硬件的支持。

image-20230701155851227

DMA 的工作方式如下:

  • CPU 需对 DMA 控制器下发指令,告诉它想读取多少数据,读完的数据放在内存的某个地方就可以了;
  • 接下来,DMA 控制器会向磁盘控制器发出指令,通知它从磁盘读数据到其内部的缓冲区中,接着磁盘控制器将缓冲区的数据传输到内存;
  • 当磁盘控制器把数据传输到内存的操作完成后,磁盘控制器在总线上发出一个确认成功的信号到 DMA 控制器;
  • DMA 控制器收到信号后,DMA 控制器发中断通知 CPU 指令完成,CPU 就可以直接用内存里面现成的数据了;

可以看到, CPU 当要读取磁盘数据的时候,只需给 DMA 控制器发送指令,然后返回去做其他事情,当磁盘数据拷贝到内存后,DMA 控制机器通过中断的方式,告诉 CPU 数据已经准备好了,可以从内存读数据了。仅仅在传送开始和结束时需要 CPU 干预。

设备驱动程序

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

image-20230701155919438

设备控制器不属于操作系统范畴,它是属于硬件,而设备驱动程序属于操作系统的一部分,操作系统的内核代码可以像本地调用代码一样使用设备驱动程序的接口,而设备驱动程序是面向设备控制器的代码,它发出操控设备控制器的指令后,才可以操作设备控制器。

不同的设备控制器虽然功能不同,但是设备驱动程序会提供统一的接口给操作系统,这样不同的设备驱动程序,就可以以相同的方式接入操作系统。如下图:

image-20230701155930130

前面提到了不少关于中断的事情,设备完成了事情,则会发送中断来通知操作系统。那操作系统就需要有一个地方来处理这个中断,这个地方也就是在设备驱动程序里,它会及时响应控制器发来的中断请求,并根据这个中断的类型调用响应的中断处理程序进行处理。

通常,设备驱动程序初始化的时候,要先注册一个该设备的中断处理函数。

image-20230701155942038

我们来看看,中断处理程序的处理流程:

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

存储系统 I/O 软件分层

前面说到了不少东西,设备、设备控制器、驱动程序、通用块层,现在再结合文件系统原理,我们来看看 Linux 存储系统的 I/O 软件分层。

可以把 Linux 存储系统的 I/O 由上到下可以分为三个层次,分别是文件系统层、通用块层、设备层。他们整个的层次关系如下图:

image-20230701155957469

这三个层次的作用是:

  • 文件系统层,包括虚拟文件系统和其他文件系统的具体实现,它向上为应用程序统一提供了标准的文件访问接口,向下会通过通用块层来存储和管理磁盘数据。
  • 通用块层,包括块设备的 I/O 队列和 I/O 调度器,它会对文件系统的 I/O 请求进行排队,再通过 I/O 调度器,选择一个 I/O 发给下一层的设备层。
  • 设备层,包括硬件设备、设备控制器和驱动程序,负责最终物理设备的 I/O 操作。

有了文件系统接口之后,不但可以通过文件系统的命令行操作设备,也可以通过应用程序,调用 readwrite 函数,就像读写文件一样操作设备,所以说设备在 Linux 下,也只是一个特殊的文件。

但是,除了读写操作,还需要有检查特定于设备的功能和属性。于是,需要 ioctl 接口,它表示输入输出控制接口,是用于配置和修改特定设备属性的通用接口。

另外,存储系统的 I/O 是整个系统最慢的一个环节,所以 Linux 提供了不少缓存机制来提高 I/O 的效率。

  • 为了提高文件访问的效率,会使用页缓存、索引节点缓存、目录项缓存等多种缓存机制,目的是为了减少对块设备的直接调用。
  • 为了提高块设备的访问效率, 会使用缓冲区,来缓存块设备的数据。

键盘敲入字母时,期间发生了什么?

看完前面的内容,相信你对输入输出设备的管理有了一定的认识,那接下来就从操作系统的角度回答开头的问题「键盘敲入字母时,操作系统期间发生了什么?」

我们先来看看 CPU 的硬件架构图:

image-20230701160008720

CPU 里面的内存接口,直接和系统总线通信,然后系统总线再接入一个 I/O 桥接器,这个 I/O 桥接器,另一边接入了内存总线,使得 CPU 和内存通信。再另一边,又接入了一个 I/O 总线,用来连接 I/O 设备,比如键盘、显示器等。

那当用户输入了键盘字符,键盘控制器就会产生扫描码数据,并将其缓冲在键盘控制器的寄存器中,紧接着键盘控制器通过总线给 CPU 发送中断请求

CPU 收到中断请求后,操作系统会保存被中断进程的 CPU 上下文,然后调用键盘的中断处理程序

键盘的中断处理程序是在键盘驱动程序初始化时注册的,那键盘中断处理函数的功能就是从键盘控制器的寄存器的缓冲区读取扫描码,再根据扫描码找到用户在键盘输入的字符,如果输入的字符是显示字符,那就会把扫描码翻译成对应显示字符的 ASCII 码,比如用户在键盘输入的是字母 A,是显示字符,于是就会把扫描码翻译成 A 字符的 ASCII 码。

得到了显示字符的 ASCII 码后,就会把 ASCII 码放到「读缓冲区队列」,接下来就是要把显示字符显示屏幕了,显示设备的驱动程序会定时从「读缓冲区队列」读取数据放到「写缓冲区队列」,最后把「写缓冲区队列」的数据一个一个写入到显示设备的控制器的寄存器中的数据缓冲区,最后将这些数据显示在屏幕里。

显示出结果后,恢复被中断进程的上下文

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

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

相关文章

小驰私房菜_26_YUV数据存在数据对齐,工具打开花图时如何处理?

【问题背景】 在Qcom Camx框架下,dump的yuv,yuv数据有时会存在数据对齐,也就是app端下发的size和我们dump出来的size是不一致的。 这个时候,我们用yuv工具查看yuv数据的时候,宽高如果直接设置的app端下发的size,这个时…

案例解析 | 虚拟数智人“岭梅香”——民间博物馆文化探寻者

TA 是湾区民间文化探寻者 还是广东民间博物馆宣传大使 万里归来颜愈少 笑时犹带“岭梅香” 虚拟数智人 是文博行业走进“元宇宙”的“探路者” 为了践行国家文化数字化战略,按照文化和旅游部“上云用数赋智”的要求,南方都市报、N视频联合广州虚拟…

MATLAB Onramp

目录 任务 音频频率 以表的形式导入数据 循环 恒星运动 知识点摘要 任务 您可以按键盘上的向上箭头键重新调用以前的命令。请注意,要执行此操作,命令行窗口必须为活动窗口。 按向上箭头键以回到命令 m3*5,然后将该命令编辑为 m3*k cle…

【209. 长度最小的子数组】

目录 一、题目解析二、算法原理三、代码实现 一、题目解析 二、算法原理 注意点&#xff1a; 三、代码实现 我自己写的代码(我的评价是很挫) class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int left 0, right -1, ret INT_MAX…

【算法与数据结构】28、LeetCode找出字符串中第一个匹配项的下标

文章目录 一、题目二、暴力穷解法三、KMP算法四、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、暴力穷解法 思路分析&#xff1a;首先判断字符串是否合法&#xff0c;然后利用for循环&#xff0c;取出子字符串…

Flutter卡片分享功能实现:将你的内容分享给世界

前言 在app中&#xff0c;在实现分享功能的时候&#xff0c;通常会有一种以卡片形式展示和分享内容的分享方式。这种功能可以将信息以整洁、易读的方式呈现给用户&#xff0c;使他们能够快速了解内容的关键信息&#xff0c;并将其分享给其他人。那么在这篇文章中&#xff0c;就…

【1004.最大连续1的个数Ⅲ】

目录 一、题目解析二、算法思路三、代码实现 一、题目解析 二、算法思路 三、代码实现 class Solution { public:int longestOnes(vector<int>& nums, int k) {int ret0,count0;int left0,right0;for (; right < nums.size();right ){if (nums[right] 0){count;…

C++——string容器常用操作汇总

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.string容器基本概念二.string容器常用操作✅前言及函数参数的说明一.构造和析构二.string特性操作三.字符操作四.赋值操作五.拼接操作六.交换…

Ubuntu安装gcc和g++图文教程

文章目录 一、gcc 和 g介绍二、ubuntu安装gcc和g三、gcc和g的选项总结 一、gcc 和 g介绍 GCC&#xff08;GNU Compiler Collection&#xff09;是由GNU项目开发的一套广泛使用的开源编译器集合。它支持多种编程语言&#xff0c;包括C、C、Objective-C、Fortran、Ada和其他语言…

基于python深度学习的水果或其他物体识别小程序

效果图如下&#xff1a; 代码演示和demo仓库看b站视频003期&#xff1a; 到此一游7758258的个人空间_哔哩哔哩_bilibili 代码展示&#xff1a; 数据集图片放置在data文件夹下&#xff0c;大家可以根据自己需要比如识别其他物体&#xff0c;只需要模仿data文件夹下的文件命名放…

浅谈基于分项计量的校园能源监管平台解决方案设计

张心志 关注acrelzxz 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;伴随着我国经济的飞速发展&#xff0c;国家机关办公建筑和大型公共建筑高耗能的问题日益突出&#xff0c;如何解决建筑能耗己成为一个国家总能耗的重要组成部分。学校是肩负着教育、科研和社会服…

Oracle中的连接方式

Oracle中的连接方式 对于数据库中表与表之间的连接&#xff08;内连接、外连接&#xff09;都可以看成集合之间的运算操作。 内连接 select * from a_table a inner join b_table b on a.id b.id; 相当于求两个集合中满足条件的结果&#xff0c;即交集。 外连接 左/外连接&a…

计算机性能

计算机性能 计算机性能描述 计算机性能测试程序 计算机性能速度指标 计算机性能计算 设1号计算机执行任务耗时3s,2号计算机执行任务耗时2s&#xff0c;则有 P11/3 P21/2 则相对性能比为 P1/P22/3 &#xff08;p1的性能为p2性能的2/3&#xff09;&#xff0c;因为P1/P2 < …

软考A计划-系统集成项目管理工程师-项目范围管理(一)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

Echarts折线图折线呈现为渐变线条

想要如图所示的折线图&#xff0c;折线线条为渐变颜色&#xff0c;两边颜色接近区域面积的颜色&#xff0c;中间颜色亮度高一些&#xff0c;在series中使用lineStyle&#xff0c;将其color设置为渐变色&#xff1a; option {xAxis: {type: category,data: [Mon, Tue, Wed, Th…

ModaHub魔搭社区:向量数据库Milvus性能优化问题(二)

目录 为什么有时候小的数据集查询时间反而更长&#xff1f; 为什么查询时 GPU 一直空闲&#xff1f; 为什么数据插入后不能马上被搜索到&#xff1f; 为什么我的 CPU 利用率始终不高&#xff1f; 创建集合时 index_file_size 如何设置能达到性能最优&#xff1f; 为什么有…

0基础学习VR全景平台篇 第53篇:专业版功能-离线导出!

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;专业版功能-离线导出&#xff01; 功能位置示意 一、本功能将用在哪里&#xff1f; 离线导出&#xff0c;指的是将VR漫游作品通过下载的方式&#xff0c;保存到本…

YOLOv5/v7 添加注意力机制,30多种模块分析⑦,CCN模块,GAMAttention模块

目录 一、注意力机制介绍1、什么是注意力机制&#xff1f;2、注意力机制的分类3、注意力机制的核心 二、CCN模块1、CCN模块的原理2、实验结果3、应用示例 三、GAMAttention模块1、GAMAttention模块的原理2、实验结果3、应用示例 大家好&#xff0c;我是哪吒。 &#x1f3c6;本…

FreeRTOS内核API速览

FreeRTOS内核API速览 信号量创建信号量计数信号量互斥信号量二值信号量 释放信号量任务模式中断模式 获取信号量任务模式中断模式 消息队列创建队列发送消息任务模式中断模式 获取消息任务模式中断模式 软件定时器创建定时器启动定时器停止定时器复位定时器删除定时器改变定时器…

我的创作纪念日:从前那个看文章的人,如今已经成为了写文章的人.

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 金句分享:…