
Rétro-ingénierie du boot ROM du TI AM3358
Voilà probablement dix-huit mois que j'ai mis la main sur quelques cartes Beaglebone Black, sauvées de la benne. Malheureusement, les cartes ne fonctionnaient pas directement. En même temps, c'était la première fois que je travaillais avec l'une de ces cartes, ou avec un ordinateur à carte unique d'ailleurs, donc je n'étais pas sûr que le problème vienne de ce que je faisais, ou des cartes elles-mêmes (peut-être la raison pour laquelle elles étaient destinées à la benne en premier lieu). Il m'a fallu beaucoup de temps et d'efforts pour que ces cartes démarrent réellement, mais bon sang, j'y suis arrivé. Et voici ce que j'ai appris en chemin.
J'ai inclus quelques utilitaires dans ce dépôt, ainsi qu'un fichier xml exporté depuis Ghidra qui contient tous les symboles que j'ai obtenus jusqu'à présent grâce à la rétro-ingénierie. J'ai utilisé ce post pour exporter sans le firmware réel, afin d'éviter tout problème de droits d'auteur, par précaution. Si vous voulez déboguer la boot ROM vous-même, vous aurez déjà le JTAG branché, vous pouvez donc extraire la boot ROM (de 0x20000 à 0x2BFFF) par vous-même.
Pour charger les symboles :
0x20000 dans Options, et vous pouvez définir le nom du bloc sur bootrom.main(), ou le gestionnaire de démarrage MMC/carte SD.Pour commencer, je savais que ces cartes étaient des versions personnalisées de la beaglebone black standard, j'ai donc déterminé assez tôt que quelque chose pouvait manquer sur la carte elle-même, comme un identifiant de carte. Ce que j'ai vu en démarrant une carte SD standard formatée avec balenaEtcher, c'était tout simplement rien. Je m'attendais à ce que les LED de la carte commencent à clignoter, et à ce que le fait de brancher un câble UART vers USB me permette de voir le processus U-Boot. Cependant, l'UART était silencieux. Si je retirais la carte SD, elle émettait la lettre C en boucle, ce qui est un comportement attendu pour un démarrage UART/série. Elle essayait définitivement de démarrer, et la carte SD modifiait ce comportement, mais je n'avais pas plus de visibilité que cela. La plupart des dépannages sur le web prenaient la sortie d'U-Boot comme point de départ pour diagnostiquer les problèmes. Je suppose que je n'allais pas avoir ce luxe.
J'ai alors compris qu'il serait utile de brancher une sonde de débogage. Malheureusement, je n'avais pas de connecteur compatible avec l'empreinte existante, alors j'ai fabriqué le mien.
La carte beaglebone possède un connecteur portant la désignation P2 qui sort les connexions JTAG. J'y ai connecté des fils jusqu'à un connecteur femelle afin de pouvoir communiquer avec elle via mon J-Link.



En lançant Ozone (le débogueur Segger), j'ai configuré le J-Link et j'ai commencé par simplement essayer de trouver le point d'entrée. Je pensais qu'un reset-halt me placerait là où il fallait, ce qui m'a conduit à l'hypothèse (incorrecte) que le point d'entrée était 0x2148a, même si j'ai certainement remarqué que ce n'était pas cohérent. Plus tard, j'ai réalisé que les cartes AM335x ne s'entendent pas vraiment bien avec le reset-halt du J-Link, il y avait donc en réalité un délai de quelques centaines de cycles d'horloge, ce qui m'atterrissait quelque part à l'intérieur d'un gestionnaire de démarrage, de manière non déterministe. (J'ai finalement contourné ce problème en écrivant un fichier GEL pour le Code Composer Studio de TI, qui prend en charge le débogage J-Link - à la réinitialisation, le registre PC est défini sur le gestionnaire de réinitialisation, les registres sont effacés, et le mode d'instruction est forcé en ARM.)
À partir d'un fil de discussion sur les forums TI (AM335x : les employés de TI, où puis-je obtenir le code source/les symboles du ROM Bootloader ?), j'ai récupéré quelques symboles de débogage : SPI Initialize à 0x231e0, SPI ReadSectors à 0x23230, et 0x24bfa est une routine qui effectue une lecture UART. C'est une aide non négligeable, je suppose. J'ai remarqué que le démarrage échouait en aboutissant dans une boucle infinie à 0x402f0440, une boucle morte. Hmm, assez loin du reste de la boot ROM, cela doit être dans la RAM ou quelque chose comme ça. Il est probablement temps de se tourner vers le manuel de référence technique (TRM) !
Le chapitre 26 du TRM contient énormément d'informations sur le démarrage. Nous obtenons la vue suivante de la boot ROM :

Description:
L'architecture du Public ROM Code est illustrée dans la Figure 26-1. Elle est divisée en trois couches principales selon une approche descendante : haut niveau, pilotes et couche d'abstraction matérielle (HAL). Chaque couche communique avec une couche de niveau inférieur via une interface unifiée. La couche de haut niveau est chargée des tâches principales du Public ROM Code : configuration du chien de garde et des horloges, et routine principale de démarrage. La couche des pilotes implémente les protocoles logiques et de communication pour tout périphérique de démarrage conformément à la spécification de l'interface. Enfin, la HAL implémente le code de plus bas niveau pour interagir avec les IP de l'infrastructure matérielle. Les périphériques de démarrage finaux sont connectés aux pads d'E/S du dispositif.
