返回介绍

我是一个键盘

发布于 2025-01-22 00:38:44 字数 3893 浏览 0 评论 0 收藏 0

二等公民 这个世界存在阶级歧视的, 我确信。

CPU 和内存很明显是第一等公民, 这一对好基友占据着二环内最核心、最金贵的土地,居高临下对外发号施令, 从各处“抢劫”二进制数据到自己的地界来。

其他的都被归类到二等公民, 居住在 5 环以外, 统称为输入输出(I/O)设备。

有些设备居无定所,通过 USB 临时接入到计算机,待个三五天就走,典型的“北漂”。

哦对了,我必须得说明, 硬盘的地位有点特殊,虽然它也是个 I/O 设备, 但是它存储着所有的程序和数据,包括操作系统老大!

虽然经常被 CPU 和内存嘲笑, 但硬盘应该属于 1.5 等子民, 住在三环以里。

我是一个键盘,和我的兄弟鼠标一样,是个典型的输入设备, 像我这样的 I/O 设备多如牛毛, 比如显卡,声卡,网卡,打印机,扫描仪, CD-ROM 等等。

操作系统老大把我们这些二等公民笼统的划分为两类:块设备和字符设备。

硬盘,CD-ROM,U 盘是典型的块设备, 数据存储在固定大小的块中, 每个块都有一个地址,就样门牌号那样。

像我,鼠标,打印机很明显就是字符设备,哪有什么块结构? 就是用一个个字符组成的流而已,也没有什么地址。

还有一种分法是存储设备(硬盘),传输设备(网卡,调制解调器)、人机交互设备(我和鼠标,显示器也算), 不管怎么划分,我们二等公民的身份都无法更改,也住不到二环去, 那里房价实在太贵了。

夜深人静的时候,我和二等公民朋友们经常探讨这个经久不衰的问题: 咱都是人,为啥就住不到二环去?

鼠标说: 这都是命啊, 计算机刚发明的时候,只有最基本的计算功能和存储功能,哪有什么显卡,声卡,网卡? CPU 和内存的祖先占据了二环,并且一直在那里经营至今, 现在都不知道是多少代了。

我说: 唉,也是, 我们的祖先还是出现晚了, 没有占据好地界儿。

网卡说: 这个不对的, 关键是我们没本事,干不了 CPU 的活啊。

“那算啥, 我的 GPU 运算速度已经很厉害了, 很多超级计算机还用我做运算部件呢,知道不?” 显卡说。

鼠标说: 别想那么多,其实二环生活也不轻松,你看看一开机,CPU 阿甘和内存就忙的不可开交, 累得要死。 像我和键盘, 尤其是你键盘, 除了码农写程序, 半天都不用一下, 还是知足吧。 总线 和 端口 虽然我们是住在五环外的二等公民,但是 CPU 还得和我们打交道, 那 CPU 是怎么和我们联系的?

一种办法就是 CPU 和每个 I/O 设备之间都扯一根线, 有多少个设备就扯多少根,组成了一个以 CPU 为中心的星型布局, 很明显这样太麻烦了, 尤其是来了新设备怎么办?

后来我们采用了“总线”这个概念, 大家都挂到这一条“总线”上, CPU 想找谁了,就在上面吼一声。

轮询(程序式 I/O) 现在 CPU 知道了我们在哪儿,还知道我们的编号, 接下来就可以和我们通信了。

这时候我们又遇到了那个老问题: CPU 太快,而我们 I/O 设备太慢, 毕竟机械设备的速度是无法和电子设备相媲美的。

比如说有个进程要读取硬盘上的文件, CPU 代表该进程向磁盘控制器发出指令:

CPU: 硬盘硬盘, 把你第 1023689 号磁盘块的内容给我拿过来

硬盘: 好的

CPU :弄好了没有?

硬盘: 还没有

CPU : 弄好了没有?

硬盘: 还没有还没有

CPU : 到底弄好没有? 快点

硬盘:都说过没弄好了 !

CPU : 弄好了没有?

硬盘 : @#¥%……&&

CPU 一直霸占着总线,不厌其烦的问硬盘弄好了没有, 别的啥事也不做, 这叫做轮询 , 或者叫做程序控制的 I/O

由于 CPU 比硬盘快百万倍, 很明显 CPU 被浪费了。

