lundi, janvier 31, 2011

Les Hackers dans l'espaaaaaaaaaaaaace !

Il y a 40 ans exactement aujourd'hui, Apollo 14 était lancé vers la Lune. Alan Shepard et Edgar Mitchell devaient se poser près du cratère Fra Mauro, déjà sélectionné pour la mission précédente Apollo 13 qui se termina comme on le sait.

La mission se déroula relativement normalement jusqu'à la préparation de la descente (PDI, Powered Descent Initiation), pendant laquelle les contrôleurs de vol (notamment le GUIDO) détectèrent que l'ordinateur de bord du LM recevait un signal électrique indiquant que le bouton ABORT était enfoncé.



Ces deux boutons jouent un rôle fondamental : ils permettent au commandant de terminer la descente en cas de problème grave ne permettant pas un alunissage en sécurité : le premier effectue un abandon avec le moteur de descente, le second (ABORT STAGE) sépare l'étage de descente et allume le moteur de remontée.

Evidemment avec une indication que le bouton est enfoncé, dès le début de la descente, elle allait être arrêtée sans possibilité de continuer ... Les contrôleurs demandèrent alors à l'équipage d'effectuer la plus vieille manoeuvre de l'informatique : tapoter sur le panneau de contrôle ... Et miracle le bit correspondant (Channel 30, Bit 1) à ABORT s'effaça ... pour revenir quelques minutes plus tard : il y avait bien un faux contact (non détecté sur terre mais probablement lié à l'apesanteur) dans l'interrupteur.

Il fallait donc trouver rapidement (les trajectoires et les réserves du LEM imposaient d'atterrir apres au maximum deux orbites complètes en parking autour de la lune) une procédure afin de permettre :
  • d'ignorer le bouton ABORT pendant la descente ;
  • pouvoir effectuer un abandon manuel rapidement en cas de problème.
L'ordinateur des vaisseaux Apollo (AGC : Apollo Guidance Computer) avait été conçu et programmé par une équipe du MIT. Il était utilisé dans le CSM et dans le LM, avec des logiciels légèrement différents. C'était un ordinateur très avancé pour son temps, utilisant des circuits intégrés, équipé de 36 kilomots de 15bits de mémoire morte et 2048 mots de mémoire vive, avec une horloge de 2MHz. Il était surtout équipé d'un séquenceur temps réel et gérant des priorités, capable de se redémarrer sans perte, ce qui sauva le premier alunissage.
Il faut bien comprendre que les programmes étant stockés en ROM, il était impossible de les modifier en vol, et que la très faible mémoire vive disponible ne permettait pas d'implémenter un patch logiciel. Enfin le fonctionnement de la télémétrie ne permettait pas au MCC d'envoyer autre chose que des données de vol (principalement positions et constantes d'équations de trajectoire).

Aujourd'hui, grâce à quelques fous, il est possible de simuler l'AGC sur n'importe quel micro, et surtout les codes sources des programmes utilisés par la NASA sont disponibles (ils ont été scannés) et compilables (les programmes sont écrits dans un assembleur d'assez haut niveau). La documentation "utilisateur" est disponible pour le logiciel utilisé sur Apollo-15.

Les signaux issus des boutons ABORT sont gérés par la routine R10, appelée 4 fois par seconde, et ne sont gérés évidemment que quand un "BURN" est en cours, ce qui correspond lors de l'alunissage aux programmes P63 (Descente), P64 (Freinage final) et P66 (Vol manuel lors de l'alunissage). Pour cela, un flag LETABRT autorisant l'abandon est positionné dans la mémoire. A l'époque, tout le monde était root , y compris les astronautes, et ils pouvaient donc repositionner n'importe quel bit dans la mémoire de l'AGC : il était donc tentant de vider simplement ce flag. Malheureusement, la routine de démarrage du moteur (appellée BURNBABY) la positionne dès que le moteur est allumé : quelque soit la rapidité des astronautes, il y avait donc un risque d'une race condition si le petit bout de métal probablement dans l'interrupteur se manifestait à ce moment là ...

Heureusement, R10 effectue également un autre test : elle vérifie qu'il n'y a pas dejà un ABORT en cours en vérifiant avant de les placer dans le séquenceur que les programmes P70 ou P71 ne sont pas déjà lancés. Pour celà, elle vérifie que la variable MODREG contenant normalement le programme principal en cours n'a pas la valeur 70 ou 71.

Don Eyles, un des programmeurs du MIT, a alors eu la bonne idée de proposer un gros hack à la NASA : demander à l'équipage, après l'initiation du programme P63, lancé quelques minutes avant la descente et qui va se charger d'allumer le moteur, de changer MODREG en mémoire par 71 : ainsi la routine R10 sera bypassée. Dès que le moteur sera démarré, la variable LETABRT sera remise à 0 par l'équipage, puis MODREG repositionné sur 63.

Malheureusement rien n'est simple en informatique, et la routine BURNBABY vérifie elle même si le programme actuel est P63 : si oui, alors elle programme la mise en route à 100% du moteur après 26 secondes, et place un bit (ZOOMFLAG) indiquant que les données venant du radar d'alunissage doivent être prises en compte pour la suite des calculs de trajectoires. Avec P71 dans MODREG, pas de THROTTLE UP ni de calcul de trajectoire !

Pas grave : l'homme étant, comme disait Von Braun, « le meilleur ordinateur pouvant être mis dans un vaisseau spatial et le seul pouvant être produit par une main d'oeuvre non qualifiée », les astronautes sont capables de positionner manuellement le moteur à 100% après 26 secondes, puis de positionner rapidement ZOOMFLAG dans la mémoire de l'AGC.

La méthode finale fut donc la suivante :
  • Après que le programme P63 soit lancé mais avant l'allumage, placer MODREG sur 71 ;
  • A l'allumage du moteur, compter 26" avec un chronomètre ;
  • Pousser le moteur à 100% ;
  • Mettre ZOOMFLAG à 1 ;
  • Mettre LETABRT à 0;
  • Remettre 63 dans MODREG.
Pour cela, les astronautes ont utilisé le DSKY (clavier de l'AGC) , dont l'interface basique reposait sur la notion de VERB (action) et de NOUN (objet) ainsi VERB 01 permet d'afficher une donnée, NOUN 01 indique que c'est une adresse en mémoire qui est demandée, alors que NOUN 35 indique que l'on veut lire l'horloge.

La séquence ci-dessus est donc la suivante :
  • VERB 21 NOUN 01 ENTER 1010 ENTER 107 ENTER (1010 est l'adresse de MODREG, 107 = 71 en octal)
  • Démarrage et poussée
  • VERB 25 NOUN 7 ENTER 101 ENTER 200 ENTER, 1 ENTER (101 est l'adresse du mot contenant ZOOMFLAG, 200 le masque octal, 1 la valeur finale)
  • VERB 25 NOUN 7 ENTER 105 ENTER 400 ENTER, 0 ENTER (105 est l'adresse du mot contenant LETABRT, 400 le masque octal, 0 la valeur finale)
  • VERB 21 NOUN 01 ENTER 1010 ENTER 77 ENTER (remise dans MODREG de 77 = 63 en octal)




Pour remettre en place le flag LETABRT en cas d'abandon réel demandé, il suffisait donc de rentrer VERB 25 NOUN 7 ENTER 105 ENTER 400 ENTER, 1 ENTER. Cela peut prendre quelques secondes, ce qui peut suffire à tuer les astronautes en cas d'abandon très près de la lune, mais cela a été jugé comme étant un risque acceptable.

Tout se passa comme prévu, et Alan Shepard put finalement aller taper quelques balles de golf sur la lune ("Miles and miles ...").

Le fait que les astronautes puissent écraser n'importe quelle valeur dans l'AGC n'était pas forcément connu, et cela a d'ailleurs posé problème lors du retour d'Apollo 11 quand Michael Collins, en oubliant de taper un NOUN a écrasé (temporairement) les valeurs envoyés par la plate-forme inertielle (descendre à 158:20:40).

Je ne suis pas sûr du tout qu'aujourd'hui un contournement serait aussi facile à implémenter sur un système d'exploitation moderne (et donc plus sécurisé) et des programmes utilisant des langages de haut niveau.

L'exploration des logiciels d'Apollo et leur simulation est en tout cas passionnante, notamment parce qu'elle montre comment programmer dans un environnement restreint, et il faut remercier les tarés qui ont scanné le code source et l'ont sauvé de l'oubli.

Apollo Surface Journal : http://www.hq.nasa.gov/office/pao/History/alsj/frame.html
Apollo Flight Journal : http://history.nasa.gov/afj/
Virtual AGC : http://www.ibiblio.org/apollo

1 commentaire:

O a dit…

Sainte vache. Je connaissais l'histoire, mais pas les détails, en particulier le coup de 26 secondes.

De nos jours ils se prendraient un NullPointerVaTeFaireException dans la tronche et ils auraient pas l'air malins.