总览
中断部分涉及内容较多,但是总体思路于教科书的一致,简单的来说就是:中断源发出中断->处理器响应中断->保存当前执行现场->执行对应的中断处理函数->恢复执行现场
。目前因为是单核,所以中断相关的处理会简单很多,但是也遗留下许多问题待思考
- 1、中断源与CPU之间的交互?
- 2、如何保存与恢复当前执行现场?
- 3、如何设置中断处理总入口?
中断源与CPU之间的交互
简单来说,中断源与CPU之间需要一个媒介来进行中断请求处理,被称作中断处理器。接收到中断请求之后,cpu要及时应答,在处理完成之后告知中断处理器结束。在intel 80386处理器一般是二级级联的8259A,树莓派2b的bcm2835中断处理器。涉及到以下内容:
- 1、初始化,禁止响应所有中断
- 2、启用中断
- 3、禁用中断
- 4、通知中断响应完毕(
end of interrupt
)
例子可以参考:arch/x86/kernel/x86_pic.c
当前执行现场的保存与恢复
这一部分是由cpu与内核一起完成的,一般是cpu保存最基本的一些寄存器(在当前中断发生的栈,或者其他方式),然后跳转到内核的中断处理进程,进行下一步的执行现场的保存以及最后的恢复动作。
例子可以参考:arch/x86/kernel/x86_trap_asm.S
和 arch/x86/kernel/x86_vector.S
假设i386
中断发生的时候,未发生权限特权变化,则是在原来的栈基础上压入EFLAGS/CS/EIP
三个寄存器而已。需要内核自己保存相关的通用寄存器状态,最后再调用对应的中断处理函数。
而armv7
较为奇怪,它提供的方式是直接将相关的寄存器banked
掉,在使用相关的汇编指令能正确恢复回去。
中断处理总入口的设置
i386
是通过设置idt
寄存器,见arch/x86/kernel/x86_trap.c
中的trap_init
函数,armv7
的还是比较奇怪,它是默认要求中断处理总入口放在0x0
或者0xFFFF0000
(CP15 Vector Base Address registers
)
未完待续……