Hallo GCC-Gemeinde,
ich steh ein bischen auf dem Schlauch! Seit einer Woche bin ich stolzer
Besitzer eines Olimex SAM9-L9260 mit ARM9 Prozessor. Linux läuft super
auch über SSH und sonst ist alles richtg gut.
Nun wollte ich mal mit dem arm-elf-gcc das obligatorische HelloWorld
übersetzen und per SCP rüberschieben geht alles wunderbar. Ohne
besondere Kommandozeilenoptionen, also mit
1
arm-elf-gcc-mcpu=arm9-ohello.ohello.c
bekomm ich erst mal eine riesen Datei (180k). Bischen arg groß für ein
HelloWorld Test. Wenn ich das rüber aufs Board kopiere dann die rechte
setze und es mir ./hello.o oder sh hello.o starten will, dann kommt nur
Illegal instruction?
Gut also mal ins Makefile vom yagarto Test-Beispiel geschaut und noch
ein paar Kommandozeilenoptionen dazugeschrieben
dann wird die hollo.o zwar nur noch rund 1.8k groß. Sieht schon mal gut
aus. Aber nach dem rüberkopieren bekomm ich dann:
cannot execute binary file
Habt ihr ne Ahnung, was ich da falsch mache?
Gruß Tilo
Das ist keine ausführbare Datei, sondern nur eine Objektdatei, d.h. das,
was man dem Linker vorwirft, damit der die Runtimeumgebung (Startupcode,
benötigte Libraries etc.) dazupackt.
Dem gcc wird man auch noch mitteilen müssen, daß er die Objektdatei dem
Linker vorwirft.
Hmm das stimmt, mit dem Linker, das hab ich jetzt auch mitbekommen.
Allerdings sollte dann doch der arm-elf-gcc compiler wenn ich alle
optionen weglasse also nur mit
1
arm-elf-gcc-mcpu=arm9hello.c
doch den ganzen build pfad durchlaufen, also
Preprocessing --> Compiling --> Assembling --> Linking
und dann automatisch eine elf Datei schmeißen. Tut er aber nicht,
sondern eine a.out. und dies ist offensichtlich ein binary-File und kein
executable.
eh ich steh total auf'm schlauch!
gruß
@Malte:
na ja die Idee kam mir ja als aller erstes und so dachte ich auch sollte
das funktionieren. Allerdings meckert der ARM9 dann mit eben dieser
Fehlermeldung aus dem Topic-Namen.
./hello.o: cannot execute binary file
:-(
Probier's mal aus mit:
arm-elf-gcc -mcpu=arm9 hello.c -o hello
so (ähnlich, aber ohne -mcpu) kompiliere ich unter Linux kleine
Programme ohne makefile.
Gruß Jörg
Dann wirst du dich wohl oder übel kundig machen müssen, was genau
dein Linux da als Binärformat benötigt, um es zur direkten Ausführung
zu akzeptieren. U. U. hilft dir ja das Kommando "file" weiter, um
existierende (tatsächlich lauffähige) Binaries mit dem von dir
erzeugten zu vergleichen.
Gesprächiger als file ist readelf. Wende doch einmal
1
arm-elf-readelf -h
auf
- das von dir selbst kompilierte Programm und
- ein fertiges Programm aus der Linux-Installation des Zielsystems
an und vergleiche die Ausgaben.
Für die ARMs gibt es ja unterschiedliche Befehlssätze und Datenformate
(normal/thumb, little-endian/big-endian). Ohne mich mit den ARMs gut
auszukennen, vermute ich, dass nicht alle Formate vom Zielsystem
unterstützt werden.
Entscheide dich doch mal, welche Fehlermeldung jetzt wirklich kommt.
#1 "Illegal instruction" oder #2 "cannot execute binary file"
Bei #1 erkennt Linux ein execute binary file, d.h. einen übersetzten und
gelinkten Quellcode. Aber der ist für den Zielprozessor nicht richtig
übersetzt und wirft deshalb bei der Ausführung einen Fehler.
Bei #2 hast du kein execute binary file, sondern z.B. nur eine
Objektdatei, die noch mit den Libraries zu verlinken wäre. Die
Fehlermeldung kommt, wenn Linux sich die Datei ansieht, um sie zu
starten. Es kann passieren, dass du nach der Korrektur von #2 bei #1
landest.
> Bei #2 hast du kein execute binary file, sondern z.B. nur eine> Objektdatei, die noch mit den Libraries zu verlinken wäre.
Oder ein Executable, das für ein anderes Zielsystem kompiliert und
gelinkt wurde.
Also erst mal vielen Dank für die Unterstützung. Der beschränken wir uns
mal auf Fehler #1. So und der Tipp mit arm-elf-readelf -h war gut. Aber
nun seht selbst. aus hallo.c -->
1
ELFHeader:
2
Magic:7f454c46010101610000000000000000
3
Class:ELF32
4
Data:2'scomplement,littleendian
5
Version:1(current)
6
OS/ABI:ARM
7
ABIVersion:0
8
Type:EXEC(Executablefile)
9
Machine:ARM
10
Version:0x1
11
Entrypointaddress:0x8100
12
Startofprogramheaders:52(bytesintofile)
13
Startofsectionheaders:261348(bytesintofile)
14
Flags:0x2,hasentrypoint,GNUEABI
15
Sizeofthisheader:52(bytes)
16
Sizeofprogramheaders:32(bytes)
17
Numberofprogramheaders:1
18
Sizeofsectionheaders:40(bytes)
19
Numberofsectionheaders:24
20
Sectionheaderstringtableindex:21
und aus einem file vom AT91SAM9260 (Board von olimex im übrigen)
Gabs da nicht nen unterschied zwischen den einzelnen Compilervarianten,
einer für Linuxbinaries [gcc-arm-linux oder so] und der andere für
standaloneanwendungen? Schliesslich wird ja anders gelinkt (oder so ;) )
Ahh, richtig, also schnell das Manual vom Board zur Hand, da war doch
irgendwas:
1
$PATH=$PATH:/usr/local/arm/4.1.1-920t/bin
2
$cat>hello.c
3
#include<stdio.h>
4
intmain(void)
5
{
6
unsignedinti;
7
printf("\r\nProba proba ");
8
for(i=0;i<10;i++)
9
printf("\r\n%d",i);
10
return0;
11
}
12
^D
13
$arm-linux-gcc-ohellohello.c
14
$cphello~/htdocs/
15
-----Ontheboard-----
16
~#wgethttp://192.168.0.xx/hello
17
~#chmod777hello
18
~#./hello
19
Probaproba
20
01
21
....
wer lesen kann ist klar im Vortei! Eine Frage bleibt dann aber noch,
gibt es den arm-linux-gcc auf für Windows (also ohne aufwendige cygwin
installation)? Ist hat in der Firma etwas schwierig ein linux mal
schnell installieren zu lassen. Bürokratie usw. Na ja.
Gruß und danke
>...arm-elf-gcc...
Ist das eine "bare metal"-Toolchain (target arm-elf)?. Ausgabe von
arm-elf-gcc -v? Schon mit einem Cross-Compiler für target arm-linux
ausprobiert?
Hoppla, zu lahm gewesen.
Cross-Compiler für arm-linux Targets und Win32-Hosts:
http://www.codesourcery.com/gnu_toolchains/arm/portal/release570
Nie selbst ausprobiert. Nutze für eigene Experimente in dem Bereich eine
virtuelle Maschine (vmware Server), darin Debian, damit buildroot.
Danke Thomas, werds mal ausprobieren, wenns nicht funzt kann ich immer
noch auf ne Linux Distribution zurückgreifen.
Im Übrigen: arm-elf-gcc ist der cross-compiler von yatargo, allerdings
nur für die hardware-nahe-kompilierung. Ich erinnere mich an die ersten
versuche damit, d.h. mittels JTAG auf die Hardware geladen und debugt
hat wunderbar funktioniert.
Für stand-alone Anwendungen auf dem embedded-Linux ist aber
höchstwahrscheilich der arm-linux-gcc zu verwenden. wenigstens noch was
gelernt heute :-D
Gruß an alle und ich hoffe so könnte es nun funktionieren.