2013-06-23 12 views
6

Desidero collegare dati binari non elaborati. Mi piacerebbe o metterlo su un particolare indirizzo, o collegarlo a un simbolo (char * mydata, ad esempio) che ho definito nel codice. Dal momento che non è un file obj, non posso semplicemente collegarlo.collegamento di dati arbitrari utilizzando la toolchain GCC ARM

Un post simile (Include binary file with GNU ld linker script) suggerisce di utilizzare objcopy con l'opzione -B bfdarch. objcopy risponde con "archictecture bfdarch unknown".

Un'altra risposta suggerisce di trasformare l'oggetto in uno script LD personalizzato e quindi includerlo dallo script LD principale. A questo punto, posso anche solo usare un file di inclusione C (che è quello che sto facendo ora) quindi preferirei non farlo.

È possibile utilizzare objcopy per eseguire questa operazione o esiste un altro modo?

+3

Come informazioni sui dati char non firmati [] = {0x12, 0x34, 0x56, 0x78, ...}; 'invece? –

+0

H2CO3, è più o meno quello che sto facendo. Ho un comando pre-compilazione per leggere nel file bin e sputare un file H con una serie di dati (come suggerisci tu). Funziona, ma sembra che ci dovrebbe essere un modo migliore per farlo. – Brian

+1

'bfdarch' non è letterale; Prova a "braccio". Funziona sicuramente come con * gas *, ha una [* .incbin * direttiva] (http://linux.web.cern.ch/linux/scientific4/docs/rhel-as-en-4/incbin.html). Ci sono anche una pletora di programmi come 'hexdump' che convertono gli array binari in 'C'. –

risposta

9

L'esempio seguente funziona per me:

$ 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 

Vale a dire non è necessario specificare l'arco BFD per i dati binari (è solo utile/necessario per il codice). Dì solo "l'input è binario" e "l'output è ..." e ti creerà il file. Dato che i dati binari puri non sono specifici dell'architettura, tutto quello che devi dire è se l'uscita è a 32 bit() oa 64 bit (elf64-...), e se è little endian/LSB (...-little, come su ARM/x86) o grande endian/MSB (...-big, ad esempio su SPARC/m68k).

Edit: Chiarimento sulle opzioni per objcopy:

  • l'utilizzo dei controlli -O ... opzione:
    • larghezza bit (se il file ELF sarà a 32 bit o 64-bit)
    • endianness (se il file ELF sarà LSB o MSB)
  • l'utilizzo dell'opzione -B ... controlla l'architettura del file ELF richiederà

È necessario essere indicate le -O ... ma il -B ... è facoltativo. La differenza è meglio illustrata da un piccolo esempio:

$ 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. solo l'identificatore del formato di output elf64-x86-64 non lega il binario generato a un'architettura specifica (ecco perché file dice no machine). L'utilizzo se lo fa -B i386 - e in tal caso, ti viene detto che questo è ora .

Lo stesso si applica a ARM; -O elf32-little rispetto a -O elf32-littlearm -B arm è che nel primo caso, si finisce con uno ELF 32-bit LSB relocatable, no machine, ... mentre in quest'ultimo, sarà un ELF 32-bit LSB relocatable, ARM....

C'è una certa interdipendenza anche qui; è necessario utilizzare l'opzione di output -O elf{32|64}-<arch> (non generica elf{32|64}-{little|big}) per poter riconoscere -B ....

Vedere objcopy --info per l'elenco di formati ELF/tipi di BFD che i binutils possono gestire.

+0

Sembra un buon modo per farlo. Ci proverò. Per la versione della toolchain che sto usando, il tipo di output è "elf32-littlearm" – Brian

+1

Se stai lavorando su una piattaforma embedded, probabilmente i tuoi dati rimarranno in flash invece di essere caricati nella ram. Aggiungete quanto segue per risolvere il problema: --rename-section .data = .rodata – escrafford

+1

arm-none-eabi-objcopy -I binario -O elf32-littlearm -B braccio --rename-sezione .data = .rodata binblob binblob.o – escrafford

1

Un modo rapido per farlo sarebbe inserire i dati nel proprio file .c (.c not .h) in modo che diventi un .o da solo, quindi nello script del linker è possibile definire uno spazio di memoria specifico e sezione per quel file .o e metterlo dove vuoi.

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

Un altro approccio potrebbe essere l'utilizzo di xxd.

xxd -i your_data your_data.c 

Nel file si otterrà due simboli unsigned char your_data[] e unsigned int your_data_len. Il primo sarà un enorme array contenente i tuoi dati, il secondo sarà la lunghezza di quell'array.

La compilazione del file C creato potrebbe richiedere del tempo, quindi se si utilizza un sistema di compilazione/Makefile gestirlo correttamente evitando inutili ricompilazioni.

xxd dovrebbe essere parte del pacchetto vim (vim-common) per la distribuzione Linux.

+1

Stavo per scrivere ~ stessa risposta. :) – dbrank0

Problemi correlati