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