我有一个简单的裸机应用程序,可以通过以下命令在 Qemu 中启动:
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
现在我正在尝试处理异常和中断,但不幸的是,我对这个主题的了解越多,我就越不了解如何处理它们。
嗯,
aarch64
为我们提供了 4 个级别:EL3 -> EL0。我检查过我的应用程序在 Qemu 中以 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
寄存器中(因为我的应用程序在 EL1 级别运行)。
据我了解,CPU 将使用 VBAR_EL1 寄存器来查找合适的处理程序的地址并执行它。
不幸的是,仅此而已!我的理解到此结束,接下来只有问题了……
如果有人能用简单的语言解释我将非常感激。
- 作者为什么将表格对齐到2048?
因为手册上说低11位是
RES0
,所以表必须对齐到0x800字节:
- 尽管官方表上还有其他偏移量,但为什么他将入口点偏移 0x80?
因为0x80+0x80 = 0x100、0x80+0x80+0x80 = 0x180等
- 我应该在 EL1 级别处理哪些异常和中断?
全部?
如果您不希望遇到任何异常,那么至少应该让所有异常处理程序调用某种“致命”操作(内核恐慌,捕获调试器,或者可能只是无限期地旋转),这样您就可以了解违反的假设。只要您不主动使用中断、EL0、页面错误等,您就可以完全运行而不会导致异常。当您开始使用更多 CPU 功能时,您必须一一添加异常处理程序。然后,您必须检查
ESR_EL1
是否有要处理的特定异常,并将它们分派到您的处理函数,但一旦到达那里,这些就会变得明显。