我正在尝试在我的ARMv6裸机应用程序中使用usermode和SVC,但为此我需要设置ARMv6中断向量表的SVC条目以分支到我的中断处理程序。但是,我找不到一个关于如何做到这一点的好例子(即:我需要设置什么内存地址,以及什么)。我过去做过类似的事情,但总是使用更全面的引导程序(RedBoot)来为我设置一些。任何帮助将不胜感激。
我正在使用以下方法测试我的应用程序:
qemu-system-arm -M versatilepb -cpu arm1176
答案 0 :(得分:3)
你在谈论SWI中断吗?或者其中一个(FIQ,IRQ)。无论哪种情况,我想我都知道问题所在。 Qemu用于运行linux,您的二进制文件未加载到地址0x00000,因此qemu不会使用您的入口点来处理异常。
我有一个使用qemu并实现解决方案的示例。转到http://github.com/dwelch67/yagbat的qemu目录。 qemu示例与yagbat repo中的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并停止模拟。