2012-09-20 64 views
7

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 
+0

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

Trả lời

4

gì có lẽ bạn nên làm là cài đặt libc6 trên hệ thống nhúng. Đọc this thread về một vấn đề tương tự. Các giải pháp trong bài # 5 đã cài đặt:

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 

tùy chọn khác của bạn là để có được những libc từ hệ thống nhúng vào VM của bạn và sau đó vượt qua nó vào gcc mối liên kết và sử dụng tùy chọn -static.

Giải pháp này cũng được đề cập trong chuỗi trên. Đọc thêm về liên kết tĩnh here.

Những điều khác để thử:

Trong this thread họ đề nghị loại bỏ các -mabi=apcs-gnu cờ từ makefile của bạn nếu bạn đang sử dụng một.

This article đề xuất feedint gcc cờ -nostdlib nếu bạn đang biên dịch từ dòng lệnh.

Hoặc bạn có thể chuyển sang sử dụng trình biên dịch arm-none-eabi-gcc. Tài liệu tham khảo về điều này có thể được tìm thấy herehere.

+0

Tôi không thể cài đặt phần mềm trên hệ thống nhúng, nhưng liên kết với libc của hệ thống đã đưa ra lỗi này: 'ld: error: Đối tượng nguồn ../libc.so.0 có phiên bản EABI 0, nhưng đích chính có phiên bản EABI 5'. Các kết quả google cho lỗi này ngụ ý rằng tôi thực sự cần một gcc khác nhau, điều này có đúng không? – flyx

+0

@flyx Bạn đang sử dụng một makefile hoặc bạn đang chạy gcc trực tiếp trên dòng lệnh? –

+0

@flyx Xem chỉnh sửa cho những thứ khác để thử rằng có thể hữu ích –

Các vấn đề liên quan