键盘敲入一个字母,操作系统发生了什么?

news2024/12/23 12:18:06

一、设备控制器

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

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

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

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

控制器分为三类寄存器,分别是状态寄存器,命令寄存器以及数据寄存器,作用如下:

  • 数据寄存器:CPU 向 IO 设备写入需要传输的数据,比如要打印的内容是【hello】,CPU 就要先发送一个 H 字符给到对应的 IO 设备
  • 命令寄存器:CPU 发送一个命令,告诉 IO 设备,要进行输入输出操作,于是就会交给 IO 设备去工作,任务完成后,会把状态寄存器里面的状态标记为完成
  • 状态寄存器:目的是告诉 CPU ,现在已经在工作或工作已经完成,如果已经在工作状态,CPU 再发送数据或者命令过来,都是没有用的,直到前面的工作已经完成,状态寄存器标记已完成,CPU 才能发送下一个字符和命令

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

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

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

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

这样做是为了减少对设备的频繁操作,那 CPU 是如何与设备的控制寄存器和数据缓冲区进行通信的?:

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

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

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

正题来辣~ 键盘敲入字母时,发生了什么?

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

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

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

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

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

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

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

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

相关文章

rest_framework_django学习笔记一(序列化器)

rest_framework_django学习笔记一(序列化器) 一、引入Django Rest Framework 1、安装 pip install djangorestframework2、引入 INSTALLED_APPS [...rest_framework, ]3、原始RESTful接口写法 models.py from django.db import models 测试数据 仅供参考 INSERT INTO de…

我与开源的历程

我在2000年开始接触开源,当时在松下航空电子美国总部工作。我负责将 IFE 系统从 Win31 迁移到 Linux。作为一个完全不懂 Linux 的小白,我不得不找到一台笔记本电脑安装并自学 Redhat Linux 6.1。2003年回到新加坡后,我发现没有一个凝聚 Linux…

Java数据结构之《链式线性表的插入与删除》问题

一、前言: 这是怀化学院的:Java数据结构中的一道难度中等偏下的一道编程题(此方法为博主自己研究,问题基本解决,若有bug欢迎下方评论提出意见,我会第一时间改进代码,谢谢!) 后面其他编程题只要我…

Rust std fs 比 Python 慢!真的吗!?

作者:Xuanwo Databend Labs 成员,数据库研发工程师 https://github.com/xuanwo 我即将分享一个冗长的故事,从 OpenDAL 的 op.read()开始,以一个意想不到的转折结束。这个过程对我来说非常有启发性,我希望你也能感受到。…

记RocketMQ本地开发环境搭建始末

前言 最近工作中涉及到了RocketMQ的应用,为方便开发决定本地搭建一套RocketMQ的使用环境。 果然实践是个好东西... VMware虚拟环境搭建 这个网上有很多教程,只会比我写的详细有条理,这里就不在赘述了。 虚拟机搭建好之后每次重启电脑都无…

flutter开发实战-轮播Swiper更改Custom_layout样式中Widget层级

flutter开发实战-轮播Swiper更改Custom_layout样式中Widget层级 在之前的开发过程中,需要实现卡片轮播效果,但是卡片轮播需要中间大、两边小一些的效果,这里就使用到了Swiper。具体效果如视频所示 添加链接描述 这里需要的效果是中间大、两边…

golang 函数选项模式

一 什么是函数选项模式 函数选项模式允许你使用接受零个或多个函数作为参数的可变构造函数来构建复杂结构。我们将这些函数称为选项,由此得名函数选项模式。 例子: 有业务实体Animal结构体,构造函数NewAnimal()&…

Liunx配置Tomcat自启动

Liunx配置Tomcat自启动 Tomcat安装配置Tomcat开机启动 Tomcat安装 下载tomcat软件安装包,上传软件包到Liunx服务器。 解压软件包到opt目录下 tar -xvf apache-tomcat-9.0.76.tar.gz -c /opt配置Tomcat开机启动 (1)修改Tomcat bin目录下的ca…

vue项目和wx小程序