中断 大家都觉得这样不合适, 因为 CPU 忙着和硬盘“卿卿我我”, 把别的 I/O 都抛弃了, 像我,鼠标即使有什么数据等着 CPU 读取,他也不搭理我们。

后来就改成了这种方式:

CPU: 硬盘硬盘, 把你第 1023689 号磁盘块的内容给我拿过来, 你弄好了以后告儿我一声。

硬盘: 我怎么告诉你啊

CPU: 我有一个中断请求线, 你弄完了可以往这个地方发信号, 我每次执行完一个指令都会检查。

硬盘 :好的

(CPU 干别的事儿去了,当前进程 A 阻塞,另外一个就绪的进程 B 开始执行)

过了不知道多少纳秒。。。。。

硬盘: CPU, 数据好了,赶紧过来取走。

CPU : 稍等,我把当前的进程 B 给保存了, 然后就去处理。

(CPU 执行中断处理程序, 读取数据.....)

这就是“ 中断” 方式,有了中断以后, 这些平时都不怎么露面的 I/O 设备都跳出了抢着发中断, “调戏”CPU, CPU 乱成了一团, 系统也乱成了一团。

CPU 不胜其烦, 后来专门找了一个叫中断控制器的家伙专门负责协调, 这家伙确实厉害,一上场就说:

只有我才能给 CPU 发中断, 你们的中断请求统统发给我啊,我来裁决谁的优先级高,谁能“调戏”CPU。

这样一来系统清净了。

(注: 这种“中断”的方式,其实就是一种异步的、事件驱动的处理思想,在计算机软硬件上应用非常广泛, 例如 Node.js, AJAX 等等 ) DMA 但是我知道, CPU 和内存才是系统的核心, CPU 运算时候只认内存这个好基友,所以所有的数据不管是谁产生的, 不管是 1.5 等公民硬盘,还是 2 等公民键盘,鼠标等, 数据统统都得搬到内存去。

这就给我们带来了一个挑战: 数据的搬运。

中断的方式对于小数据量传输是有效的, 像我是一个键盘,每次你按下一个键以后, 我就会发出一个中断告诉 CPU,CPU 就能发出指令,把这个一个键对应的字符搬到内存。

但是对于大数据量传输尤其是像硬盘这样的, CPU 还得花费大量的时间和精力不断的发出指令,让磁盘控制器把数据从硬盘搬到内存去, 这相当于又陷入了程序式 I/O 的陷阱。

对于类似这样的情况,我们也有办法处理, 就是用一个 DMA 控制器, 使用这个专用的处理器进行 I/O 设备和内存之间直接的数据传输, 脏活累活都被这个 DMA 给处理了。

CPU: 硬盘硬盘, 把你第 1023689 号磁盘块的内容发送到内存的 xyz 地址去,弄完了告诉我, 我去干别的事儿去了。

硬盘 : 好咧, DMA, 我这儿有数据要传输, 数据一共有 4096 个字节, 要传输到内存的 xyz 地址去。

DMA : 没问题 !

(DMA 控制器开始哼哧哼哧的干活,把这 4096 个字节复制到 xyz 地址)

DMA : CPU, 数据已经在内存中了, 可以用了啊

CPU : 怪不得刚才有时候我没法使用总线, 是不是你小子霸占着啊?

DMA : 我不用总线怎么搬运数据到内存? 我也没有挪用几个时钟周期啊, 再说了你还能使用你的一级缓存和二级缓存不是?

CPU : 好吧, 看在你帮我干了这么多苦活累活,就算了吧。 键盘的工作原理 说了这么多别人的事儿, 也该说说我自己了。

我和鼠标一样,是个非常简单的 I/O 设备, 每次你按下和释放键盘上某个键的时候, 我就会产生一个扫描码,例如你按下 A , 扫描码是"1E" , 释放 A ,扫描码是"9E"

我把这个扫描码放到 0x60 端口, 然后向 CPU 发中断, 当然得通过中断控制器了。

CPU 会调用中断处理程序, 读这个 0x60 端口,取到扫描码, 翻译成 ASCII 码就可以使用了。

那么问题来了, 假设系统中有好几个进程都在等待键盘的输入, 这个中断处理程序获得 ASCII 码发给谁呢? 怎么发过去呢?

这个问题留给你了, 欢迎给我回复留言,正确答案有奖励啊。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文