Ours & Hippy — le blogOurs & Hippyourshippy@huoc.orgtag:blog.huoc.org,2009:atom2010-03-03T21:33:53+01:00tag:blog.huoc.org,2009:posts/43
Une modeste introduction à (mon travail sur) QEMU
2010-03-03T21:33:53+01:002010-03-03T21:33:53+01:00Nhat Minh Lê (rz0)
<p>Voilà un petit mois que j’ai commencé mon stage en laboratoire, stage
facultatif entrant dans mon cursus Ensimag. Pour les curieux, je suis
chez <a class="extern" href="http://tima.imag.fr/">TIMA</a>, un labo en plein centre de
Grenoble. Durant ce stage, je suis censé étudier la prise en charge de
processeurs <a class="extern" href="http://fr.wikipedia.org/wiki/VLIW">VLIW</a> par <a class="extern" href="http://www.qemu.org">QEMU</a>, en me basant sur l’exemple du C64x+, un
<a class="extern" href="http://fr.wikipedia.org/wiki/DSP">DSP</a> conçu par Texas Instrument. L’objectif est d’établir une méthode
convaincante, et un petit prototype qui l’illustre sur le C64x+.
</p><p>Pour l’heure, je ne peux que constater que j’ai un mal certain
à m’adapter à QEMU. Ce n’est pas tant à cause de la documentation
interne quasi inexistante, ça, disons, j’ai l’habitude avec le code
libre. Mais la structure même du programme est à mon sens quelque peu
obscure : de la redondance entre modules similaires, une isolation
architecturale qui me paraît douteuse, et des conventions qui semblent
au premier abord très peu intuitives.<sup>α</sup>
</p><div class="Notes"><p>α : J’entends d’ici la horde de fanboys en puissance qui se prépare
à me lyncher. <i>Disclaimer!</i> Ce n’est pas que je dénigre le travail
accompli, ou les mecs derrière tout ça, qui, à n’en pas douter, sont
doués, géniaux, sublimes, etc. plus que je ne le serai
jamais… Bref, je ne fais que constater que, du point de vue du
gars qu’on emploie (gratuitement) à hacker ce code, c’est pas
évident…
</p></div><p>Dans ce premier article, donc, je vous propose simplement une petite
présentation de QEMU et de sa technique d’émulation, du moins, ce que
j’en ai compris. :)
</p><h3><i>QEMU is an emulator</i>
</h3><p>Et ouais, QEMU, ce n’est pas WINE. Car QEMU, <em>c’est</em> un émulateur, un
programme capable d’exécuter du binaire destiné à d’autres
machines. Dans la petite jungle des solutions d’interopérabilité
binaire, l’émulateur est sans doute celui qui se place au niveau le
plus bas puisqu’il lit et imite une architecture directement au niveau
de son jeu d’instructions. QEMU se différencie en cela de logiciels de
virtualisation, tels que <a class="extern" href="http://www.xen.org">Xen</a>, dont j’ai <a href="http://blog.huoc.org/./35-netbsd-xen-test.html">déjà parlé</a> dans un
billet précédent, dont le but est de faire tourner des systèmes
différents mais conçus pour le même CPU, sur une même machine.
</p><p>Le travail d’un émulateur est donc de lire et d’exécuter un code
binaire ; en l’occurrence, il s’agit du codage des instructions d’une
machine réelle, mais cela pourrait tout à fait être une machine
abstraite. Au final, les techniques possibles sont semblables à celles
que l’on peut imaginer pour un compilateur. Simplement, ici, le
langage source est binaire (et le langage cible aussi). L’analyseur
« syntaxique » se voit donc remplacé par une espèce d’automate dont le
rôle est de décoder le binaire en entrée, à la manière du processeur
que l’on imite. On y gagne a priori en simplicité : les formes que
peuvent prendre les instructions sont généralement assez régulières et
limitées. Mais les subtilités guettent ! Pour peu que le jeu
d’instructions soit un peu étoffé, les cas particuliers se multiplient
rapidement. De plus, il faut prendre en compte l’état de la machine ;
en terme de langages, cela se traduirait par un contexte.
</p><p>Une fois l’instruction identifiée… reste à l’exécuter. Là encore,
comme pour les langages de programmation, le choix s’offre à nous,
notamment entre interprétation et compilation. Et QEMU a choisi…
</p><h3>Traduction binaire dynamique
</h3><p>… la traduction binaire dynamique.<sup>β</sup> En quelques mots, il s’agit
d’une compilation à la volée vers du code exécutable par le processeur
hôte (faisant tourner QEMU lui-même). Ce code est ensuite directement
exécuté. Et hop ! On a un truc pas trop lent. C’est <i>grosso modo</i> le
même principe que dans les <a class="extern" href="http://fr.wikipedia.org/wiki/Compilation_à_la_volée">JIT</a> que l’on trouve dans les machines
virtuelles de langages de haut niveau, et dont, il y a quelques
années, tout le monde était trop fier.<sup>γ</sup>
</p><div class="Notes"><p>β : Wikipédia donne « translation dynamique de code », mais désolé,
je ne vois aucun avantage à utiliser « translation » ici à part se
donner l’air plus analphabète qu’on ne l’est. :] Plus sérieusement,
il me paraît douteux qu’un tel terme soit entré dans l’usage, aussi,
je ne me sens pas obligé de l’employer…
</p><p>γ : <i>Then some Lisp defenders came and ruined the fun…</i>
</p></div><p>Plus en détails, QEMU est composé de modules implémentant chacun
l’émulation d’un processeur donné, appelé processeur cible <i>(target)</i>,
en opposition au processeur hôte, sur lequel tourne QEMU, et vers
lequel les instructions vont être traduites. La responsabilité
d’analyser l’entrée binaire est déléguée au module.
</p><p>Celui-ci lit l’entrée par blocs qu’il traduit dans un langage
intermédiaire, composé d’un jeu de micro-opérations minimal. Un bloc
est une suite simple d’instructions, qui s’exécutent linéairement, les
unes après les autres. Concrètement, cela signifie que le bloc prend
fin au premier saut. Ce code intermédiaire est transmis à TCG, le
générateur de code de QEMU, qui se charge de le traduire pour
l’hôte. Cela ressemble à s’y méprendre à de la compilation, n’est-ce
pas ? Ici, on retrouve les avantages usuellement attribués à l’usage
d’un langage intermédiaire : abstraction, uniformité, simplicité.
</p><h3>Et moi, dans tout ça ?
</h3><p>Et bien moi, dans tout ça, je travaille surtout sur la partie analyse
et génération du code intermédiaire. L’objectif de mon stage est
d’élaborer une méthode de traduction systématique de jeux
d’instructions VLIW vers le langage intermédiaire de QEMU. L’idée
serait d’automatiser les aspects fastidieux liés à la multitude de cas
possibles introduite par le parallélisme. Ainsi, à partir d’une
description abstraite du jeu d’instructions, j’espère pouvoir générer
le code qui effectue réellement la traduction.
</p><p>À l’heure où j’écris ces lignes, je commence tout juste à m’attaquer
à la partie traduction. J’ai passé ce dernier mois (du moins les jours
où je travaillais dessus) à faire connaissance avec QEMU, et, dans une
moindre mesure, l’architecture du C64x+. Pour l’heure, je n’ai produit
qu’un squelette plus que minimaliste de <i>target</i> C64x+, dont je pense
reparler bientôt, dans un prochain article technique consacré au récit
de mon (début de) périple dans les entrailles de QEMU !
</p>