9.2 Interrupt硬件部分

今天课程的主要内容是中断。中断对应的场景很简单,就是硬件想要得到操作系统的关注。例如网卡收到了一个packet,网卡会生成一个中断;用户通过键盘按下了一个按键,键盘会产生一个中断。操作系统需要做的是,保存当前的工作,处理中断,处理完成之后再恢复之前的工作。这里的保存和恢复工作,与我们之前看到的系统调用过程(注,详见lec06)非常相似。所以系统调用,page fault,中断,都使用相同的机制。

但是中断又有一些不一样的地方,这就是为什么我们要花一节课的时间来讲它。中断与系统调用主要有3个小的差别:

  1. asynchronous。当硬件生成中断时,Interrupt handler与当前运行的进程在CPU上没有任何关联。但如果是系统调用的话,系统调用发生在运行进程的context下。

  2. concurrency。我们这节课会稍微介绍并发,在下一节课,我们会介绍更多并发相关的内容。对于中断来说,CPU和生成中断的设备是并行的在运行。网卡自己独立的处理来自网络的packet,然后在某个时间点产生中断,但是同时,CPU也在运行。所以我们在CPU和设备之间是真正的并行的,我们必须管理这里的并行。

  3. program device。我们这节课主要关注外部设备,例如网卡,UART,而这些设备需要被编程。每个设备都有一个编程手册,就像RISC-V有一个包含了指令和寄存器的手册一样。设备的编程手册包含了它有什么样的寄存器,它能执行什么样的操作,在读写控制寄存器的时候,设备会如何响应。不过通常来说,设备的手册不如RISC-V的手册清晰,这会使得对于设备的编程会更加复杂。

我们这节课的内容非常的简单。我们会讨论

  • console中的提示符“$ ”是如何显示出来的

  • 如果你在键盘输入“ls”,这些字符是怎么最终在console中显示出来的。

这节课剩下的内容这两部分,以及背后相关的机制。

我们首先要关心的是,中断是从哪里产生的?因为我们主要关心的是外部设备的中断,而不是定时器中断或者软件中断。外设中断来自于主板上的设备,下图是一个SiFive主板,如果你查看这个主板,你可以发现有大量的设备连接在或者可以连接到这个主板上。

主板可以连接以太网卡,MicroUSB,MicroSD等,主板上的各种线路将外设和CPU连接在一起。这节课的大部分内容都会介绍当设备产生中断时CPU会发生什么,以及如何从设备读写数据。

下图是来自于SiFive有关处理器的文档,图中的右侧是各种各样的设备,例如UART0。我们在之前的课程已经知道UART0会映射到内核内存地址的某处,而所有的物理内存都映射在地址空间的0x80000000之上。(注,详见4.5)。类似于读写内存,通过向相应的设备地址执行load/store指令,我们就可以对例如UART的设备进行编程。

所有的设备都连接到处理器上,处理器上是通过Platform Level Interrupt Control,简称PLIC来处理设备中断。PLIC会管理来自于外设的中断。如果我们再进一步深入的查看PLIC的结构图,

从左上角可以看出,我们有53个不同的来自于设备的中断。这些中断到达PLIC之后,PLIC会路由这些中断。图的右下角是CPU的核,PLIC会将中断路由到某一个CPU的核。如果所有的CPU核都正在处理中断,PLIC会保留中断直到有一个CPU核可以用来处理中断。所以PLIC需要保存一些内部数据来跟踪中断的状态。

如果你看过了文档,这里的具体流程是:

  • PLIC会通知当前有一个待处理的中断

  • 其中一个CPU核会Claim接收中断,这样PLIC就不会把中断发给其他的CPU处理

  • CPU核处理完中断之后,CPU会通知PLIC

  • PLIC将不再保存中断的信息

学生提问:PLIC有没有什么机制能确保中断一定被处理?

Frans教授:这里取决于内核以什么样的方式来对PLIC进行编程。PLIC只是分发中断,而内核需要对PLIC进行编程来告诉它中断应该分发到哪。实际上,内核可以对中断优先级进行编程,这里非常的灵活。

(注,以下提问来自课程结束部分,与本节内容时间上不连续)

学生提问:当UART触发中断的时候,所有的CPU核都能收到中断吗?

Frans教授:取决于你如何对PLIC进行编程。对于XV6来说,所有的CPU都能收到中断,但是只有一个CPU会Claim相应的中断。

以上是有关中断的硬件部分,我们接下来介绍中断相关的软件部分。

Last updated