You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AArch64架构下异常与中断处理及相关疑问解答

AArch64 EL1异常处理常见问题解答

运行环境

我通过以下命令在QEMU中运行AArch64裸机应用:

qemu-system-aarch64 -M virt \
    -cpu cortex-a72 \
    -bios "$(QEMU_PATH)/share/qemu/edk2-aarch64-code.fd" \
    -m 128M \
    -nographic \
    -device loader,file=$(BUILD_DIR)/kernel.elf \
    -device loader,addr=0x40100000,cpu-num=0

当前应用运行在EL1特权级,配置异常向量表时参考了如下示例代码:

.text
.global vector_table
.balign 2048
vector_table:
    b .
.balign 0x80
    b .
.balign 0x80
    b .
.balign 0x80
    b .
...

adr x0, vector_table
msr VBAR_EL2, x0

已知需将vector_table地址写入VBAR_EL1寄存器指定异常入口,但仍有三个疑问:


1. 为何向量表要按2048字节对齐?

AArch64的异常向量表总大小固定为2048字节(0x800),包含16个异常入口,每个入口占128字节(0x80)。CPU寻址向量表时,会直接忽略VBAR_ELx寄存器的低11位(因为2^11=2048),只取高地址位作为向量表的起始基地址。如果不按2048字节对齐,低11位不为0,CPU会自动截断这部分,导致向量表实际起始地址和你设置的不一致,直接打乱异常入口的寻址逻辑。这是硬件强制要求,必须按此对齐才能让CPU正确定位每个异常入口。

2. 为何入口点偏移为0x80,而官方文档中的偏移不同?

AArch64的向量表有两种布局模式,针对不同特权级的异常划分了不同的入口位置,但每个异常入口块的固定大小都是128字节(0x80)。你看到的.balign 0x80是在为每个入口块预留固定空间,不管当前入口写了多少代码,都对齐到下一个0x80的位置,保证下一个异常入口的地址准确。

而官方文档里的"不同偏移",指的是不同类型异常在向量表中的相对位置(比如EL1的同步异常在起始地址+0x0,IRQ在+0x80,FIQ在+0x100),但每个入口块的间隔确实是0x80。教程里的写法只是先给每个入口块占位,后续再填充具体的处理代码。

3. EL1级别需处理哪些异常和中断?

EL1是操作系统内核运行的特权级,需要处理的异常和中断主要分为四类:

  • 同步异常:用户态(EL0)触发的系统调用(SVC指令)、非法指令、内存访问错误(空指针、权限不足)、未定义指令、除数为零等,这类异常是CPU执行指令时直接触发的,内核需要处理或给用户进程返回错误。
  • IRQ中断:外设触发的常规中断,比如定时器中断、UART串口输入、网卡数据包到达、键盘输入等,是外部设备主动向CPU发送的信号,内核需要响应并处理对应设备事件。
  • FIQ中断:快速中断,优先级高于IRQ,用于处理响应时间要求极高的场景(比如实时系统的紧急事件),部分硬件会合并处理FIQ和IRQ,但AArch64硬件仍保留该机制。
  • SError中断:系统错误异常,比如内存ECC错误、总线错误等硬件层面的严重故障,内核需要处理这类致命或可恢复的硬件问题。

另外,EL0没有权限处理任何异常,所有来自EL0的异常都会自动转到EL1处理。


内容的提问来源于stack exchange,提问作者Denis Steinman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:39:51