针对嵌入式基于ARM的Linux系统进行交叉编译

8

我正在尝试为一个嵌入式(自定义)基于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

1
如果你的内存空间紧张,更小的uClibc可以替代glibc。但是你需要构建使用uClibcgcc编译器。获得一个工作正常的工具链(包括gccuClibc(或glibc)和其他软件包),并从源代码构建Linux内核,Busybox和其他软件包的一个相对容易的方法是使用BuildRoot。使用良好的编译器+ libc组合,您可以将您的应用程序静态链接,并独立于目标库。 - sawdust
1个回答

5
您应该在嵌入式系统上安装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标志。 本文建议如果您正在从命令行编译,则向gcc添加-nostdlib标志。
或者,您可以切换到使用arm-none-eabi-gcc编译器。这里可以找到有关此内容的参考资料:此处此处

我无法在嵌入式系统上安装软件,但是链接到系统的libc时出现了以下错误:ld: error: Source object ../libc.so.0 has EABI version 0, but target main has EABI version 5。谷歌搜索结果表明,我实际上需要不同的gcc,这是正确的吗? - flyx
@flyx 你是使用makefile还是直接在命令行上运行gcc? - embedded.kyle
arm-none-eabi-gcc可能是正确的选择。我没有尝试过,因为我从硬件制造商那里得到了一个可用的工具链,但无论如何我会将其标记为正确答案。这些链接非常有帮助。 - flyx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接