arm64的异常向量表vectors中设置了各种异常的入口,目前有效的异常入口有两个同步异常el0_sync,el1_sync和两个异步异常el0_irq,el1_irq,其他异常入口暂时都invalid。中断属于异步异常,所以本文重点关注el0_irq和el1_irq。
通过上图,我们可以看出中断的处理分为三个部分,保护现场,中断处理,恢复现场。其中el0_irq和el1_irq的具体实现略有不同,但处理流程大致是相同的。接下来我们以el0_irq为例对上面三个步骤进行梳理。
将CPU寄存器按照pt_regs结构体的定义将第一现场保存到栈上。
保存PSTATE到SPSR_ELx寄存器;
将PSTATE中的D A I F全部屏蔽;
保存PC寄存器的值到ELR_ELx寄存器;
如上图,大概主要有如下三个动作:
进入中断栈;
执行中断控制器的handle_arch_irq;
退出中断栈;
在处理之前我们先看下什么叫做中断栈。
中断栈用来保存中断的上下文。
中断栈的创建:内核启动时中会去为每个cpu创建一个per cpu的中断栈:start_kernel->init_IRQ->init_irq_stacks
中断栈的使用:中断发生和退出的时候调用irq_stack_entry和irq_stack_exit来进入和退出中断栈。
主要分三步:
disable中断;
检查在退出中断前有没有需要处理事情,如调度、信号处理等。
将之前压栈的pt_regs弹出,恢复现场。
5T技术资源大放送!包括但不限于:C/C++,Arm, Linux,Android,人工智能,单片机,树莓派,等等。在公众号内回复「peter」,即可免费获取!!
记得点击分享、赞和在看,给我充点儿电吧