2013-06-23 20 views
6

Ich möchte in rohen Binärdaten verknüpfen. Ich möchte es entweder an eine bestimmte Adresse schreiben oder es mit einem Symbol verlinken (zB char * mydata), das ich im Code definiert habe. Da es keine obj-Datei ist, kann ich es nicht einfach einbinden.Verknüpfung beliebiger Daten mit GCC ARM Toolchain

Ein ähnlicher Beitrag (Include binary file with GNU ld linker script) schlägt vor, objcopy mit der Option -B bfdarch zu verwenden. objcopy antwortet mit "archictecture bfdarch unknown".

Noch eine andere Antwort schlägt vor, das Objekt in ein benutzerdefiniertes LD-Skript zu transformieren und dann das aus dem LD-Hauptskript aufzunehmen. An dieser Stelle kann ich auch einfach eine C Include-Datei verwenden (was ich gerade mache), also würde ich das lieber nicht tun.

Kann ich objcopy verwenden, oder gibt es einen anderen Weg?

+3

How'bout 'unsigned Char Daten [] = {0x12, 0x34, 0x56, 0x78, ...};' stattdessen? –

+0

H2CO3, das ist ziemlich genau das, was ich mache. Ich habe einen Pre-Build-Befehl, um die Bin-Datei einzulesen und spucke eine H-Datei mit einem Array von Daten aus (wie Sie es vorschlagen). Es funktioniert, aber es scheint, als sollte es einen besseren Weg geben, es zu tun. – Brian

+1

'bfdarch' ist nicht literal; Versuche 'Arm'. Das funktioniert definitiv so wie mit * gas *, es hat eine [* .incbin * Direktive] (http://linux.web.cern.ch/linux/scientific4/docs/rhel-as-en-4/incbin.html). Es gibt auch eine Fülle von Programmen wie 'hexdump', die binäre in 'C'-Arrays konvertieren. –

Antwort

9

Das folgende Beispiel funktioniert für mich:

$ dd if=/dev/urandom of=binblob bs=1024k count=1 
$ objcopy -I binary -O elf32-little binblob binblob.o 
$ file binblob.o 
binblob.o: ELF 32-bit LSB relocatable, no machine, version 1 (SYSV), not stripped 
$ nm -S -t d binblob.o 
0000000001048576 D _binary_binblob_end 
0000000001048576 A _binary_binblob_size 
0000000000000000 D _binary_binblob_start 

D.h. keine Notwendigkeit, den BFD-Bogen für binäre Daten zu spezifizieren (es ist nur nützlich/notwendig für Code). Sagen Sie einfach "die Eingabe ist binär" und "die Ausgabe ist ..." und es wird die Datei erstellt. Da reine binäre Daten nicht architekturspezifisch sind, müssen Sie nur sagen, ob die Ausgabe 32 Bit (elf32-...) oder 64 Bit (elf64-...) ist und ob Little Endian/LSB (...-little, wie auf ARM/x86) oder groß ist Endian/MSB (...-big, wie zB auf SPARC/m68k).

Edit: Klärung über die Optionen für objcopy:

  • die Nutzung der -O ... Option Kontrollen:
    • Bit-Breite (ob die ELF-Datei seiner 32-Bit- oder 64-Bit)
    • endianness (ob die ELF-Datei LSB oder MSB) wird
  • die Nutzung der -B ... Option steuert die Architektur der ELF-Datei

Wunsch erhalten Sie haben die -O ... specifiy aber die -B ... ist optional. Der Unterschied wird am besten anhand eines kleinen Beispiels veranschaulicht:

$ objcopy -I binary -O elf64-x86-64 foobar foobar.o 
$ file foobar.o 
foobar.o: ELF 64-bit LSB relocatable, no machine, version 1 (SYSV), not stripped 

$ objcopy -I binary -O elf64-x86-64 -B i386 foobar foobar.o 
$ file foobar.o 
foobar.o: ELF 64-bit LSB relocatable, AMD x86-64, version 1 (SYSV), not stripped

I.e. nur der Ausgabeformat-Spezifizierer elf64-x86-64 bindet die generierte Binärdatei nicht an eine bestimmte Architektur (deshalb file sagt no machine). Die Verwendung, wenn -B i386 tut dies - und in diesem Fall wird Ihnen gesagt, dies ist jetzt .

Das gleiche würde für ARM gelten; -O elf32-little vs -O elf32-littlearm -B arm ist, dass im ersten Fall, Sie mit einer ELF 32-bit LSB relocatable, no machine, ... enden, während in der letzteren, wird es eine ELF 32-bit LSB relocatable, ARM... sein.

Auch hier gibt es einige Abhängigkeiten; Sie müssen die -O elf{32|64}-<arch> (nicht die allgemeine elf{32|64}-{little|big}) Ausgabeoption verwenden, um -B ... erkannt zu machen.

Eine Liste der ELF-Formate/BFD-Typen, mit denen Ihre binutils umgehen können, finden Sie unter objcopy --info.

+0

Sieht aus wie ein guter Weg, es zu tun. Ich werde das ausprobieren. Für die Version der Toolchain, die ich verwende, lautet der Ausgabetyp "elf32-littlearm" – Brian

+1

Wenn Sie an einer eingebetteten Plattform arbeiten, möchten Sie wahrscheinlich, dass Ihre Daten in Flash bleiben, anstatt in RAM geladen zu werden. Fügen Sie Folgendes hinzu, um das Problem zu beheben: --rename-section .data = .rodata – escrafford

+1

arm-none-eabi-objcopy -I binär -O elf32-littlearm -B-arm --name-date .data = .rodata binblob binblob.o – escrafford

1

Eine schnelle Möglichkeit wäre, die Daten in eine eigene .c-Datei (.c nicht .h) zu stellen, so dass sie selbst zu einem .o wird. Dann können Sie im Linker-Skript einen bestimmten Speicherplatz definieren und Abschnitt Eintrag für diese .o-Datei und legen Sie es, wo immer Sie wollen.

MEMORY 
{ 
... 
BOB : ORIGIN = 0x123400, length = 0x200 
... 
} 
SECTIONS 
{ 
... 
TED : { mydata.o } > BOB 
... 
} 
5

Ein anderer Ansatz könnte xxd sein.

xxd -i your_data your_data.c 

In der Datei finden Sie zwei Symbole unsigned char your_data[] und unsigned int your_data_len bekommen. Das erste wird ein riesiges Array sein, das Ihre Daten enthält, das zweite ist die Länge dieses Arrays.

Die Kompilierung der erstellten C-Datei könnte Zeit in Anspruch nehmen. Wenn Sie also ein Buildsystem/Makefile verwenden, können Sie unnötige Neukompilierungen vermeiden.

xxd sollte Teil von vim (vim-common) Paket für Ihre Linux-Distribution sein.

+1

Ich wollte nur ~ die gleiche Antwort schreiben. :) – dbrank0