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

问题描述 投票:0回答:3

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

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

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

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

按照我的理解,文件应该加载到 RAM 的地址 0x20005000

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

=> 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 ...
binary yocto u-boot instruction-set
3个回答
2
投票

得到了另一位朋友的帮助,我发现它非常有帮助,所以我将其发布:

您可以使用 Yocto 工具链,但无法链接到 C 库(默认情况下完成),因此您必须向 GCC 添加一些额外的选项,让它知道您也不能使用 U 中的

go
指令-引导跳转到您刚刚加载到内存中的 ELF 二进制文件,必须使用工具
objdump
将 ELF 二进制文件转换为“原始”二进制文件(您的情况下的 ARM 指令列表)。 ELF 二进制文件是一种特定的格式,封装了您的代码/数据和一些额外信息,ELF 的第一部分是二进制文件的描述,所以现在,当您在第一个地址处执行
go
时,您试图告诉 CPU 执行非 ARM 指令的指令。您基本上想要执行我们所说的 ELF 二进制文件的“.text”部分。


1
投票

请在 https://www.denx.de/wiki/view/DULG/UBootStandalone#Section_5.12.1 查找示例。

go 不需要 ELF 二进制文件的开头,而是入口例程的地址。如果您想访问 U-Boot 例程,则必须重新定位二进制文件。


1
投票

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

您忽略了许多重要的细节。
你是如何编译这个程序的,例如什么工具链,什么makefile?
您是否将此程序与库链接?

按照我的理解,文件应该加载到 RAM 的地址 0x20005000

你是如何得到这个“理解”的?

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

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

这就是“执行”ELF header 时发生的情况。
由于该文件显然包含 ELF 标头,因此其文件扩展名应该是 .elf 而不是 .bin.
这个可执行文件是如何获得误导性的名称的?

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


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

(首先,不要在评论中添加重要信息。使用编辑功能将其添加到您的原始帖子中。)
您提供的“信息”没有任何意义(即结束地址小于起始地址)。避免解释信息,而是简单地呈现(复制粘贴)实际输出。

然后我使用 fatload mmc 1:4 0x10005000 hello.bin 代替,这似乎可以工作。我猜我正在写信给一个超出范围的地址。

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

go 0x10005000 还是不行。

尝试任意加载/起始地址并不是一种有效的调试技术。
“似乎有效”“仍然无效” 的总和是对结果的低质量描述。
请参阅如何以聪明的方式提出问题

© www.soinside.com 2019 - 2024. All rights reserved.