Tôi cố gắng biên dịch một số mã C cho một hệ thống Linux dựa trên ARM (tùy chỉnh). Tôi thiết lập một máy ảo Ubuntu với một trình biên dịch chéo có tên arm-linux-gnueabi-gcc-4.4 vì nó trông giống như những gì tôi cần. Bây giờ khi tôi biên dịch mã của tôi với gcc này, nó tạo ra một nhị phân như thế này:Biên dịch chéo cho hệ thống Linux dựa trên ARM nhúng
$ 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
Khi tôi cố gắng chạy nhị phân này trên Linux nhúng, tôi nhận được
$ ./test1
-sh: ./test1: not found
Quyền là đủ. Tôi chỉ có thể tưởng tượng rằng một cái gì đó xảy ra với các định dạng nhị phân, vì vậy tôi xem xét một số nhị phân làm việc như tài liệu tham khảo:
$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped
tôi thấy rằng có một số khác biệt, nhưng tôi không có kiến thức để lấy được tôi cần gì chính xác để khắc phục và cách tôi có thể khắc phục điều đó. Ai đó có thể giải thích sự khác biệt nào là quan trọng?
Một điều tôi nhìn là phụ thuộc:
$ ldd test1
libc.so.6 => not found (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
(Điều thú vị là, này hoạt động trên hệ thống mục tiêu mặc dù nó không thể thực thi nhị phân.) Hệ thống nhúng chỉ có một libc.so.0
sẵn. Tôi đoán tôi cần phải nói cho trình biên dịch phiên bản libc tôi muốn liên kết chống lại, nhưng như tôi hiểu nó, gcc chỉ liên kết với các phiên bản nó đi kèm với, là điều này đúng? Tôi có thể làm gì với nó?
Edit: Đây là các Makefile tôi sử dụng:
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
Nếu bạn đang sử dụng bộ nhớ, nhỏ hơn nhiều 'uClibc' có thể thay thế cho' glibc'. Tuy nhiên bạn sẽ cần một trình biên dịch * gcc * được xây dựng để sử dụng 'uClibc'. Một (tương đối) phương pháp dễ dàng có được chuỗi công cụ hoạt động của * gcc *, * uClibc * (hoặc * glibc *) và bạn bè cộng với xây dựng hạt nhân Linux, Busybox và các gói khác từ nguồn là sử dụng 'BuildRoot'. Với sự kết hợp trình biên dịch + libc tốt, bạn có thể liên kết ứng dụng của mình một cách tĩnh và độc lập với các thư viện của mục tiêu. – sawdust