1、Cortex-A核的处理器工作模式
Monitor Mode : 安全监控模式,主要运行安全相关的代码。
PHY_mode : 超级管理模式,主要是用于虚拟化技术的支持。
2、ARM处理器的异常
中断属于异常中的一种。导致处理器从用户模式切换到异常模式的事件通常异常源。
异常模式 | 异常源 | 备注 |
---|---|---|
FIQ异常模式 | FIQ类型的异常源 | FIQ类型的异常源指的是一类,不是某一个。 |
IRQ异常模式 | IRQ类型的异常源 | IRQ类型的异常源指的是一类,比如按键中断,定时器中断,串口中断,.... |
SVC模式 | Reset信号 | 系统发送复位时,复位按键,看门狗复位,上电复位。 |
软中断指令(swi) | swi 软中端号, 软中断号的范围为0 ~ (2^24-1) | |
Abort模式 | data Abort类型异常源 | 取数据发送异常, |
Prefetch Abort类型异常源 | 取指令发送异常。 | |
Undef模式 | undef类型异常源 | 译码器翻译指令时,无法解析指令,则是未定义的异常 |
总结:5种异常模式对应着7中异常源,异常源具有优先级,复位的优先级是最高。
3、异常的处理过程
当发生异常时,程序切换到异常处理程序中执行,分析异常的处理过程。
4、swi软中断指令
start.s文件:
@ 启动文件
.text
.global _start
_start:
@ 1. 构建异常向量表
b reset
b undef_handler
b swi_handler
b pref_handler
b data_handler
b .
b irq_handler
b fiq_handler
@ 异常处理程序的入口函数
reset:
@ 2. 初始化SVC模式下的栈指针,
ldr sp, =0x40000800
@ 3. 从svc模式切换到user模式
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x10
msr cpsr, r0
@ 4. 初始化user模式下的栈指针
ldr sp, =0x40000700
mov r0, #0x3
mov r1, #0x4
@ 软中断指令
@ 执行软中断指令,CPU自动完成4大步3小步保存现场,
/*
1. 保存cpsr到spsr_<mode>
2. 修改cpsr
2.1 切换到ARM状态
2.2 禁止中断位,根据需要
2.3 修改模式位,切换到对应的异常模式
3. 保存返回地址到LR_<mode>
4. 修改PC值执行异常向量表中
*/
swi 2
add r2, r0, r1 @ r2 = r0 + r1 = 0x7
nop
nop
b stop
undef_handler:
@ 软中断的异常处理程序
swi_handler:
stmfd sp!, {r0-r1, lr} @ 压栈保存现场
mov r0, #9
mov r1, #15
@ 将lr中的值恢复给PC
@ ^ : 恢复spsr_<mode>到cpsr中
ldmfd sp!, {r0-r1, pc}^ @ 出栈恢复现场
pref_handler:
data_handler:
irq_handler:
fiq_handler:
stop:
b stop
.end
@ 启动文件
.text
.global _start
_start:
@ 1. 构建异常向量表
b reset
ldr pc, __undef_handler
ldr pc, __swi_handler
ldr pc, __pref_handler
ldr pc, __data_handler
b .
ldr pc, __irq_handler
ldr pc, __fiq_handler
@ .word : 申请4字节的空间存放一个32位的数据
/* __undef_handler指针变量名,申请4字节空间,
存undef_handler函数的入口地址 */
__undef_handler:
.word undef_handler
__swi_handler:
.word swi_handler
__pref_handler:
.word pref_handler
__data_handler:
.word data_handler
__irq_handler:
.word irq_handler
__fiq_handler:
.word fiq_handler
@ 异常处理程序的入口函数
reset:
@ 2. 初始化SVC模式下的栈指针,
ldr sp, =0x40000800
@ 3. 从svc模式切换到user模式
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x10
msr cpsr, r0
@ 4. 初始化user模式下的栈指针
ldr sp, =0x40000700
mov r0, #0x3
mov r1, #0x4
@ 软中断指令
@ 执行软中断指令,CPU自动完成4大步3小步保存现场,
/*
1. 保存cpsr到spsr_<mode>
2. 修改cpsr
2.1 切换到ARM状态
2.2 禁止中断位,根据需要
2.3 修改模式位,切换到对应的异常模式
3. 保存返回地址到LR_<mode>
4. 修改PC值执行异常向量表中
*/
swi 2
add r2, r0, r1 @ r2 = r0 + r1 = 0x7
nop
nop
b stop
undef_handler:
@ 软中断的异常处理程序
swi_handler:
stmfd sp!, {r0-r1, lr} @ 压栈保存现场
mov r0, #9
mov r1, #15
@ 将lr中的值恢复给PC
@ ^ : 恢复spsr_<mode>到cpsr中
ldmfd sp!, {r0-r1, pc}^ @ 出栈恢复现场
pref_handler:
data_handler:
irq_handler:
fiq_handler:
stop:
b stop
.end
@ 启动文件
.text
.global _start
_start:
@ 1. 构建异常向量表
b reset
ldr pc, __undef_handler
ldr pc, __swi_handler
ldr pc, __pref_handler
ldr pc, __data_handler
b .
ldr pc, __irq_handler
ldr pc, __fiq_handler
@ .word : 申请4字节的空间存放一个32位的数据
/* __undef_handler指针变量名,申请4字节空间,
存undef_handler函数的入口地址 */
__undef_handler:
.word undef_handler
__swi_handler:
.word swi_handler
__pref_handler:
.word pref_handler
__data_handler:
.word data_handler
__irq_handler:
.word irq_handler
__fiq_handler:
.word fiq_handler
@ 异常处理程序的入口函数
reset:
@ 2. 初始化SVC模式下的栈指针,
ldr sp, =0x40000800
@ 3. 从svc模式切换到user模式
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x10
msr cpsr, r0
@ 4. 初始化user模式下的栈指针
ldr sp, =0x40000700
mov r0, #0x3
mov r1, #0x4
@ 软中断指令
@ 执行软中断指令,CPU自动完成4大步3小步保存现场,
/*
1. 保存cpsr到spsr_<mode>
2. 修改cpsr
2.1 切换到ARM状态
2.2 禁止中断位,根据需要
2.3 修改模式位,切换到对应的异常模式
3. 保存返回地址到LR_<mode>
4. 修改PC值执行异常向量表中
*/
swi 2
swi 3
swi 4
add r2, r0, r1 @ r2 = r0 + r1 = 0x7
nop
nop
b stop
undef_handler:
@ 软中断的异常处理程序
swi_handler:
stmfd sp!, {r0-r1, lr} @ 压栈保存现场
@ 获取软中断号
sub r3, lr, #4
ldr r4, [r3]
bic r4, r4, #0xFF000000
cmp r4, #2
moveq r0, #9
cmp r4, #3
moveq r1, #15
cmp r4, #4
moveq r0, #6
moveq r1, #12
@ 将lr中的值恢复给PC
@ ^ : 恢复spsr_<mode>到cpsr中
ldmfd sp!, {r0-r1, pc}^ @ 出栈恢复现场
pref_handler:
data_handler:
irq_handler:
fiq_handler:
stop:
b stop
.end