- 1 建立异常向量表
- 2 示例
- 3 使能中断
异常的初始化
就是建立异常向量表
并使能异步异常
(可以理解为中断
)的过程。
1 建立异常向量表
在ARMv8架构的AArch32状态下启动处理器的时候,SCTLR.V
决定了reset向量的位置,这与AArch64状态下是不同的(AArch64状态下,reset不再是向量表的一部分):
SCTLR.V=0
,处理器从0x00000000
启动;SCTLR.V=0
,处理器从0xFFFF0000
启动。
可以通过硬件输入管脚VINITHI
设置SCTLR.V
的复位值。
除了reset向量之外,其余的异常都要通过异常向量表进行查找,而这些向量表的位置可以通过可编程向量表基地址寄存器进行用户自定义。通俗的讲,就是这些异常向量表放在任何位置都可以,你只需要把它的起始基地址写入到基地址寄存器中,处理器的硬件自动就能找到。这类表有4个,分别是:
- 向量表基地址寄存器(VBAR)(安全模式使用);
- Monitor向量表基地址寄存器(MVBAR);
- Hyp向量表基地址寄存器(HVBAR);
- VBAR(非安全模式使用);
2 示例
示例1
:展示了一个典型的32位状态下的向量表,包含reset和其它异常
.balign 0x20
vector_table_base_address:
B reset_handler
B undefined_handler
B svc_handler
B prefetch_handler
B data_handler
NOP
B IRQ_handler
// 还可以把FIQ handler的代码添加在这儿
4个向量表中的表项可以不同。具体可以参考ARM® Architecture Reference Manual ARMv8, for ARMv8-A architecture
规范中的Exception vectors and the exception base address
部分内容。
必须初始化4个向量表,也就是在使用向量表之前,需要设置4个向量表基地址寄存器。向量表的基地址必须是32字节对齐的。
示例2
:展示了reset之后,如何初始化VBAR
和MVBAR
LDR R1, =secure_vector_table_base_address
MCR P15, 0, R1, C12, C0, 0 // 初始化VBAR(Secure)
LDR R1, =monitor_vector_table_base_address
MCR P15, 0, R1, C12, C0, 1 // 初始化MVBAR
3 使能中断
异常分为异步和同步异常,异步异常通俗的讲就是我们常规意义上的
中断
,同步异常就是我们常规意义上的异常
异步异常包括abort
、IRQ
和FIQ
,我们称之为广义上的中断。reset之后,可以通过设置CPSR.{A,I,F}
标志位进行屏蔽。因此,如果想要捕获 abort
、IRQ
和FIQ
,必须将CPSR.{A,I,F}
标志位清零。
另外,为了使能中断,还必须要初始化外部中断控制器(GIC),发送中断信号给处理器。关于GIC控制器的初始化可以参考GICv2或v3相关手册。
示例3
:展示了如何使能abort
、IRQ
和FIQ
// 使能异步abort、中断和快速中断
CPSIE aif
CPSIE
快速开关中断的命令:a,异步abort;i,中断;f,快速中断。需要注意的是,该命令只是通知处理器不接收中断信号而异,并没有控制GIC通用中断控制器,中断该发生还是发生。