Rust嵌入式应用程序未在AArch64系统下正确链接

Rust嵌入式应用程序未在AArch64系统下正确链接,rust,arm,embedded,rust-cargo,stm32f0,Rust,Arm,Embedded,Rust Cargo,Stm32f0,我正在尝试使用ARM系统作为主机为stm32f0编译和调试一个嵌入式rust应用程序。 该应用程序已在英特尔安装环境下编译并运行 我在一台由四个Cortex-A53 64位CPU驱动的计算机上运行。操作系统是Debian的64位版本: $ uname -a Linux pinebook 4.4.196 #1 SMP Tue Oct 15 16:54:21 EDT 2019 aarch64 GNU/Linux 我为AArch64安装了锈迹和带锈迹的货物(通道稳定): 根据,我发现rust lld

我正在尝试使用ARM系统作为主机为stm32f0编译和调试一个嵌入式rust应用程序。 该应用程序已在英特尔安装环境下编译并运行

我在一台由四个Cortex-A53 64位CPU驱动的计算机上运行。操作系统是Debian的64位版本:

$ uname -a
Linux pinebook 4.4.196 #1 SMP Tue Oct 15 16:54:21 EDT 2019 aarch64 GNU/Linux
我为AArch64安装了锈迹和带锈迹的货物(通道稳定):

根据,我发现rust lld不是以二进制形式分发给ARM系统的,所以我不得不从以下来源编译它:

$ ld.lld --version
LLD 10.0.0 (https://github.com/llvm/llvm-project.git 1c247dd028b368875bc36cd2a9ccc7fd90507776) (compatible with GNU linkers)
现在,编译过程已顺利完成:

export RUSTFLAGS="-C linker=ld.lld"
cargo build
但是,生成的elf文件似乎链接错误:尝试通过
openocd
使用
gdb
加载它会导致某种无声故障:

(gdb) target remote :3333
Remote debugging using :3333
0x00000000 in ?? ()
(gdb) load
Start address 0x0, load size 0
Transfer rate: 0 bits in <1 sec.
(gdb) 
似乎精灵没有正确连接。运行
readelf-l
会突出显示,在我的ARM系统上,入口点设置为
0x0
,这对于stm32f0是错误的。 这是我的ARM笔记本电脑上的
readelf

lf file type is EXEC (Executable file)
Entry point 0x0
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00010034 0x00010034 0x00060 0x00060 R   0x4
  LOAD           0x000000 0x00010000 0x00010000 0x00094 0x00094 R   0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02 
虽然这是在我的英特尔系统下编译的elf:

Elf file type is EXEC (Executable file)
Entry point 0x8005b59
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x08000000 0x08000000 0x06de0 0x06de0 R E 0x1000
  LOAD           0x007de0 0x20000000 0x08006de0 0x00000 0x00028 RW  0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     .vector_table .text .rodata 
   01     .data .bss 
   02     
我不确定这是否与目标体系结构与主机相同(因此使用linux userland链接)或简单有关,因为arm系统不太受支持


有人能给我指出正确的方向吗?

您必须使用专用于该板的链接器srcipt创建原始二进制图像


我正确地假设链接器存在问题,并且有两种解决方案

两年前,Rust使用LLD作为ARM架构()的默认链接器。不幸的是,
rust lld
本身并没有以二进制形式发布给ARM平台(很讽刺,不是吗?),所以我不得不从源代码处编译它,并通过命令行指定它

导出
RUSTFLAGS
变量会起作用,但会覆盖在
.cargo/config
中定义的默认值,其中还包括链接器脚本的指令(
-C link arg=-Tlink.x
)。简而言之,我确信使用了正确的链接器脚本,因为它列在
.cargo/config
中,但是
RUSTFLAGS
env变量正在删除它

解决办法是

  • 导出标记时显式包含链接器脚本:
    export-RUSTFLAGS=“-C linker=ldd-C link arg=-Tlink.x”
  • 使用其他选项在
    .cargo/config
    文件中指定
    “-C”,“linker=lld”
    作为生锈标志
  • 启用旧的链接器(
    arm none-eabi-ld
    ),通过取消对
    .cargo/config
    中的以下行的注释,可以更轻松地检索该链接器:
    “-C”,“linker=arm none-eabi-gcc”

您是否在stm32f0上安装了Linux?不,它是一个非常小的MCU,只是尝试在独立固件中闪存。通常为目标体系结构指定
cargo
包就足够了-它在我的英特尔系统上。我知道如何从头开始设置二进制文件,但我正在开发一个安装环境。您是否使用链接器脚本进行了尝试?根据您的假设,二进制文件没有正确链接@加博在这里可能是正确的。
lf file type is EXEC (Executable file)
Entry point 0x0
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00010034 0x00010034 0x00060 0x00060 R   0x4
  LOAD           0x000000 0x00010000 0x00010000 0x00094 0x00094 R   0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02 
Elf file type is EXEC (Executable file)
Entry point 0x8005b59
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x08000000 0x08000000 0x06de0 0x06de0 R E 0x1000
  LOAD           0x007de0 0x20000000 0x08006de0 0x00000 0x00028 RW  0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     .vector_table .text .rodata 
   01     .data .bss 
   02