查看原文
其他

按下键盘时计算机系统中发生了什么?

脚本之家 2022-09-29

The following article is from 码农的荒岛求生 Author 陆小风

 关注脚本之家”,与百万开发者在一起

出品 | 码农的荒岛求生 (ID:escape-it)

已获得原公众号的授权转载
今天的话题是当我们按下键盘时计算机系统中发生了什么,实际上,要是真写起来,这个问题大概能写成一本书,这里将会从宏观上来了解一下从按下按键到输出至屏幕的整个过程。
键盘大家都很熟悉了,一般长这样
不好意思放错了,一般长这样:
然而它的内部其实是这样类似于矩阵的电路:
每个按键其实是一个开关,当我们按下按键时电路闭合,抬起按键时电路断开,这样当我们按键时键盘中的微型处理器就能感知到,此时万里长征第一步开始了,以下假设我们使用的是usb键盘。
键盘中的硬件检测到的被称为keycode,存放在键盘里中的存储器中,这个存储设备被称为endpoint,usb控制器不断poll该endpoint从而获取到keycode。
usb控制器获取到数据后开始向CPU发起中断:
此时你的CPU在干嘛呢?此时系统中有很多进程,像word以及其它聊天软件之类,假设你正在使用word,因此CPU正在执行word进程相应的机器指令:
CPU检测到中断产生后丢下word进程(暂停)并转到kernel mode,此时CPU发现是usb产生的中断,因此找到usb中断处理函数,该中断函数中开处理按键数据:
由于USB有一套通信协议,像HID(Human Interface Device)协议等,
所以这里的按键就像网络数据包一样被封装成了usb数据在协议栈中一层层向上传递,边传递边处理。
底层的USB层解析后发现是HID数据,然后将其交给HID层处理,HID处理后数据处理后交给输入层,输入层解析后keycode发现按下的是字符“M”,然后将其记录在设备文件(device file)中,在类Unix系统中就是/dev/input/event**,此时数据正式从硬件来到的了计算机系统中:
既然键盘数据一路跋山涉水从硬件来到了内核态,那么接下来就是用户态的表演。
我们在屏幕上看到的一个个窗体,window,实际上这些窗体是由窗体管理器(window manager)管理的,窗口管理器清楚的知道这些window的层级、位置、大小以及是否获取了焦点(focus)。
还是以Unix为例,在Unix系统中,窗体管理器叫做 X window manager,其运行在X Window System,该系统由X server以及X client组成,我们的图形界面应用程序就是x client,其接受来自X server的键盘鼠标等消息:
X server又是从哪里获取键盘鼠标等消息呢?答案就是我们刚才提到的设备文件/dev/input/event**,通过读取该文件X server就能知道键盘被按下以及被按下的是哪个按键。
接下来X server将该消息发送到获取焦点的窗体,此时我们的窗体APP检测键盘按键的代码开始执行,如果是窗体App是赛车游戏程序并且检测到了向上的箭头按键,那么就需要对车进行加速,这需要对游戏画面进行重绘、如果窗体App是文本编辑器则需要将按下的字符显示出来。
在这里以文本编辑器word为例,当word检测到用户按下的是字符M时,word需要知道该以什么字体显示该字符、字体大小是多少、颜色是什么等等。
现在word知道了关于该字符的足够信息,接下来需要请求X Window System将其在屏幕上显示出来,怎么显示呢?
原来内存中有一块被称为framebuffer的区域,GPU从这里获取数据并将其在屏幕上渲染出来,我们需要做的就是将字符包含的所有信息添加到frame buffer中,这样下一次显卡刷新时你按下的字符就能在屏幕上显示出来了。
怎么样,看似简单的按下键盘到屏幕显示字符着实不简单,这里涉及软硬件的密切配合,毫不夸张的说,你每次按下键盘后计算机系统中可能需要成千上万行代码的执行才能把按键最终显示在屏幕上,是不是很有趣!
好啦,今天的文章就到这里,希望这篇对大家理解计算机系统有所帮助

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存