Nous allons voir comment préparer une carte Raspberry Pi pour faire du kernel debugging. Ce post à pour but d’initier au debugging de bas niveau.

Prérequis

Pour faire du kernel debugging il vous suffit d’une machine avec un noyau Linux. Dans mon cas une Raspberry Pi. Vous pouvez aussi utiliser n’importe quelle carte ARM ou pour ce post, mais il faudra surement l’adapter.

J’aurais pu utiliser un ordinateur habituel, mais il est de plus en plus rare de pouvoir accéder à une interface série sur des machines récentes.

Le debugging au niveau du noyau n’est pas la même chose qu’en userland. On interagit directement avec le kernel. Donc on oublie la connexion SSH.

On va devoir passer par une connexion série via les ports GPIO. Pour cela il faut un adaptateur TTL vers USB.

Connexion série

Pour la connexion série, il faut connaitre le brochage GPIO de la Raspberry Pi 3. Pour cela soit vous cherchez vous-même sur Google ou alors vous avez la commande pinout (python3-gpiozero) qui vous affiche tout en bas le brochage de GPIO :

   3V3  (1) (2)  5V
 GPIO2  (3) (4)  5V
 GPIO3  (5) (6)  GND
 GPIO4  (7) (8)  GPIO14 <== receive
   GND  (9) (10) GPIO15 <== transmit
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND
GPIO22 (15) (16) GPIO23
   3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND
 GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8
   GND (25) (26) GPIO7
 GPIO0 (27) (28) GPIO1
 GPIO5 (29) (30) GND
 GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20

Les ports qui nous intéressent sont les suivants :

  • 6 : GND
  • 8 : GPIO14 (TxD)
  • 10 : GPIO15 (RxD)

L’image ci-dessus illustre le branchement que j’ai fais. Pas compliqué, il faut juste ne pas se tromper de PIN.

Il est tout à fait possible de faire la même configuration avec n’importe quel Arduino. Veillez avant de l’utiliser de téléverser un programme vide. Ou du moins qui n’affiche rien sur la sortie série.

Kernel

Si vous souhaitez faire du kernel debugging, vous allez devoir recompiler votre noyau pour que GDB puisse lire les symboles du noyau.

Il suffit de cocher la première case dans Kernel Hacking-> Compile-time checks and compiler options.

Vous pouvez aussi éditer la ligne CONFIG_DEBUG_INFO et configurer à y à la place m dans le fichier .config.

Cet article est toujours d’actualité pour vous aider !

KDB

KDB est le debugger initial implémenté dans le noyau lorsque vous le compilez avec. Contrairement à KGDB il n’y a pas besoin de seconde machine pour le debugging, même si c’est mieux.

Pour activer KDB, il y a deux possibilités :

  • Modifier les paramètres de démarrage du kernel et ajouter cette chaine : console=ttyS0,115200 kgdboc=ttyS0,115200 nokaslr.
  • Au démarrage de la Raspberry Pi à l’aide de la commande suivante : echo ttyS0 > /sys/modules/kgdboc/parameters/kgdboc.

Pour passer en “mode” KDB : il faut ensuite lancer la commande suivante : echo g > /proc/sysrq-trigger.

Cela va stopper l’exécution du kernel pour entrer en mode debugger. En effet, pour se connecter avec gdb depuis kgdboc il faut que le kernel soit en pause.

KGDB

On switch sur KGDB, c’est la version de GDB utilisée pour le kernel debugging. Il est très probable que vous devez lancer GDB sur une machine qui n’a pas la même architecture que la Raspberry Pi.

Pour cela il vous faut une nouvelle version le gdb : arm-linux-gnueabihf-gdb.

Vous pouvez récupérer cette version de GDB sur la page Github de la fondation Raspberry.

Lorsque vous lancez gdb, mettez en argument exécutable vmlinux. Il faut ensuite configurer le baudrate de la Raspberry Pi qui est par défaut à 115200 : (gdb) set remotebaud 115200.

Puis il faut dire à GDB sur quelle interface est la cible : (gdb) target remote /dev/ttyUSB0.

Voilà ! GDB est configuré pour faire du kernel debugging. Il vous faudra un minimum de connaissance en programmation bas niveau et sur l’architecture du noyau Linux pour la suite.

Debugger le noyau devient très utile pour le développement de modules, de drivers ou la recherche de bugs.


C’est un début, mais je vais continuer sur la lignée et faire des posts un peu plus bas niveau sur le noyau Linux.

Si vous avez besoin d’infos ou souhaitez corriger des erreurs, contactez-moi sur Twitter : @matteyeux

Github : matteyeux


Références :

https://www.kernel.org/doc/html/v4.18/dev-tools/kgdb.html

https://www.kernel.org/doc/html/v4.10/dev-tools/gdb-kernel-debugging.html

https://elixir.bootlin.com/linux/latest/source