简简单单
简简单单的一个ping动作,中间涉及的内容几乎包含了计算机领域里面所有的基础内容,复杂而精妙。
这篇文章一次肯定写不完,最后写完了肯定也不可能包含所有的内容。我对其中的一些内容也早就忘的干净,不过既然写了,就认真写,能写多少写多少,能写多细写多细,并且尽量表达的通俗易懂一点,有哪里不对的地方,别打我,跟我说,我会改。
先上一个大致的流程图,后面也会按照这图里的四个点分开讲
操作系统键盘输入到内核处理
比如我们在命令行中输入了ping www.baidu.com,实际上我们每次敲击一次键盘,操作系统都需要通过中断处理机制来处理事件。诶,这里有几个知识点了:
什么叫中断/中断处理?
以单核为例好解释一点,通过将其他处理中的任务暂停下来以满足更高优先级的操作,就是中断。
为什么需要中断处理?
以个人计算来说,我们最大的需求除了有一台性能牛叉的计算机,还需要让计算机能够快速的,准确的响应我们的操作,比如输入一个“我爱你”,如果让别人先发过去了,那你的爱情不就没了吗?所以敲击键盘表白时,我们希望操作系统能够快速响应并发出消息,但是他要是同时也在处理其他任务怎么办呢?那就把其他任务暂时中断了吧,等我的表白发出去了,你再处理不迟
中断处理包含了哪些内容?
从键盘到内核的过程
1:用户输入
用户在键盘打字,每敲击一次键盘,都会触发一个电信号和一个扫描码
2:中断控制器
将电信号和扫描码送入中断控制器的输入引脚中
3:电信号给内核
之后中断控制器会给处理器发出一个中断信号。其中电信号一般会通过中断处理器映射为一个中断值,不同的中断值会有不同的IRQ线处理。扫描码则对应的是每个键,具体的scan code table可以参考:keyboard scan code 表 - JavaShuo
外部中断(External Interrupts):这是最常见的中断类型,用于处理外部设备的中断。它们可以是硬件设备(如网卡、声卡等)或软件生成的中断。在x86架构中,IRQ 0至15用于外部中断。
时钟中断(Timer Interrupts):这是由系统时钟定期触发的中断。它们用于维护系统的计时器,调度任务等。在x86架构中,IRQ 0被系统时钟使用。
键盘中断(Keyboard Interrupts):这是用于处理键盘输入的中断。键盘的按下和释放动作会触发该中断。在x86架构中,IRQ 1被键盘使用。
硬盘中断(Disk Interrupts):这是用于处理硬盘输入/输出操作的中断。当硬盘完成一个输入/输出操作时,会触发该中断。在x86架构中,IRQ 14和IRQ 15被硬盘使用。
网络中断(Network Interrupts):这是用于处理网络输入/输出操作的中断。当网络数据包到达或发送完毕时,会触发该中断。具体使用的IRQ类型取决于网络硬件设备。
USB中断(USB Interrupts):这是用于处理USB设备的中断。当USB设备插入或拔出时,会触发该中断。具体使用的IRQ类型取决于USB控制器的配置
4:内核运行中断处理程序
内核接收到一个中断电信号时,会执行一个中断处理程序。而这个中断处理程序是设备驱动程序中一部分。设备驱动程序是为设备和内核之间的通信提供服务的,不然内核没法识别或者感知设备的动作。撰写设备驱动程序会在后面也说到。整理一下思路,每个设备会有自己的设备驱动程序,其中会有一个中断处理程序用来告知内核此时设备想要与你沟通。内核收到通知并在中断上下文中运行该中断处理程序。
1:设备程序会把中断处理程序注册到指定的IRQ中断线上,以随时响应来自设备的要求。也就是上图中的handle_IRQ_event部分。
2:我们经常会听到一个进程上下文,这个和中断上下文没有关系。进程上下文是用户程序需要调用内核的一些函数时出现的。而中断上下文则是设备要求内核响应其动作时出现的。
5:中断处理程序执行
中断处理程序开始处理设备的要求动作,比如响应键盘或者读取网卡缓存的内容。整个过程是不能被中断的。同时又不能执行得太久,不然操作系统就卡了,不能处理别的事了。
那就有个问题了,我们要求中断处理程序需要快速的响应,快速的释放,但是它可能又要面对复杂的过程或者海量的数据还处理,怎么办呢?拆开吧
6:中断处理程序上部分
拆成了两部分,首先是急速模式,需要尽快完成,这部分由中断处理程序完成。剩下的成为下半部分,无论有多少事都没关系,可以慢慢处理。
以键盘为例的不能很好的体现下半部分的工作量,我们可以以网卡为例。
当网卡收到信息时,因为网卡上的缓存大小固定,所以这部分就需要快速的往内存里面搬运,不然后面再进来的数据就会被丢弃了。于是中断处理程序的上半部分咔咔的搬数据,办完了之后,这个中断就退出来,将内核的控制权交给中断前的程序。
7:剩下的下半部分
搬过来的数据后面自然会有其他程序接管处理,这部分就和内核调度相关了,调度逻辑大致是按照进程的优先级等因素并使用一定的算法,分配每个进程的时间片,让用户程序跑起来。按下不表
大致的过程就是这样了,接下来介绍一下中断上下文。
前面说中断上下文则是设备要求内核响应其动作时出现的,而它的出现是需要把其他的用户程序中断,而自己又不能中断。原则上不允许执行的太久,所以他需要快速的执行。然后快速的释放资源。
由于我们的例子是键盘输入,所以下半部分没什么内容,就是CPU给显卡,显卡来显示。