【问题标题】:U-Boot How to run a standalone binary program?U-Boot 如何运行独立的二进制程序?
【发布时间】:2018-09-23 15:56:45
【问题描述】:

我编译了一个简单的二进制文件(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 ...

感谢您的帮助

【问题讨论】:

  • the => bdinfo,命令告诉我一些有关 DRAM 组的信息,从 0x10000000(7 个零)开始,到 0x4000000 结束。然后我使用 fatload mmc 1:4 0x10005000 hello.bin 代替,这似乎工作。我想我正在写一个超出范围的地址。 go 0x10005000 还是不行。

标签: binary yocto u-boot instruction-set


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    您是如何获得这种“理解”的

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

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

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

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


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

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

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

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

    go 0x10005000 还是不行。

    尝试任意加载/起始地址并不是一种有效的调试技术。
    “似乎有效”“仍然无效”的总和是对结果的低质量描述。
    How To s The Smart Way

    【讨论】:

    • 我使用 arm-fslc-linux-gnueabi-gcc 编译它。实际上我写了 ${CC} myapp/helloworld.c -o hello.bin 。我想将 helloworld 中的字符串打印到屏幕上,UART 就可以了。确切的地址可能无关紧要,但我预计我需要将二进制文件加载到内存中。我没有任何makefile,我对链接也不太了解。也许你能指出我正确的方向?
    • CC = arm-fslc-linux-gnueabi-gcc -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4。 2/sysroots/armv7at2hf-neon-fslc-linux-gnueabi
    【解决方案3】:

    从另一个朋友那里得到了一些帮助,我觉得很有帮助,所以我会发布它:

    您可以使用 Yocto 工具链,但不能链接到 C 库(这是默认完成的),因此您必须向 GCC 提供一些额外的选项以使其知道,您也不能使用 go 指令从 U-Boot 跳转到您刚刚加载到内存中的 ELF 二进制文件,必须使用工具 objdump 将 ELF 二进制文件转换为“原始”二进制文件(在您的情况下为 ARM 指令列表)。 ELF 二进制文件是一种封装代码/数据和一些额外信息的特定格式,ELF 的第一部分是二进制文件的描述,所以现在,当你在第一个地址执行go 时,你试图告诉 CPU 执行一些不是 ARM 指令的东西。您基本上想要执行我们称之为 ELF 二进制文件的“.text”部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      相关资源
      最近更新 更多