Il peut être pratique d’avoir un environnement de développement ARM utilisable directement depuis un environnement x86 lorsqu’on ne possède pas d’environnement dédié (périphérique cible, raspberry PI par exemple) ou qu’on ne veut pas émuler tout un système d’exploitation dans Qemu pour lancer un simple binaire.
Les étapes suivantes décrivent comment installer l’environnement de compilation (GCC) ainsi que les outils permettant d’exécuter directement un binaire ARM.
Installation
GCC
Sous Gentoo, l’installation de l’environnement crossdev se fait avec une simple commande:
crossdev -t arm-none-eabi
Les packages binutils, gcc et libc sont installés automatiquement :
- crossdev version: 20151026
- Host Portage ARCH: amd64
- Target Portage ARCH: arm
- Target System: arm-none-eabi
- Stage: 3 (C compiler & libc)
- ABIs: default
Les exécutable sont installés avec le préfix: arm-none-eabi-*, par exemple pour gcc: arm-none-eabi-gcc
Qemu
Qemu va permettre d’exécuter notre binaire. Il faut ajouter la cible « arm » dans le fichier /etc/make.conf :
QEMU_USER_TARGETS= »i386 x86_64 arm »
QEMU_SOFTMMU_TARGETS= »i386 x86_64 arm »
GDB
Pour pouvoir debugger un binaire, il faut également installer une version de GDB capable de debugger du code ARM: emerge -av cross-arm-none-eabi/gdb
Compilation de code assembleur ARM
Le code assembleur utilisé est un simple « Hello world » (fichier helloworld.s) :
.global _start _start: mov r7, #4 mov r0, #1 mov r2, #12 ldr r1, =string swi 0 mov r7, #1 swi 0 .data string: .ascii "Hello World\n"
La compilation se fait avec la commande :
arm-none-eabi-as -g helloworld.s -o helloworld.o
puis
arm-none-eabi-ld helloworld.o -o helloworld
Debug avec Qemu et GDB
Exécuter le binaire dans Qemu (en debug) :
qemu-arm -singlestep -g 1234 helloworld
et dans un deuxième terminal, se connecter avec gdb (si vous voulez charger votre configuration dans .gdbinit, il faut retirer l’option -nx):
arm-none-eabi-gdb -q -nx (gdb) file helloworld Reading symbols from helloworld...done. (gdb) target remote 127.0.0.1:1234 Remote debugging using 127.0.0.1:1234 ...
Nous voici connectés en debug, avec un breakpoint à la première ligne:
(gdb) disass _start Dump of assembler code for function _start: => 0x00008000 <+0>: mov r7, #4 0x00008004 <+4>: mov r0, #1 0x00008008 <+8>: mov r2, #12 0x0000800c <+12>: ldr r1, [pc, #8] ; 0x801c <_start+28> 0x00008010 <+16>: svc 0x00000000 0x00008014 <+20>: mov r7, #1 0x00008018 <+24>: svc 0x00000000 0x0000801c <+28>: andeq r8, r1, r0, lsr #32
L’environnement est ainsi fonctionnel.
source:
documentation QEMU Gentoo
documentation crossdev Gentoo