1.前言
2.异常类型描述
见 ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(1)-EL/ET/ST 一文
3. 异常处理路由对比
AArch32、AArch64架构下IRQ 和Data Abort 异常处理流程图对比.
3.1 IRQ 路由
3.1.1. AArch32 IRQ 路由
图 AArch32 IRQ 路由
3.1.2. AArch64 IRQ 路由
图 AArch64 IRQ路由
图 AArch64 IRQ向量查找
3.2. Data Abort 路由
3.2.1. AArch32 Data Abort 路由
3.2.2. AArch64 Data Abort 路由
4. 源代码异常入口
4.1 C函数入口
异常类型 | AArch32 State | AArch64 State | ||
所在文件 | C 函数 | 所在文件 | C 函数 | |
Und | arm/kernel/traps.c | do_undefinstr | Arm64/kernel/traps.c | do_undefinstr |
Data Abort | arm/mm/fault.c | do_DataAbort | arm64/mm/fault.c | do_mem_abort |
IRQ | arm/kernel/irq.c | asm_do_IRQ | arm64/kernel/irq.c | handle_IRQ |
FIQ | ||||
System Call |
4.2 上报流程图
例举Data Abort 和 IRQ中断的入口流程图
- Data Abort 上报
- IRQ上报
4.3. 异常进入压栈准备
分析64位kernel_entry 压栈代码逻辑(代码路径:kernel/arch/arm64/kernel/entry.S)
压栈准备 | 说明 |
• sp指向 #S_LR – #S_FRAME_SIZE 位置 | #S_FRAME_SIZE是pt_regs结构图的size |
• 依次把x28-x29 … x0-x1 成对压入栈内 | 每压入一对寄存器,sp指针就移动 -16 =((64/8)*2)字节长度,栈是向地址减少方向增长的. |
• 保存sp+#S_FRAME_SIZE数据到x21 | add x21, sp, #SP_FRAME_SIZE |
• 保存elr_el1到x22 | mrs x22, elr_el1 |
• 保存spsr_el1到x23 | mrs x23, spsr_el1 |
• 把lr、x21写入sp+#S_LR地址内存 | 保存lr和x21的数据到指定栈内存位置 |
• 把x22、x23写入sp+#S_PC地址内存 | 保存elr,spsr数据到指定栈内存位置 |
4.4. 栈布局
5. 参考文档
[1] DDI0487A_k_armv8_arm_iss10775.pdf