ARMLinux中断源码分析2中断处理流程.docx
《ARMLinux中断源码分析2中断处理流程.docx》由会员分享,可在线阅读,更多相关《ARMLinux中断源码分析2中断处理流程.docx(50页珍藏版)》请在三一办公上搜索。
1、ARM Linux中断源码分析(2 )中断处理流程ARM支持7类异常中断,所以中断向量表设8个条目,每个条目4字 节,共32字节。异常名称中断向量异常中断模式优先级复位0x0特权模式1未定义的指令0x4未定义指令中止模式6软件中断0x8特权模式6指令预取中止0x0c中止模式5数据访问中止0x10中止模式2保留0x14外部中断请求IRQ0x18IRQ模式4快速中断请求FIQ0x1cFIQ模式3回顾第一节所讲的内容,当一个异常或中断发生时,处理器会将PC设置为特定地址,从而跳转到已经初始化好的异常向量表。因此,要理清中断处理流程,先从异常向量表开始。对于ARM Linux而言,异常向量表和异常处理
2、程序都存在arch/arm/kernel/entry_armv.S 汇编文件中。vector异常向量表点击(此处)折叠或打开1 .globl_.vectors_start vectors start: 2.3swi3.SYS_ERROR04.bvector_und + stubs_offset5ldr5.pc, .LCvswi + stubs_offset6.bvector_pabt + stubs_offset7.bvector_dabt + stubs_offset8.bvector_addrexcptn + stubs_offset9.bctor_irqvector_irq + stub
3、s_offset 中断入口,veb10.11.vector_fiq + stubs_offset12. globl-L vectors end:13._vectors_endvector_irq+stubs_offset为中断的入口点,此处之所以要加上stubs_offset,是为了实现位置无关编程。首先分析一下.equ stubs_offset, _vectors_start + 0x200 - _stubs_start在第3节中已经提到,内核启动时会将异常向量表拷贝到0xFFFF_0000,将异常向量处理程序的stub拷贝到0xFFFF_0200。图5-1描述了异常向量表和异常处理程序搬移
4、前后的内存布局。搬移后vectors itart X图5-1异常向量表和异常处理程序搬移前后对比当汇编器看到B指令后会把要跳转的标签转化为相对于当前PC 的偏移量(32M)写入指令码。由于内核启动时中断向量表和 stubs都发生了代码搬移,所以如果中断向量表中仍然写成b vector_irq,那么实际执行的时候就无法跳转到搬移后的 vector_irq处,因为指令码里写的是原来的偏移量,所以需要把指 令码中的偏移量写成搬移后的。设搬移后的偏移量为offset,如图 5-1所示,offset = L1+L2=0x200 - (irq_PC_X - vectors_start_X) + (vect
5、or_irq_X - stubs_start_X)=0x200 - (irq_PC - vectors_start) + (vector_irq - stubs_start)=0x200 - irq_PC + vectors_start + vector_irq - stubs_start= vector_irq + (vectors_start + 0x200 -stubs_start) - irq_PC令 stubs_offset = vectors_start + 0x200 -stubs_start贝U offset = vector_irq + stubs_offset - irq_
6、PC,所以中断 入口点为 “bvector_irq + stubs_offset”,其中减去irq_PC是由汇编器在编译时完成的。vector_irq处理函数在分析vector_irq处理函数之前,先了解一下当一个异常或中 断导致处理器模式改变时,ARM处理器内核的处理流程如下图所 示:R14_tior_made return link= CPSRCPSR4;0J = exception rode numberCPSR5 m 0卜 Execute in ASM state */if = Res.et or FIQ tlienCPSRL& * 1/* Oisable fast interrupt
7、s/* else CPSS6 is unthariged */CPSR7J = 1h Msabk fiorm-al interrupts */If cexception_niode != UNDEF or 5WI tlienCPSRSJ,1h sable Imprecise aborts W6 otil/) 7/A else CPSRS is unchanged +/CPSR93 = CPlregLEEbit/* Endianness on exception entryPC = exception vector address中断刚发生时,处理器处于irq模式。在stubs_start和st
8、ubs_end之间找到vector_irq处理函数的定义vector_stub irq, IRQ_MODE, 4,其中 vector_stub 是一个宏(在 arch/arm/kernel/entry_armv.S中定义),为了分析更直观,我们 将vector_stub宏展开如下:1./*2.Interrupt dispatcher3.*/4.vector_irq:5.6.sublr, lr, #4 在中断发生时,lr指向最后.if 4执行的指令地址加上8。只有在当前指令执行完毕后,才进入中断 处理,所以返回地址应指向下一条指令,即(lr-4)处。7.endif9.10. Save r0,lr
9、_ (parent PC)and spsr_11. (parentCPSR)13.stmiasp, r0, lr保存r0,lr到irq模式下的栈中14.mrslr, spsr15.strlr, sp, #8保存spsr到irq模式下的栈中16.17.18. Preparefor SVC32 mode. IRQsremain disabled.19.20.mrsr0, cpsr21.eorr0, r0, #( IRQ_MODE八 SVC_MODE) 设12.但未切换置成SVC模式,22.msrspsr_cxsf, r0 保存到spsr_irq 中23.24.25.branch table mus
10、t immediately follow thicode26.27.andlr, lr, #0x0f lr存储着上一个处理器模式的cpsr值,lr = lr & 0x0f取出用于判断发生中断前是用户 态还是核心态的信息,该值用于下面跳转表的索引。28.29.movr0, sp 将irq模式下的sp保存到r0,作为参数传递给即将调用的irq_usr或_irq_svcldrlr, pc, lr, lsl #2 pc 指向当前执行指令地址加8,即跳转表的基址。lr作为索引,由于是4字节对 齐,所以 lr = lr 2.30.31.movspc, lr branch to handler in SVC
11、 mode当mov指令后加“s”且 目标寄存器为pc时,当前模式下的spsr会被复制到cpsr,从而 完成模式切换(从irq模式切换到svc模式)并且跳转到pc指向 的指令继续执行32.33.34.35.36.ENDPROC(vector_irq).longirq_usr0 (USR_26 / USR_32).longirq_invalid 1 (FIQ_26 / FIQ_32).longirq_invalid 2 (IRQ_26 / IRQ_32)irq_svc3 (SVC_26 / SVC_32)38.longirq_invalid 439.longirq_invalid 540.long
12、irq_invalid 641.longirq_invalid 742.longirq_invalid 843.longirq_invalid 944.longirq_invalid a45.longirq_invalid b46.longirq_invalid c47.long_irq_invalid d49.longirq_invaliirq_invali_irq_usr 如果发生中断前处于用户态则进入irq_usr,其定义如下(arch/arm/kernel/entry_armv.S):1.align2.irq_usr:3.usr_entry 保存中断上下文,稍后分析4.kuser_cm
13、pxchg_check5.6.bltrace_hardirqs_off7.#endif#ifdef CONFIG_TRACE_IRQFLAGS8.9.10.ldrr8, tsk, #TI_PREEMPT获取preempt计数器值get_thread_info tsk 获取当前进程的进程描述符中的成员变量thread_info的地址,并将该地址保存到寄存器tsk(r 9)(在 entry-header.S 中定义) #ifdef CONFIG_PREEMPT 如果定义了抢占,增加抢占数值11.addr7, r8, #1reempt加1,标识禁止抢占12.strr7, tsk, #TI_PREEM
14、PT 将加 1 后的结果写入进程内核栈的变量中13 #endif ID.14.irq_handler 调用中断处理程序,稍后分析15. #ifdef CONFIG_PREEMPT16.ldrr0,tsk, #TI_PREEMPT 获取 preempt计数器值17.strr8,tsk, #TI_PREEMPT 将 preempt 恢复到中断前的值18.teqr0,r7 比较中断前后preempt是否相等19.strner0,r0, -r0 如果不等,则产生异常(向地址0写入数据)?20. #endif21 #ifdefCONFIG_TRACE_IRQFLAGS22.bltrace_hardirq
15、s_on23 #endif 3.24.movwhy, #0 r8=025.ret_to_user 中断处理完成,恢复中断上下文并返回中断产生的位置,稍后分析26.UNWIND(.fnend27. ENDPROC(irq_usr)宏定义usr_entry(保护上下文到栈)上面代码中的usr_entry是一个宏定义,主要用于保护上下文到栈中:1.macrousr_entry2.UNWIND(.fnstart3.UNWIND(.cantunwind dont unwind the use4.spacesubsp,sp, #S_FRAME_SIZE ATPCS 中,堆栈被定义为递减式满堆栈,所以首先让
16、sp向下移动#S_FRAME_SIZE(pt_regs 结构体 size),准备向栈中存放数据。此处的sp是sv5.6.stmibsp,r1 - r127.ldmiar0,r1 - r38.addr0,sp, #S_PCefor interlockavoidance9.movr4,#-110.11.strr1,spealr0 copiedc模式下的栈指针。 save the r12. from the exception stack13.14.15.ks on16. We arethe stack:now ready to fill in the remaining blan17. r2 -l
17、r_, already fixed up for correct return/restart18. r3 -spsr_19. r4 -orig_r0 (see pt_regs definition in ptrace.h)20.21. Also,separately save sp_usr and lr_usr22.23.stmiar0,r2 - r424.stmdbr0, sp, lr厂将user模式下的sp和lr保存到svc模式的栈中25.26.27. Enablethe alignment trap while in kernel mode28.29.alignment_trap r0
18、30.31.32. Clear FP to mark the first stack frame33.34.zero_fp35.endm上面的这段代码主要是在填充结构体pt_regs,在include/asm/ptrace.h 中定义:i.structpt_regs 2.long uregs18;3.;4.5.#define6.#define7.#define8.#define9.#define10 #define11 #define12 #define13 #defineARM_cpsruregs16ARM_pcuregs15ARM_lruregs14ARM_spuregs13ARM_ipu
19、regs12ARM_fpuregs11ARM_r10uregs10ARM_r9uregs9ARM_r8uregs8#define ARM_r7uregs7#define ARM_r6uregs6#define ARM_r5uregs5#define ARM_r4uregs4#define ARM_r3uregs3#define ARM_r2uregs2#define ARM_r1uregs1#define ARM_r0uregs0#define ARM_ORIG_r0uregs1714.15.16.17.18.19.20.21.22.usr_entry宏填充pt_regs结构体的过程如图5-2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARMLinux 中断 源码 分析 处理 流程
链接地址:https://www.31ppt.com/p-4882987.html