基于ARM的嵌入式Linux系统的交叉编译



我试图为基于嵌入式(自定义)ARM的Linux系统编译一些C代码。我用一个名为arm-linux-gnueabi-gcc-4.4的交叉编译器设置了一个Ubuntu虚拟机,因为它看起来像我需要的。现在,当我用这个gcc编译代码时,它会生成一个二进制文件,如下所示:

$ file test1
test1: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.31,
BuildID[sha1]=0x51b8d560584735be87adbfb60008d33b11fe5f07, not stripped

当我尝试在嵌入式Linux上运行这个二进制文件时,我得到了

$ ./test1
-sh: ./test1: not found

权限是足够的。我只能想象二进制格式有问题,所以我看了一些工作二进制作为参考:

$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped

我看到有一些差异,但我不知道我到底需要解决什么以及如何解决。有人能解释哪种差异是关键的吗?

我看到的另一件事是依赖性:

$ ldd test1
libc.so.6 => not found (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)

(有趣的是,这在目标系统上有效,尽管它不能执行二进制文件。)嵌入式系统只有libc.so.0可用。我想我需要告诉编译器我想链接的libc版本,但据我所知,gcc只是链接它附带的版本,这是正确的吗?我该怎么办?

编辑:这是我使用的Makefile:

CC=/usr/bin/arm-linux-gnueabi-gcc-4.4
STRIP=/usr/bin/arm-linux-gnueabi-strip          
CFLAGS=-I/usr/arm-linux-gnueabi/include             
LDFLAGS=-nostdlib
LDLIBS=../libc.so.0
SRCS=test1.c
OBJS=$(subst .c,.o,$(SRCS))
all: test1
test1: $(OBJS)
$(CC) $(LDFLAGS) -o main $(OBJS) $(LDLIBS)
$(STRIP) main
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
clean:
rm -f $(OBJS)
include .depend

您可能应该做的是在嵌入式系统上安装libc6。阅读这篇关于类似问题的文章。5号帖子中的解决方案是安装:

libc6_2.3.6.ds1-13etch9_arm.deb
linux-kernel-headers_2.6.18-7_arm.deb
libc6-dev_2.3.6.ds1-13etch9_arm.deb

您的另一个选择是将libc从嵌入式系统获取到VM上,然后将其传递给gcc链接器并使用-static选项。

上述线程中也提到了此解决方案。在此处阅读有关静态链接的更多信息。

其他尝试:

在这个线程中,他们建议从您的makefile中删除-mabi=apcs-gnu标志(如果您正在使用的话)。

如果您是从命令行编译的,本文建议将-nostdlib标志提供给gcc。

或者您可以切换到使用arm-none-eabi-gcc编译器。关于这方面的参考资料可以在这里和这里找到。

最新更新