Logiciels Libres et Systèmes Embarqués


5.13. Débogage

Le débogage du noyau Linux est assez périlleux, il faut faire particulièrement attention lors du passage entre le mode réel et le mode virtuel. En effet, le débogueur GDB risque d'être perdu et de créer un accès illégal à la mémoire. De plus, les interruptions interrompent le flot d'instructions, notamment lors des défauts de TLB ou lorsque le timer est activé, ce qui ne facilite pas le débogage...

Le seul moyen de ne pas perdre le fil de l'exécution et de ne pas provoquer une erreur d'accès mémoire, c'est d'utiliser la commande stepi de GDB. Cette dernière exécute la prochaine instruction puis s'arrête. Si on souhaite avancer de plusieurs instructions d'un seul coup, il vaut mieux utiliser le couple mon bps hw/continue. La commande bps hw permet de placer un point d'arrêt processeur, c'est-à-dire que c'est le PowerPC qui va comparer à chaque pas l'adresse de l'instruction en cours avec celle d'un point d'arrêt. Ces derniers sont en nombre très limités (quatre) mais sont indispensables car les points d'arrêts logiciels (traps) ne marchent pas dans notre cas.

Pour mettre en place le débogueur, il faut avant tout lancer le débogueur matériel XMD et exécuter les commandes suivantes :

XMD% ppconnect
XMD% dow u-boot

Puis, il faut lancer le débogueur logiciel GDB. Ensuite on doit : l'attacher à XMD, charger la table des symboles pour le mode réel, charger la table des symboles pour le mode virtuel, placer un point d'arrêt matériel et lancer l'exécution du chargeur.

(gdb) target remote :1234
(gdb) symbol-file  /Linux/vmlinux
(gdb) add-symbol-file  /Linux/vmlinux 0xC0000000
(gdb) monitor bps 0x00000000 hw
(gdb) continue

Il n'est pas envisageable de charger le noyau tel quel, même s'il n'est pas compressé. En effet, il a besoin d'un certain nombre de paramètres indispensables, tel que la taille de la mémoire disponible. C'est pourquoi il faut charger dans un premier temps U-Boot, qui lui même chargera le noyau.

5.13.1. Niveau d'optimisation

Il est impossible de compiler le noyau sans l'option d'optimisation de GCC. En effet, certaines opérations d'optimisation provoquent une erreur si cette option n'est pas activée, c'est le cas avec les fameux extern inline. Si on souhaite tout de même déboguer, et que l'on ne veut pas s'arracher les cheveux à cause du ré-ordonnancement statique des instructions ou de la fusion de variables, il faut compiler le noyau avec le niveau d'optimisation le plus bas. Pour cela, il faut modifier le fichier Makefile de la manière suivante :

- CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O1 \

5.13.2. Machine Check Exception

Nous avons déjà vu que le débogueur XMD crée une erreur fatale lorsqu'on l'utilise et que l'exception "Machine Check" est activée, ce qui est le cas dans le noyau Linux. Pour les phases de développement, j'ai rajouté une entrée dans le menu de configuration pour préciser si l'on souhaite ignorer cette erreur. Il faut donc modifier le fichier arch/ppc/config.in de la manière suivante :

  if [ "$CONFIG_40x" = "y" ]; then
      choice 'Machine Type'               \
           "Oak           CONFIG_OAK      \
           Virtex         CONFIG_VIRTEX   \
           Walnut         CONFIG_WALNUT"  Walnut
  fi

+ if [ "$CONFIG_VIRTEX" = "y" ]; then
+   bool 'Ignore Virtex Machine Check Exception' CONFIG_VIRTEX_MCE_IGNORE
+ fi

Il suffit ensuite de modifier le fichier include/asm-ppc/processor.h de la manière suivante :

+ #ifndef CONFIG_VIRTEX_MCE_IGNORE
  #define MSR_ME        (1<<12)  /* Machine Check Enable */
+ #else
+ #define MSR_ME        0
+ #endif