我有AT91Bootloader为AT91sam9 ARM控制器。我需要添加一些额外的硬件初始化,但我只编译了。bin文件。我将bin文件加载到内存中,并试图调用它:
((void (*)())0x00005000)();
但是,没有任何结果。请尽量少用汇编器。我以前接触过汇编程序,但由于ARM汇编程序的复杂性,我无法理解它。我怎么能从引导加载程序的中间调用,执行bin文件(它将在一些内存扇区,例如0x00005000),然后返回引导加载程序并继续执行它自己的代码?
如果ARM asm "太复杂",您会发现调试遇到的任何问题都非常困难。Basic* ARM汇编语言是我见过的最不复杂的汇编语言之一。
你的代码应该工作(虽然我不会使用硬编码地址在那里),只要"。bin"是正确的格式。常见问题:
- 入口点应该是ARM代码;一些编译器默认为Thumb。这是可能的(如果有点棘手),使拇指代码工作。
- 入口点需要位于文件的开头。如果不拆解,很难判断你是否做对了。
- 链接器将插入"thunks"(又名"坦克")。"存根")。在一些链接器中,一个奇怪的现象意味着可以将放在入口点之前。你可以使用
--stub-group-size=-1
(文档在这里)来解决这个问题。
*忽略像Thumb/VFP/NEON这样你不需要开始的东西
ARM汇编是比较简单的一种,非常直接。如果你想继续做裸金属,你将需要学习至少一些组装。例如理解Alexey的评论。
您正在寻找的指令是BX,它分支到一个地址,您需要分支到引导加载程序下载的代码的汇编是:
.globl tramp
tramp:
bx r0
C原型是
void tramp ( unsigned int address );
正如在注释中提到的,程序需要为你运行它的地址编译,并且/或者它需要与位置无关,否则它将无法工作。此外,您还需要使用适当的入口点构建应用程序,如果它是原始二进制文件,并且您要分支到加载二进制文件的地址,则二进制文件需要能够通过将二进制文件中的第一个单词作为执行的入口点来启动。
也要理解elf格式文件包含您想要加载的数据,但作为一个整体不是您想要加载的数据。它是一个"二进制文件",但要运行其中包含的程序,您需要解析和提取可加载部分,并将它们加载到正确的位置。
如果你不知道这些术语是什么意思,用谷歌,和/或搜索SO,答案就在那里