wx:key 的值以两种形式提供: 1、字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。 2、保留关键字 this 代表在 for 循环中的 item 本身,这种…

学习笔记:Pytorch 搭建自己的Faster-RCNN目标检测平台

B站学习视频 up主的csdn博客 1、什么是Faster R-CNN 2、pytorch-gpu环境配置(跳过) 3、Faster R-CNN整体结构介绍 Faster-RCNN可以采用多种的主干特征提取网络,常用的有VGG,Resnet,Xception等等。 Faster-RCNN对输入…

ArkTS-列表选择弹窗

调用 每一个sheet中的action对应其点击事件 Button(列表选择弹窗).onClick(() > {ActionSheet.show({title: 列表选择弹窗标题,message: 内容,autoCancel: true,confirm: {value: 确认,action: () > {console.log(Get Alert Dialog handled)}},cancel: () > {console.…

INFINI Easysearch 与华为鲲鹏完成产品兼容互认证

何为华为鲲鹏认证 华为鲲鹏认证是华为云围绕鲲鹏云服务(含公有云、私有云、混合云、桌面云)推出的一项合作伙伴计划,旨在为构建持续发展、合作共赢的鲲鹏生态圈,通过整合华为的技术、品牌资源,与合作伙伴共享商机和利…

视频分割方法:批量剪辑高效分割视频,提取m3u8视频技巧

随着互联网的快速发展,视频已成为获取信息、娱乐、学习等多种需求的重要载体。然而,很多时候,需要的只是视频的一部分,这就要对视频进行分割。而m3u8视频是一种常见的流媒体文件格式,通常用于在线视频播放。本文将分享…

unity学习笔记13

一、常用物理关节 Unity中的物理关节(Physics Joints)是用于在游戏中模拟和控制物体之间的连接。物理关节允许你在对象之间应用各种约束,例如旋转、移动或固定连接,以模拟真实世界中的物理交互。 物理关节类型: 1.F…

同旺科技 分布式数字温度传感器 -- OPC Servers测试

内附链接 1、数字温度传感器 主要特性有: ● 支持PT100 / PT1000 两种铂电阻; ● 支持 2线 / 3线 / 4线 制接线方式; ● 支持5V~17V DC电源供电; ● 支持电源反接保护; ● 支持通讯波特率1200bps、2…

spring日志输出到elasticsearch

1.maven <!--日志elasticsearch--><dependency><groupId>com.agido</groupId><artifactId>logback-elasticsearch-appender</artifactId><version>3.0.8</version></dependency><dependency><groupId>net.l…

koa2项目中封装log4js日志输出

1.日志输出到控制台 npm i log4js -D 封装log4js文件&#xff1a; 注意&#xff1a;每次都要重新获取log4js.getLogger(debug)级别才能生效 const log4js require("log4js");const levels {trace: log4js.levels.TRACE,debug: log4js.levels.DEBUG,info: log4js.…

通过C#获取Windows设置的夏令时开关

C#获取Windows夏令时开关 // 获取所有的时区信息 var allTimeZones TimeZoneInfo.GetSystemTimeZones().ToList();通过接口可以看到, 字段SupportsDaylightSavingTime代表是否支持配置夏令时 // 获取当前Window设置的时区 var tmpLocal TimeZoneInfo.Local;但是取Local 信息…

python+pytest接口自动化(5)-requests发送post请求

简介 在HTTP协议中&#xff0c;与get请求把请求参数直接放在url中不同&#xff0c;post请求的请求数据需通过消息主体(request body)中传递。 且协议中并没有规定post请求的请求数据必须使用什么样的编码方式&#xff0c;所以其请求数据可以有不同的编码方式&#xff0c;服务…

文件格式扩展名转换:将图片png扩展名批量改为jpg的方法

在处理大量图片文件时&#xff0c;可能会遇到需要将文件格式扩展名进行转换的情况。比如&#xff0c;将图片文件从PNG格式转换为JPG格式。这不仅可以节省存储空间&#xff0c;还可以提高图片加载速度&#xff0c;特别是在网页设计中。本文详解如何将PNG图片批量转换为JPG格式的…