Rust嵌入式应用程序未在AArch64系统下正确链接
我正在尝试使用ARM系统作为主机为stm32f0编译和调试一个嵌入式rust应用程序。 该应用程序已在英特尔安装环境下编译并运行 我在一台由四个Cortex-A53 64位CPU驱动的计算机上运行。操作系统是Debian的64位版本: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
$ 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”
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