本文主要针对ARM cortex-A9处理器的研究。
ARM采用的是32位的RISC架构
数据类型:
- Byte 字节 8bit
- Halfword 半字 16bit(v4以上版本)
- Word 字 32bit
ARM内核只提供FIQ和IRQ两种中断向量。
ARM支持大端模式和小端模式两种存储方式。
工作模式:
- User:用户模式
- System:系统模式,和User模式相同寄存器的模式,运行特权级操作
- FIQ:快速中断,高优先级
- IRQ:外部中断模式,低优先级中断
- SVC:特权模式,复位
- Abort:数据访问终止模式,存取异常,用于虚拟存储和存储保护
- Undef:未定义模式,执行未定义指令的模式,有时通过软件仿真协处理器硬件的工作模式
- Monitor:监控模式,安全模式和非安全模式间切换
异常源及其优先级:
- Reset:复位异常
- Data Abort:数据访问终止异常,从内存中进行数据读写,发生错误时候产生
- FIQ:快速中断异常
- IRQ:外部中断异常
- Abort :预取指令终止异常
- SWI:软中断异常
- Undef:未定义指令异常
异常对应的工作模式及LR的返回值
异常 | 工作模式 | 返回 | 用途 |
复位异常 | SVC | - | - |
数据访问终止异常 | Abort | LR-8 | 指向导致数据终止的指令 |
快速中断异常 | FIQ | LR-4 | 指向发生异常正在执行的指令 |
外部中断异常 | IRQ | LR-4 | 指向发生异常正在执行的指令 |
预取指令终止异常 | Abort | LR-4 | 指向导致预取指令异常的指令 |
软中断异常 | SVC | LR | 指向SWI指令的下一条语句 |
未定义指令异常 | Undef | LR | 指向未定义指令的下一条语句 |
中断响应流程:
- 备份CPSR给SPSR
- 修改CPSR:切换工作状态ARM态,切换异常对应的工作模式,使能禁用IRQ和FIQ
- 保存异常返回地址:LR
- 修改PC值跳转给异常处理程序
软中断处理流程:
@1.创建异常向量表
b reset_handle
b undef_handle
b swi_handle
b prefetch_handle
b data_handle
nop
b irq_handle
b fiq_handle
@创建栈
.data
stack_head: @SVC栈
.space 64
stack_end:
user_stack_head: @user栈
.space 128
user_stack_end:
@2.启动
reset_handle:
ldr sp, = stack_end @初始化SVN下的栈
@切换到用户模式
mrs r0, cpsr @cpsr状态寄存器读取,保存到r0中
bic r0, #0xff @对CPSR操作流程:先读取旧的值,在针对读的值进行修改,最后回写
orr r0, #0x10
msr cpsr, r0
ldr r0, =user_stack_end @初始化User下的栈
mov sp, r0
mov r0, #1
mov r1, #2
swi #16
swi_handle:
stmfd sp!, {r0-r2,lr} @压栈保护现场
...
mov r0, lr
sub r0, #4 @获取SWI机器指令地址
ldr r1, [r0] @读取SWI机器指令
bic r1, #0xff000000 @读取SWI中断号
mov r0, r1 @看下中断号
bl swi_c_handle @调用更加详细的C语言处理程序
ldmfd sp!, {r0-r2,pc}^ @出栈还原、跳转、恢复CPSR
掌握中断跳转的实现方法还是必要的,可以从本质上理解每个操作。