我正在尝试在我的 ARMv6 裸机应用程序中使用用户模式和 SVC,但为此我需要设置 ARMv6 中断向量表的 SVC 条目以分支到我的中断处理程序。但是,我找不到一个很好的例子来说明如何做到这一点(即:我需要设置什么内存地址,以及设置什么)。我过去做过类似的事情,但总是使用更全面的引导加载程序(RedBoot)为我设置了一些。任何帮助,将不胜感激。
我正在使用以下方法测试我的应用程序:
qemu-system-arm -M versatilepb -cpu arm1176
我正在尝试在我的 ARMv6 裸机应用程序中使用用户模式和 SVC,但为此我需要设置 ARMv6 中断向量表的 SVC 条目以分支到我的中断处理程序。但是,我找不到一个很好的例子来说明如何做到这一点(即:我需要设置什么内存地址,以及设置什么)。我过去做过类似的事情,但总是使用更全面的引导加载程序(RedBoot)为我设置了一些。任何帮助,将不胜感激。
我正在使用以下方法测试我的应用程序:
qemu-system-arm -M versatilepb -cpu arm1176
你说的是SWI中断吗?或其他之一(FIQ,IRQ)。无论哪种情况,我想我都知道问题出在哪里。Qemu 用于运行 linux,您的二进制文件未在地址 0x00000 加载,因此 qemu 不会使用您的入口点来处理异常。
我有一个使用 qemu 并实现解决方案的示例。进入http://github.com/dwelch67/yagbat的 qemu 目录。qemu 示例与 yagbat 存储库中的 gba 并没有真正的关系,gba 是一个 32 位 ARM 的东西,所以很容易从中借用代码,所以我把它卡在那里。
该示例是专门为您的问题编写的,因为我试图弄清楚如何以这种方式使用 qemu。看起来地址 0x00000000 空间被模拟为 ram,因此您可以重写 qemu 异常表,并在二进制加载的 0x10000 地址空间中具有异常调用代码。
一个快速而肮脏的解决方案是使二进制文件的入口点(qemu 加载到 0x10000)类似于地址 0x00000 处的向量表。ldr pc 指令与程序计数器相关,反汇编可能显示它正在加载 0x10000 处的地址,但它实际上与 pc 相关,并且反汇编程序使用 pc 假设正在使用链接地址。
.globl _start
_start:
ldr pc,start_vector_add
ldr pc,undef_vector_add
ldr pc,swi_vector_add
start_vector_add: .word start_vector
undef_vector_add: .word undef_vector
swi_vector_add: .word swi_vector
然后在你想引起任何中断之前,在这个例子中我使用 swi 指令来引起一个 swi 中断。您从 0x10000 到 0x00000 复制了足够多的代码,以包括异常表和它加载到 pc 中的地址列表。通过将您的程序链接到 0x10000,这些地址在 0x10000 范围内。当中断发生时,您现在修改的异常处理程序会将基于 0x10000 的地址加载到 pc 中,并且将调用 0x10000 范围内的处理程序。
在我的示例中使用此命令行运行二进制文件
qemu-system-arm -M versatilepb -m 128M -kernel hello_world.bin
然后 ctrl-alt-3(不是 F3 而是 3)将切换到串行控制台,您可以看到输出,然后关闭该窗口以关闭 qemu 并停止模拟。