arm(裸机):将二进制文件作为函数调用

时间:2013-03-01 09:37:09

标签: c arm bare-metal

我有AT91Bootloader用于AT91sam9 ARM控制器。我需要添加一些额外的硬件初始化,但我只编译了.bin文件。 我将bin文件加载到内存并尝试调用它:

((void (*)())0x00005000)();

但是,没有任何结果。请尽量少使用汇编程序。之前我被介绍给汇编程序,但由于它的共谋而无法理解ARM汇编程序。如何从bootloader中间调用,执行bin文件(例如,它将在某个内存扇区,例如0x00005000),然后返回bootloader并继续执行它自己的代码?

2 个答案:

答案 0 :(得分:2)

如果ARM asm“过于复杂”,您将发现调试任何问题非常困难。 Basic * ARM程序集是我遇到的最少复杂汇编语言之一。

你的代码应该工作(虽然我不会在那里使用硬编码的地址),前提是“。bin”的格式正确。常见问题:

  • 入口点应为ARM代码;一些编译器默认为Thumb。使Thumb代码工作是可能的(如果有点棘手)。
  • 入口点需要位于文件的开头。如果没有拆解,很难判断你是否正确地完成了这项工作。
  • 链接器将在必要时插入“thunks”(a.k.a。“stubs”)。某些链接器中的怪癖意味着thunk可以在入口点之前放置。您可以使用--stub-group-size=-1(文档here)。
  • 解决此问题

*忽略Thumb / VFP / NEON之类的东西,你不需要开始使用。

答案 1 :(得分:1)

ARM程序集是更简单的程序之一,非常直接。如果你想继续做裸机,你至少需要学习一些装配。例如,理解Alexey的评论。

您正在寻找的指令是BX,它分支到一个地址,您需要分支到您的引导加载程序下载的代码的程序集:

.globl tramp
tramp:
   bx r0

C原型是

void tramp ( unsigned int address );

正如评论中所提到的,程序需要针对您运行它的地址进行编译和/或它需要与位置无关,否则它将无法工作。您还需要使用正确的入口点构建应用程序,如果它是原始二进制文件并且您分支到加载二进制文件的地址,则二进制文件需要能够通过使二进制文件中的第一个单词为执行的切入点。

另请注意,elf格式文件包含要加载的数据,但整体上不是您要加载的数据。它是一个“二进制文件”,但要运行其中包含的程序,您需要解析并提取可加载部分并将它们加载到正确的位置。

如果您不知道这些术语的含义,请使用Google,和/或搜索SO,答案就在那里。