ARM Linux中断机制分析
异常向量表的拷贝过程用图表示比较清晰,如下图所示:
图一 向量表搬移及offset偏移量计算示图
图一说明:上面两条有方向的横线,横线方向代表地址生长方向,下面那个是Code/Load视图,是搬移前的代码在生成的二进制内核中的组织情况,上面的Exec view是代码在内存中开始执行后的分配情况。
2.linux对ARM异常、中断的处理流程
2.1当IRQ发生时,硬件完成的操作
R14_irq= address of next instruction to be executed + 4/*将寄存器lr_mode设置成返回地址*/
SPSR_irq = CPSR /*保存处理器当前状态、中断屏蔽位以及各条件标志位*/
CPSR[4:0] = 0b10010 /*设置当前程序状态寄存器CPSR中相应的位进入IRQ模式*/
CPSR[5] = 0 /*在ARM状态执行*/
/*CPSR[6] 不变*/
CPSR[7] = 1 /*禁止正常中断*/
If high vectors configured then
PC=0xFFFF0018 /*将程序计数器(PC)值设置成该异常中断的中断向量地址,从
*而跳转到相应的异常中断处理程序处执行,对于ARMv7向量表普遍是0xFFFF0018
*/
else
PC=0x00000018
2.2 指令流跳转过程
以上CPU操作完成后,PC跳转到0xFFFF0018,该地址就是指令W(b) vector_irq + stubs_offset所在地址。然后跳转到vector_stub irq,IRQ_MODE, 4,去执行相应的异常、中断处理函数。
接下来具体看代码:
.globl __vectors_start //异常向量表开始0xFFFF0000 __vectors_start: ARM( swi SYS_ERROR0 ) THUMB( svc #0 ) THUMB( nop ) W(b) vector_und + stubs_offset W(ldr) pc, .LCvswi + stubs_offset W(b) vector_pabt + stubs_offset W(b) vector_dabt + stubs_offset W(b) vector_addrexcptn + stubs_offset W(b) vector_irq + stubs_offset //中断发生后的跳转地址0xFFFF0018 W(b) vector_fiq + stubs_offset .globl __vectors_end __vectors_end: |
stubs_offset只是个偏移量,用来修正跳转地址的,主要的操作是vector_irq执行。vector_irq是由宏vector_stub irq,IRQ_MODE,4(IRQ_MODE在include\asm\ptrace.h中定义:0x12)生成。以下是vector_irq生成后的代码(汇编代码中,@开始的语句、//、//都代表注释):
.align 5 vector_irq: sub lr, lr, 4//因为异常发生时,cpu将pc地址+4赋值给lr,这里做修正。 @ Save r0, lr_ @ (parent CPSR) @ stmia sp, {r0, lr}//保存r0, lr,到irq堆栈中(每个异常都有属于自己的堆栈) mrs lr, spsr //lr保存spsr_irq的值,即usr状态的cpsr的值(见2.1) str lr, [sp, #8]//保存spsr到[sp+8]处 @ Prepare for SVC32 mode. IRQs remain disabled. @ mrs r0, cpsr eor r0, r0,#( IRQ_MODE ^ SVC_MODE| PSR_ISETSTATE) // PSR_ISETSTATE:选择ARM/Thumb指令集 msr spsr_cxsf, r0//这里的cxsf表示从低到高分别占用的4个8bit的数据域 |
异或运算是可以交换位置的,也即A^B^C等价于A^C^B。所以这里的r0^( IRQ_MODE ^ SVC_MODE| PSR_ISETSTATE)等价于r0^ IRQ_MODE ^SVC_MODE,由于r0的低5位模式位与IRQ_MODE相同,所以r0^ IRQ_MODE的运算结果的低5位全被清零,然后再^SVC_MODE,也即低5位被设置为SV
ARMLinux中断机 相关文章:
- ARM Linux中断机制之中断的初始化(11-10)
- ARM Linux中断机制之中断的申请(11-10)
- ARM Linux中断机制之中断处理(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)