设置中断向量表,ARMv6
我正在尝试在 ARMv6 裸机应用程序中使用用户模式和 SVC,但为此我需要设置 ARMv6 中断向量表的 SVC 条目以分支到我的中断处理程序。但是,我找不到关于如何执行此操作的好示例(即:我到底需要设置什么内存地址,以及设置什么)。我过去也做过类似的事情,但总是使用更全面的引导加载程序(RedBoot)为我设置其中一些。任何帮助将不胜感激。
我正在使用以下方法测试我的应用程序:
qemu-system-arm -M versatilepb -cpu arm1176
I'm trying to use usermode and SVC in my ARMv6 bare metal application, but for this I need to set up the SVC entry of the ARMv6 interrupt vector table to branch to my interrupt handler. But, I can't find a good example on how to do this (ie: what memory address exactly I need to set, and to what). I have done similar things in the past, but always with a more comprehensive bootloader (RedBoot) that set up some of this for me. Any help would be appreciated.
I am testing my application using:
qemu-system-arm -M versatilepb -cpu arm1176
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你说的是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 假设正在使用链接地址。
然后,在您想要引发任何中断之前,在示例中我使用 swi 指令来引发 swi 中断。您从 0x10000 到 0x00000 复制足够的代码以包含异常表及其加载到 PC 中的地址列表。通过将程序链接到 0x10000,这些地址就在 0x10000 范围内。当中断发生时,您现在修改的异常处理程序会将基于 0x10000 的地址加载到 PC 中,并且将调用 0x10000 范围内的处理程序。
在我的示例中使用此命令行运行二进制文件
,然后 ctrl-alt-3(不是 F3,而是 3)将切换到串行控制台,您可以看到输出,然后关闭该窗口以关闭 qemu 并停止模拟。
Are you talking about the SWI interrupt? Or one of the others (FIQ, IRQ). In either case I think I know what the problem is. Qemu is for running linux, your binary is not loaded at address 0x00000 so your entry points are not used by qemu for handling exceptions.
I have an example that uses qemu and implements a solution. Go to the qemu directory of http://github.com/dwelch67/yagbat. The qemu example is not really related to the gba thing in the yagbat repo, the gba is a 32 bit ARM thing so it was easy to borrow code from so I stuck it there.
The example was specifically written for your question as I tried to figure out how to use qemu in this manner. It appears that the address 0x00000000 space is simulated as ram, so you can re-write the qemu exception table and have the exceptions call code in the 0x10000 address space that your binary loads.
A quick and dirty solution is to make the entry point of the binary (that qemu loads to 0x10000) resemble a vector table at address 0x00000. The ldr pc instruction is relative to the program counter, the disassembly might show that it is loading an address at 0x10000 but it is really relative to the pc and the disassembler used the pc assuming the linked address being used.
Then before you want to cause any interrupts, in the example I use the swi instruction to cause an swi interrupt. You copy enough of the code from 0x10000 to 0x00000 to include the exception table and the list of addresses that it loads into the pc. by linking your program to 0x10000 those addresses are in the 0x10000 range. When the interrupt occurs, the exception handler that you have now modified will load the 0x10000 based address into the pc and your handler in the 0x10000 range will get called.
Using this command line to run the binary in my example
and then ctrl-alt-3 (not F3 but 3) will switch to the serial console and you can see the output, and close that window to close out of qemu and stop the simulation.