que gcc arm ld cortex-m3

gcc - que - gnu toolchain



enlazar datos arbitrarios usando la cadena de herramientas GCC ARM (3)

Quiero vincular datos binarios en bruto. Me gustaría ponerlo en una dirección particular, o tener un enlace a un símbolo (por ejemplo, char * mydata) que he definido en el código. Como no es un archivo obj, no puedo simplemente vincularlo.

Una publicación similar ( Incluir archivo binario con el script del enlazador GNU ld ) sugiere usar objcopy con la opción -B bfdarch . objcopy responde con "archictecture bfdarch unknown".

Sin embargo, otra respuesta sugiere transformar el objeto en un script LD personalizado y luego incluirlo desde el script LD principal. En este punto, puedo usar un archivo de inclusión C (que es lo que estoy haciendo ahora) así que preferiría no hacerlo.

¿Puedo usar objcopy para lograr esto, o hay otra manera?


Una forma rápida de hacerlo sería colocar los datos en su propio archivo .c (.c no .h) para que se convierta en un .o por sí mismo, luego en el script del enlazador se puede definir un espacio de memoria específico y una entrada de sección para ese archivo .o y póngalo donde quiera.

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


El siguiente ejemplo funciona para mí:

$ 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

Es decir, no es necesario especificar el arco BFD para datos binarios (solo es útil / necesario para el código). Simplemente diga "la entrada es binaria", y "la salida es ...", y le creará el archivo. Como los datos binarios puros no son específicos de la arquitectura, todo lo que necesita saber es si la salida es 32 bits ( elf32-... ) o 64 bits ( elf64-... ), y si es poco endian / LSB ( ...-little , como en ARM / x86) o big endian / MSB ( ...-big , como p. ej. en SPARC / m68k).

Editar: Aclaración sobre las opciones para objcopy :

  • el uso de los controles de opción -O ...
    • ancho de bits (si el archivo ELF será de 32 bits o de 64 bits)
    • endianness (si el archivo ELF será LSB o MSB)
  • el uso de la opción -B ... controla la arquitectura que solicitará el archivo ELF

Tienes que especificar el -O ... pero el -B ... es opcional. La diferencia se ilustra mejor con un pequeño ejemplo:

$ 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

Es decir, el especificador de formato de salida elf64-x86-64 no elf64-x86-64 el binario generado a una arquitectura específica (es por eso que el file dice que no machine ). El uso si -B i386 hace - y en ese caso, se le dice que ahora es AMD x86-64 .

Lo mismo se aplicaría a ARM; -O elf32-little vs. -O elf32-littlearm -B arm es que en el primer caso, terminas con un ELF 32-bit LSB relocatable, no machine, ... mientras que en el último, será un ELF 32-bit LSB relocatable, ARM...

Aquí también hay cierta interdependencia; tiene que usar -O elf{32|64}-<arch> (no el elf{32|64}-{little|big} genérico elf{32|64}-{little|big} ) opción de salida para poder hacer -B ... reconocido.

Consulte objcopy --info para ver la lista de formatos ELF / tipos de BFD que pueden manejar sus binutils.


Otro enfoque podría ser usar xxd .

xxd -i your_data your_data.c

En el archivo obtendrá dos símbolos unsigned char your_data[] y unsigned int your_data_len . El primero será un gran conjunto que contiene sus datos, el segundo será la longitud de ese conjunto.

La compilación del archivo C creado puede tomar tiempo, por lo que si está utilizando un sistema de compilación / Makefile, trátelo de forma adecuada para evitar recompilaciones innecesarias.

xxd debe ser parte del paquete vim ( vim-common ) para su distribución de Linux.