U-Boot如何运行独立的二进制程序?

时间:2018-04-13 10:07:30

标签: binary yocto u-boot instruction-set

我编译了一个简单的二进制文件(hello.bin)并将其存储在存储卡上。

我正在运行带有i.mx 6四核处理器的NXP Sabre开发套件。我已启动U-boot并尝试访问二进制文件并使其运行。

可以使用hello.bin,因为以下命令有效:

=> fatload mmc 1:4 0x20005000 hello.bin
reading hello.bin

我理解它的方式应该将文件加载到地址为0x20005000的RAM中

所以我想测试二进制文件是否存在

=> md 0x20005000
20005000: 464c457f 00010101 00000000 00000000    .ELF............
20005010: 00280002 00000001 00010315 00000034    ..(.........4...
20005020: 000028f4 05000400 00200034 00280009    .(......4. ...(.
20005030: 00240025 70000001 00000454 00010454    %.$....pT...T...

看起来没问题,因为起始位与我复制到SD卡的文件相匹配。

当我尝试启动二进制文件时,设备会报告未定义的指令:

=> go 0x20005000
## Starting application at 0x20005000 ...
undefined instruction
pc : [<20005158>]          lr : [<4ff71403>]
reloc pc : [<e7897158>]    lr : [<17803403>]
sp : 4f56dd50  ip : 00000000     fp : 00000002
r10: 4f56f938  r9 : 4f56deb0     r8 : 4ffc3c40
r7 : 4ff713d9  r6 : 00000002     r5 : 20005000  r4 : 4f56f93c
r3 : 20005000  r2 : 4f56f93c     r1 : 4f56f93c  r0 : 00000000
Flags: nzCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

请在https://www.denx.de/wiki/view/DULG/UBootStandalone#Section_5.12.1.

找一个例子

go 不期望ELF二进制文件的启动,而是入口例程的地址。如果要访问U-Boot例程,则必须重新定位二进制文​​件。

答案 1 :(得分:1)

  

我编译了一个简单的二进制文件(hello.bin)并将其存储在存储卡上。

您省略了许多重要细节 你是如何编译这个程序的,例如什么工具链,什么makefile?
你有这个程序与图书馆链接?

  

我理解它的方式应该将文件加载到地址为0x20005000的RAM中

你是如何得到这个&#34;理解&#34; 的?

通常,独立程序的加载地址取决于几个因素 首先,必须考虑可用内存的地址(在目标板上) 其次,除非独立程序是可重定位的(在您的情况下不太可能),否则程序必须按照程序链接时定义的加载/起始地址加载。
程序的加载和起始地址可以从其映射文件(即链接器输出)获得。

  

当我尝试启动二进制文件时,设备会报告未定义的指令:

当ELF标题被执行&#34;时,会发生这种情况 由于文件明确包含ELF标题,因此其文件扩展名应为 .elf ,而不是 .bin
这个可执行文件是如何得到误导性名称的?

您可能没有构建独立的二进制图像文件 U-Boot源代码的 examples / standalone / 目录包含用于构建独立二进制文件的示例代码和makefile,例如: a hello_world.bin
务必为您的主板正确定义 CONFIG_STANDALONE_LOAD_ADDR
默认加载地址肯定是不合适的。

  

=&gt; bdinfo,命令告诉我一些有关DRAM库的信息,从0x10000000(7个零)开始,到0x4000000结束。

(首先,请勿在评论中添加重要信息。使用编辑功能将其添加到原始帖子。)

&#34;信息&#34;你提供的没有意义(即结束地址小于起始地址)。避免解释信息,而只是简单地呈现(复制&#39; n&#39;粘贴)实际输出。

  

然后我使用fatload mmc 1:4 0x10005000 hello.bin,然后似乎工作。我想我正在写一个出界的地址。

fatload命令仅将文件内容复制到内存中。通过验证内存而不是完成命令来确认该副本的真正成功 您的评论很混乱,因为您没有提到任何先前的加载问题。

  

去0x10005000仍然无效。

尝试任意加载/启动地址不是一种有效的调试技术 &#34;的总和似乎有效&#34; &#34;仍然不起作用&#34; 是对结果的低质量描述。 /> 见How To Ask Questions The Smart Way

答案 2 :(得分:0)

从另一位朋友那里得到了一些帮助,我发现它非常有帮助所以我会发布它:

您可以使用Yocto工具链,但无法链接到C库(默认情况下已完成),因此您必须向GCC添加一些额外选项,以便让它知道,您也无法使用{{1}来自U-Boot的指令跳转到刚刚加载到内存中的ELF二进制文件,ELF二进制文件必须转换为&#39; raw&#39;使用工具go生成二进制文件(在您的案例中为ARM指令列表)。 ELF二进制文件是一种特定的格式,它封装了您的代码/您的数据和一些额外的信息,ELF的第一部分是二进制文件的描述,所以当你在objdump处执行时第一个地址,您试图告诉CPU执行不是ARM指令的事情。你基本上想要执行我们称之为&#39; .text&#39; ELF二进制文件的一部分。