Sous-bassements techniques
Le contenu de ce chapitre n'est pas indispensable pour utiliser
VirtualBox avec succès. Nous indiquons ce qui suit à titre informatif pour
ceux qui sont plus familiers de la technologie et de l'architecture informatique
et qui veulent en savoir davantage sur la manière dont fonctionne VirtualBox "sous
le capot".
Où VirtualBox stocke ses fichiers
Dans VirtualBox, une machine virtuelle et ses paramètres sont
décrits dans un fichier de paramètres de la machine virtuelle, au format
XML. De plus, la plupart des machines virtuelles ont un ou plusieurs
disques durs qui leur sont en général présentés par des images de disque
(comme au format VDI). L'endroit où sont stockés tous ces fichiers
dépend de la version de VirtualBox qui a créé la machine.
Machines créées par VirtualBox version 4.0 ou supérieur
À partir de la version 4.0, par défaut, chaque machine virtuelle
dispose d'un répertoire sur votre ordinateur hôte (où tous les fichiers
de cette machine sont stockés -- le fichier des paramètres XML (avec une
extension de fichier .vbox) et ses
images de disque.
Par défaut, ce "dossier machine" se trouve dans un dossier ordinaire
appelé "VirtualBox VMs", créé par VirtualBox dans le dossier personnel
de l'utilisateur du système actuel. L'emplacement de ce répertoire personnel
dépend des conventions du système d'exploitation hôte :
Sur Windows, il s'agit de
%HOMEDRIVE%%HOMEPATH%; en général
quelque chose comme C:\Documents and
Settings\NomUtilisateur\.
Sur Mac OS X, il s'agit de
/Users/nomutilisateur.
Sur Linux et Solaris, il s'agit de
/home/nomutilisateur.
Par simplicité, nous abrègerons cela ci-dessous par
$HOME. En utilisant cette convention, le
dossier ordinaire de toutes les machines virtuelles est
$HOME/VirtualBox VMs.
Par exemple, quand vous créez une machine virtuelle qui s'appelle
"VM Exemple", vous verrez que VirtualBox crée
le dossier $HOME/VirtualBox VMs/VM Exemple/
et, dans ce dossier,
le fichier des paramètres VM Exemple.vbox et
l'image de disque virtuel VM Example.vdi.
C'est le rangement par défaut si vous utilisez l'assistant "Créer
une nouvelle machine virtuelle" comme décrit au . Une fois que
vous commencez à travailler avec la VM, des fichiers supplémentaires
apparaîtront : vous trouverez des fichiers journaux dans un
sous-dossier qui s'appelle
Logs, et une fois que vous aurez pris
des instantanés, ils apparaîtront dans un sous-dossier
Snapshots. Pour chaque VM, vous pouvez
modifier l'emplacement de son dossier d'instantanés dans les paramètres
de la VM.
Vous pouvez changer le dossier machine par défaut en sélectionnant
"Préférences" du menu "Fichier" de la fenêtre principale de VirtualBox.
Puis, dans la fenêtre qui apparaît, cliquez sur l'onglet "Général". Sinon,
utilisez VBoxManage setproperty
machinefolder ;; voir le .
Machines créées par des versions de VirtualBox antérieures à 4.0
Si vous avez mis à jour vers VirtualBox 4.0 en partant d'une ancienne
version de VirtualBox, vous aurez probablement vos fichiers de paramètres
et les disques selon l'organisation du système de fichiers d'alors.
Avant la version 4.0, VirtualBox séparait les fichiers de
paramètrage de la machine des images de disque virtuel. Les fichiers de
paramétrage de la machine avaient une extension
.xml et se trouvaient dans un dossier
appelé "Machines" dans le répertoire de configuration global de VirtualBox
(voir la prochaine section). Donc, par exemple, sur Linux, il s'agissait
du répertoire caché $HOME/.VirtualBox/Machines.
Le dossier par défaut des disques durs s'appelait "HardDisks" et se trouvait
également dans le dossier .VirtualBox.
L'utilisateur pouvait changer les deux endroits dans les préférences
globales (le concept de "dossier par défaut des disques durs" a été
abandonné avec VirtualBox 4.0, vu que les images de disque se trouvent
désormais par défaut dans le dossier de chaque machine.)
L'ancienne organisation avait plusieurs gros inconvénients.
Il était très difficile de déplacer une machine virtuelle
d'un hôte à l'autre car les fichiers concernés ne se trouvaient pas
dans le même dossier. De plus, les médias virtuels de toutes les
machines étaient enregistrés avec un registre global dans le
fichier des paramètres transversaux de VirtualBox.
($HOME/.VirtualBox/VirtualBox.xml).
Pour déplacer une machine sur un autre hôte, il n'était donc
pas suffisant de déplacer le fichier des paramètres XML et les images
de disque (qui se trouvaient à des endroits différents), mais
il fallait en plus copier méticuleusement les entrées du disque
dur à partir du XML du registre de médias global, ce qui était
presque impossible si la machine avait des instantanés et, donc, des
images de différenciation.
Le stockage des images de disque virtuel, qui peuvent beaucoup
grossir, sous le répertoire caché
.VirtualBox (au moins sur les hôtes
Linux et Solaris) amenait de nombreux utilisateurs à se demander
ce qu'était devenu leur espace disque.
Si les nouvelles VMs créées avec VirtualBox 4.0 ou supérieur
respectent la nouvelle organisation, pour une compatibilité maximum, les
anciennes VMs ne sont pas converties en nouvelle
organisation. Sans cela, les paramètres de la machine seraient immanquablement
cassés si l'utilisateur rétrogradait de la 4.0 à une version plus ancienne
de VirtualBox.
Données globales de configuration
Outre les fichiers des machines virtuelles, VirtualBox gère des
données globales de configuration. Sur Linux et Solaris, depuis VirtualBox 4.3
elles se trouvent dans le répertoire caché $HOME/.config/VirtualBox
même si $HOME/.VirtualBox sera utilisé
s'il existe pour rester compatible avec les anciennes versions ; sur
un Mac, elles se trouvent
dans $HOME/Library/VirtualBox.
VirtualBox crée automatiquement ce répertoire de configuration si
nécessaire. Vous pouvez éventuellement fournir un répertoire de configuration
alternatif en réglant la variable d'environnement
VBOX_USER_HOME ou,
en plus, sur Linux ou Solaris, en utilisant la variable standard
XDG_CONFIG_HOME (car le
fichier des paramètres globaux de VirtualBox.xml
pointe vers tous les autres fichiers de configuration, ce qui permet
de naviguer entre plusieurs configurations de VirtualBox.
VirtualBox stocke essentiellement dans ce répertoire son fichier
de paramètres globaux, un autre fichier XML appelé
VirtualBox.xml. Cela comprend des
options de configuration globales et la liste des machines virtuelles
enregistrées avec des pointeurs vers leurs fichiers de paramètres XML.
(Ni l'emplacement du fichier ni son répertoire n'ont changé avec
VirtualBox 4.0.)
Avant VirtualBox 4.0, tous les médias virtuels (fichiers images
de disque) étaient également stockés dans un registre global de ce
fichier de paramètres. Par compatibilité, ce registre de médias existe
toujours si vous mettez à jour VirtualBox et s'il y a des médias
issus de machines créées avec une version inférieure à 4.0. Si vous
n'avez pas de telles machines, il n'y aura pas de registre de médias
global ; avec VirtualBox 4.0, chaque fichier XML d'une machine a
son propre registre de médias.
De même, avant VirtualBox 4.0, le dossier "Machines" par défaut
et le dossier "HardDisks" par défaut se trouvaient dans le répertoire de
configuration de VirtualBox (par exemple, $HOME/.VirtualBox/Machines
sur Linux). Si vous mettez à jour à partir d'une version de VirtualBox
inférieure à la 4.0, les fichiers de ce répertoire ne sont pas déplacés
automatiquement afin de ne pas casser la rétro compatibilité.
Résumé des modifications de la configuration de 4.0
Changements de configuration en 4.0 et ultérieure
La table suivante donne un bref apperçu des changements de configuration
entre les versions anciennes et la 4.0 ou ultérieure :
Avant 4.0
4.0 ou supérieur
Dossier par défaut des machines
$HOME/.VirtualBox/Machines
$HOME/VirtualBox
VMs
Emplacement des images de disque
$HOME/.VirtualBox/HardDisks
Dans chaque dossier de machine
Extension des fichiers de paramètres de la machine
.xml
.vbox
Registre de médias
Fichier VirtualBox.xml
global
Chaque fichier des paramètres d'une machine
Enregistrement des médias
Ouverture/fermeture explicite obligatoire
Automatique après la connexion
Fichiers XML de VirtualBox
VirtualBox utilise l'XML tant pour les fichiers des paramètres
de la machine que pour le fichier de configuration global,
VirtualBox.xml.
Tous les fichiers XML de VirtualBox sont versionnés. Quand un nouveau
fichier de paramètres est créé (par exemple parce qu'on crée une nouvelle
machine virtuelle), VirtualBox utilise automatiquement le format des
paramètres de la version actuelle de VirtualBox. Il se peut que ces
fichiers ne soient pas lus si vous rétrogradez à une version plus
ancienne de VirtualBox. Cependant, quand VirtualBox rencontre un fichier
de paramètres d'une ancienne version (comme après une mise à jour de
VirtualBox), il essaie autant que possible de garder le format des
paramètres. Il ne mettra à jour en silence les fichiers des paramètres
que si les paramètres actuels ne peuvent pas être exprimés dans l'ancien
format, par exemple parce que vous avez activé une fonction qui n'était
pas présente dans l'ancienne version de VirtualBox.
Par exemple, avant VirtualBox 3.1, il était possible d'activer
/désactiver qu'un seul lecteur DVD dans une machine virtuelle.
S'il a été activé, cela serait toujours possible sur le deuxième
maître du contrôleur IDE. Avec VirtualBox 3.1, on peut connecter
des lecteurs DVD à un slot de son choix sur un contrôleur de son choix,
donc ils pourraient être sur le deuxième esclave d'un contrôleur IDE
ou sur un slot SATA. Si vous avez un fichier de paramètres d'une
machine d'une ancienne version et si vous mettez à jour
VirtualBox vers la 3.1 et si vous déplacez le lecteur DVD de sa
position par défaut, on ne peut pas l'exprimer dans l'ancien format
des paramètres ; le fichier XML de la machine serait écrit dans
le nouveau format et une copie de sauvegarde de l'ancien format serait
gardée.
Dans ces cas-là, VirtualBox sauvegarde le fichier des anciens
paramètres dans le répertoire de configuration de la machine virtuelle.
Si vous avez besoin de revenir à une ancienne version de VirtualBox,
vous devrez recopier à la main ces fichiers de sauvegarde.
Nous ne documentons volontairement pas les spécifications des fichiers
XML de VirtualBox car nous nous réservons le droit de les modifier à l'avenir.
Nous vous suggérons donc fortement de ne pas éditer ces fichiers à la main.
VirtualBox offre un accès complet à ses données de configuration par son
outil en ligne de commande VBoxManage
(voir le ) et son API (voir le ).
Exécutables et composants de VirtualBox
VirtualBox a été conçu pour être modulaire et flexible. Quand on ouvre
l'interface graphique (GUI) de VirtualBox et qu'on démarre une VM,
au moins trois processus fonctionnent :
VBoxSVC, le processus du service
de VirtualBox qui fonctionne toujours en tâche de fond. Ce processus
est lancé automatiquement par le processus du premier client
VirtualBox (la GUI, VBoxManage,
VBoxHeadless, le service web ou
autre) et il s'arrête peu de temps après que le dernier client a
quitté. Le service est responsable d'archiver, maintenir l'état de
toutes les VMs et de la communication entre les composants de VirtualBox.
Cette communication est implémentée via COM/XPCOM.
Quand nous parlons de "clients" ici, nous voulons dire
les clients locaux d'un processus serveur
VBoxSVC en particulier, pas les
clients sur un réseau. VirtualBox utilise son propre concept
client/serveur pour permettre à ses processus de coopérer, mais
tous ces processus tournent sous le même compte utilisateur du
système d'exploitation hôte, et c'est entièrement transparent
pour l'utilisateur.
Le processus de la GUI,, VirtualBox,
une application client basée sur la bibliothèque multiplateformes
Qt. Lancée sans l'option --startvm,
cette application agit comme un gestionnaire de VirtualBox, en
affichant les VMs et leurs paramètres. Elle communique alors les
paramètres et les changements d'état à VBoxSVC
et elle répercute les changements subis par d'autres moyens comme
VBoxManage.
Si on lance l'application client VirtualBox
avec l'argument --startvm, elle
charge la bibliothèque VMM qui inclut l'hyperviseur proprement dit
et qui lance une machine virtuelle et offre une entrée et une sortie
à l'invité.
Toutes les interfaces de VirtualBox (client) communiqueront avec le
processus du service et elles peuvent contrôler et répercuter l'état actuel.
Par exemple, tant le selecteur de VM que la fenêtre de VM ou VBoxManage peuvent
être utilisés pour mettre en pause la VM en fonction, les autres composants
reflèteront toujours le changement d'état.
La GUI de VirtualBox n'est qu'une des nombreuses interfaces (client)
disponibles. La liste complète comprise dans VirtualBox est :
VirtualBox, l'interface Qt
implémentant le gestionnaire et les VMs en fonction ;
VBoxManage, une alternative
moins conviviale mais plus puissante, décrite au .
VBoxSDL, une interface graphique
simple basée sur la bibliothèque SDL ; voir .
VBoxHeadless, une interface de
VM qui ne fournit pas directement de sortie graphique et d'entrée
clavier/souris,
mais qui permet une redirection par VirtualBox Remote Desktop Extension;
voir .
vboxwebsrv, le processus du
service web de VirtualBox qui permet de contrôler un hôte VirtualBox à
distance. Ceci est décrit en détails dans le manuel de référence
du VirtualBox Software Development Kit (SDK) ; merci de voir le
pour des détails.
Le shell Python de VirtualBox, une alternative en Python à
VBoxManage. Elle est aussi décrite dans le manuel de référence du SDK.
En interne, VirtualBox comprend beaucoup plus d'interfaces
séparées. Vous pourriez les rencontrer en analysant les messages d'erreur
internes ou les fichiers journaux. Parmi elles, on compte :
IPRT, une bibliothèque d'exécution portable qui forme une couche
d'abstraction d'accès aux fichiers, du filage (threading), la manipulation
de chaînes, etc. Chaque fois que VirtualBox accède aux fonctions du
système hôte, il le fait via cette bibliothèque pour une portabilité
multiplateformes.
VMM (Virtual Machine Monitor), le cœur de l'hyperviseur.
EM (Execution Manager), contrôle l'exécution d'un code invité.
REM (Recompiled Execution Monitor), fournit une émulation logicielle
des instructions du processeur.
TRPM (Trap Manager), intercepte et traite les traps et les
exceptions de l'invité.
HWACCM (Hardware Acceleration Manager), offre un support pour
VT-x et AMD-V.
PDM (Pluggable Device Manager), une interface abstraite entre le
VMM et les périphériques émulés qui sépare les implémentations du
périphérique de l'intérieur du VMM et qui facilite l'ajout de nouveaux
périphériques émulés. Par PDM, des développeurs tiers peuvent ajouter
de nouveaux périphériques virtuels à VirtualBox, sans devoir modifier
VirtualBox lui-même.
PGM (Page Manager), un composant contrôlant la pagination de
l'invité.
PATM (Patch Manager), corrige le code de l'invité pour améliorer
et accélérer la virtualisation logicielle.
TM (Time Manager), gère les horloges et tous les aspects de l'heure
des invités.
CFGM (Configuration Manager), fournit une structure arborescente
qui garde les paramètres de configuration de la VM et tous les périphériques
émulés.
SSM (Saved State Manager), enregistre et charge l'état d'une VM.
VUSB (Virtual USB), une couche USB qui sépare les contrôleurs USB
émulés des contrôleurs de l'hôte et des périphériques USB ; ceci
active également l'USB distant.
DBGF (Debug Facility), un débogueur de VM intégré.
VirtualBox émule un certain nombre de périphériques pour offrir
l'environnement matériel dont ont besoin divers invités. La plupart de
ces périphériques standards se trouvent dans beaucoup de machines
compatibles PC et sont largement supportés par les systèmes d'exploitation
invités. Pour les périphériques réseaux et de stockage en particulier,
il existe plusieurs options pour que les périphériques émulés accèdent
au matériel sous-jacent. Ces périphériques sont gérés par
PDM.
Les suppléments invité pour divers systèmes d'exploitation invités.
Il s'agit de code installé dans les machines virtuelles ; voir .
Le composant "Main" est spécial : il lie tous les modules
ci-dessus et c'est la seule API publique fournie par VirtualBox. Tous
les processus clients listés ci-dessus n'utilisent que cettte API et
n'accèdent jamais directement aux composants de l'hyperviseur. Il s'en
suit que des applications tierces utilisant l'API principale de VirtualBox
peuvent s'appuyer sur le fait qu'elle est toujours bien testée et que
toutes les possibilités de VirtualBox sont complètement présentées. C'est
cette API qui est décrite dans le manuel de référence du SDK de
VirtualBox indiqué ci-dessus (de nouveau, voir le ).
Virtualisation matérielle vs. logicielle
VirtualBox permet aux logiciels de la machine virtuelle de s'exécuter
directement sur le processeur de l'hôte, mais il utilise une gamme de
techniques complexes pour intercepter les opérations interférant avec votre
hôte. Chaque fois que l'invité essaie de faire quelque chose de potentiellement
dangereux pour votre ordinateur et ses données, VirtualBox s'interpose et
rentre en action. En particulier, pour beaucoup de matériel auquel croit
avoir accès l'invité, VirtualBox simule un certain environnement "virtuel"
selon la façon dont vous avez configuré une machine virtuelle. Par exemple,
quand l'invité cherche à accéder à un disque dur, VirtualBox redirige ces
requêtes vers ce que vous avez configuré comme étant le disque dur virtuel
de la machine virtuelle -- en principe, un fichier image sur votre hôte.
Malheureusement, la plateforme x86 n'a jamais été conçue pour
être virtualisée. La détection des
situations où VirtualBox doit contrôler le code invité qui s'exécute, comme
décrit ci-dessus, est difficile. Il existe deux façons de faire cela :
Depuis 2006, les processeurs Intel et AMD supportent ce qu'on
appelle la "virtualisation matérielle".
Cela signifie que ces processeurs peuvent aider VirtualBox à intercepter
des opérations potentiellement dangereuses que pourrait essayer de
faire le système d'exploitation invité et ils facilitent la présentation
de matériel virtuel à une machine virtuelle.
Ces fonctionnalités du matériel diffèrent entre les processeurs
Intel et AMD. Intel a appelé sa techno VT-x ;; AMD a nommé la leur AMD-V. Le support d'Intel et d'AMD de la
virtualisation est très différent dans le détail, mais pas si différent
dans le principe.
Sur de nombreux systèmes, les fonctions de virtualisation
matérielle doivent être préalablement activées dans le BIOS avant
de pouvoir être utilisées par VirtualBox.
Contrairement aux autres logiciels de virtualisation, pour
de nombreux scénari d'utilisation, VirtualBox n'exige pas
que les fonctions de virtualisation matérielle soient présentes.
Par des techniques sophistiquées, VirtualBox virtualise beaucoup
de systèmes d'exploitation invités complets de manière
logicielle. Cela signifie que vous
pouvez lancer des machines virtuelles même sur d'anciens processeurs
qui ne supportent pas la virtualisation matérielle.
Même si VirtualBox n'exige pas toujours la virtualisation matérielle,
son activation est nécessaire dans les scénari suivants :
Certains systèmes d'exploitation, rares, comme OS/2, utilisent
des instructions processeur très ésotériques qui ne sont pas supportées
par notre virtualisation logicielle. Pour les machines virtuelles
configurées pour contenir un tel système d'exploitation, la
virtualisation matérielle est activée automatiquement.
Le support des invités 64 bits de VirtualBox (ajouté avec la
version 2.0) et le multiprocessing (SMP, ajouté avec la version 3.0)
exigent tous deux l'activation de la virtualisation matérielle (ce n'est
tout de même pas une grosse limite vu l'immense majorité des processeurs
64 bits et multi cœurs actuels incluant lavirtualisation matérielle ;
les exceptions à cette règle étant par exemple les anciens processeurs
Intel Celeron et AMD Opteron.)
Ne lancez pas d'autres hyperviseurs (produits de virtualisation
open-source ou propriétaires) en même temps que VirtualBox ! Si
plusieurs hyperviseurs peuvent, en principe, être installés
en parallèle, n'essayez pas de lancer plusieurs
machines virtuelles à partir d'hyperviseurs concurrents en même temps.
VirtualBox ne peut pas savoir ce qu'un autre hyperviseur essaie de faire
sur un même hôte, et surtout si plusieurs produits essaient d'utiliser la
virtualisation matérielle, les fonctions telles que VT-x, cela peut planter
tout l'hôte. De plus, dans VirtualBox, vous pouvez mélanger la virtualisation
logicielle et matérielle quand vous lancez plusieurs VMs. Dans certains cas,
une petite perte de performances sera inévitable si vous mélangez des
VMs avec virtualisation VT-x et logicielle. Nous recommandons de ne pas
mélanger les modes de virtualisation si la performance maximum et
une faible surcharge (overhead) sont essentiels. Cela ne s'applique pas
à AMD-V.
Détails sur la virtualisation logicielle
L'implémentation de la virtualisation sur les processeurs x86 sans
le support de la virtualisation matérielle est une tâche extraordinairement
complexe car l'architecture du processeur n'a pas été conçue pour être
virtualisée. On peut résoudre en général les problèmes, mais au prix de
performances réduites. Ainsi, il existe un conflit constant entre les
performances de virtualisation et la précision.
Le jeu d'instructions x86 a été conçu au départ dans les années 1970 et
subi des modifications significatives avec l'ajout d'un mode protégé dans
les années 1980s avec l'architecture du processeur 286, puis à nouveau avec
l'Intel 386 et l'architecture 32 bits. Alors que le 386 avait un
support de virtualisation vraiment limité pour les opérations en mode réel,
(le mode V86, utilisé par la "DOS Box" de Windows 3.x et d'OS/2 2.x), aucun
port n'existait pour virtualiser toute l'architecture.
En théorie, la virtualisation logicielle n'est pas complexe en soi.
Outre les quatre niveaux de privilèges ("rings") fournis par le matériel
(dont en général on n'utilise que deux : ring 0 pour le mode noyau et ring 3
pour le mode utilisateur), il faut faire la différence entre le "contexte
hôte" et le "contexte invité".
Dans le "contexte hôte", tout est comme s'il n'y avait pas d'hyperviseur
actif. Cela pourrait être le mode actif si une autre application de votre
hôte consomme du temps processeur ; dans ce cas, il existe un mode
ring 3 hôte et un mode ring 0 hôte. L'hyperviseur n'est pas impliqué.
Par contre, dans le "contexte invité", une machine virtuelle est active.
Tant que le code invité s'exécute en ring 3, ce n'est pas très problématique
vu qu'un hyperviseur peut paramétrer les tableaux des pages correctement et
exécuter ce code de manière native sur le processeur. Les problèmes arrivent
sur la manière d'intercepter ce que fait le noyau de l'invité.
Il y a plusieurs solutions possibles à ces problèmes. Une approche
est l'émulation logicielle totale, ce qui implique généralement une recompilation.
A savoir que tout le code qui doit être exécuté par l'invité est analysé,
transformé sous une forme qui n'autorisera pas l'invité à modifier et à
voir l'état réel du processeur, lequel l'exécutera simplement. Ce processus
est bien sûr très complexe et coûteux en termes de performances. (VirtualBox
contient un recompilateur basé sur QEMU qu'on peut utiliser pour une
émulation logicielle pure, mais le recompilateur n'est activé que dans
des situations particulières, décrites ci-dessous.)
Une autre solution possible est la paravirtualisation, où seuls les
OS invités spécialement modifiés sont autorisés à s'exécuter. De cette manière,
la plupart des accès matériels sont rendus abstraits et toutes les fonctions
qui accèderaient normalement au matériel ou à l'état privilégié du processeur
se basent plutôt sur l'hyperviseur. La paravirtualisation peut donner
de bonnes fonctionnalités et de bonnes performances sur des processeurs
x86 standards, mais cela ne peut marcher que si l'OS invité peut être
modifié, ce qui n'est évidemment pas toujours le cas.
VirtualBox choisit une approche différente. Quand on démarre une
machine virtuelle par son pilote noyau du support ring-0, VirtualBox a
réglé le système hôte pour qu'il puisse lancer nativement la plupart du
code invité, mais il s'insère lui-même "en bas" de l'image. Il peut alors
supposer le contrôle lorsque c'est nécessaire -- si une instruction privilégiée
est exécutée, l'invité plante (traps) (en particulier car un accès au registre
E/S a été tenté et un périphérique doit être virtualisé) ou car des interruptions se produisent. VirtualBox peut
alors gérer cela et soit acheminer une requête vers un périphérique virtuel,
soit, si possible, déléguer la gestion de tels éléments à l'OS hôte ou
invité. Dans le contexte invité, VirtualBox peut être donc dans un des trois
états :
Le code invité ring 3 s'exécute sans modifications, à pleine
vitesse, autant que possible. Le nombre d'erreurs sera généralement
faible (sauf si l'invité autorise l'E/S du port depuis ring 3,
chose que nous ne pouvons pas faire car nous ne voulons pas que
l'invité puisse accéder aux ports réels). On parle aussi de "mode brut",
car le code ring-3 de l'invité s'exécute sans modifications.
Pour le code invité en ring 0, VirtualBox utilise une astuce
savoureuse : il reconfigure l'invité pour que son code ring-0
se lance plutôt en ring 1 (ce qui n'est en principe pas utilisé sur les
systèmes d'exploitation x86). Il s'en suit que lorsque le code ring-0
de l'invité (qui s'exécute en fait en ring 1) tel que le pilote d'un
périphérique invité, essaie d'écrire sur un registre E/S ou d'exécuter
une instruction non privilégiée, l'hyperviseur de VirtualBox en ring
0 "réel" peut prendre le dessus.
L'hyperviseur (VMM) peut être actif. Chaque fois qu'une erreur
survient, VirtualBox regarde l'instruction problématique et il peut
la reléguer à un périphérique virtuel, à l'OS hôte, à l'invité ou
il peut le lancer dans le recompilateur.
En particulier, on utilise le recompilateur quand le code invité
désactive les interruptions et VirtualBox ne peut pas savoir quand
on y reviendra (dans ces situations, VirtualBox analyse en fait le
code invité en utilisant son propre désassembleur). De plus, certaines
instructions privilégiées telles que LIDT doivent être gérées à part.
Enfin, tout le code en mode réel ou protégé (comme le code du BIOS,
un invité DOS ou un démarrage de système d'exploitation) se lance
complètement dans un recompilateur.
Malheureusement, cela ne fonctionne que dans une certaine mesure.
Entre autres, les situations suivantes nécessitent une gestion spéciale :
L'exécution de code ring 0 en ring 1 provoque beaucoup d'erreurs
d'instructions supplémentaires car ring 1 n'est pas autorisé à exécuter
des instructions privilégiées (dont le ring-0 de l'invité en contient
beaucoup). Avec chacune de ces erreurs, le VMM doit s'arrêter et
émuler le code pour obtenir le comportement désiré. Si cela fonctionne,
l'émulation de milliers d'erreurs est très coûteuse et très pénalisante
en performances de l'invité virtualisé.
Il existe des défauts dans l'implémentation de ring 1 de
l'architecture x86 qui n'ont jamais été corrigés. Certaines instructions
qui planteraient même en ring 1 ne le font pas.
Cela concerne par exemple les paires d'instructions LGDT/SGDT, LIDT/SIDT,
ou POPF/PUSHF. Alors que l'opération "load" est privilégiée et peut
donc planter, l'instruction "store" réussit toujours. Si l'invité est
autorisé à les exécuter, il verra l'état réel du PC et pas celui
virtualisé. L'instruction CPUID a également le même problème.
Un hyperviseur a en général besoin de réserver certaines parties
de l'espace d'adresse de l'invité (tant l'espace d'adresse liénaire
que les sélecteurs) pour son propre usage. Ce n'est pas complètement
transparent pour l'OS invité et cela peut provoquer des conflits.
L'instruction SYSENTER (utilisée pour les appels système) exécutée
par une application en fonction dans un OS invité transite toujours
par le ring 0. Mais c'est là où l'hyperviseur se lance et pas l'OS
invité. Dans ce cas, l'hyperviseur doit bloquer et émuler l'instruction
même quand ce n'est pas souhaitable.
Les registres de segments du processeur contiennent un cache
de descripteur "caché" inaccessible de manière logicielle. L'hyperviseur
ne peut pas lire, enregistrer ou restaurer cet état, mais l'OS invité
peut l'utiliser.
Certaines ressources doivent (et peuvent) être neutralisées par
l'hyperviseur, mais l'accès est si fréquent que cela crée une perte
significative de performance. Un exemple réside dans le registre
TPR (Task Priority) en mode 32 bits. Les accès à ce registre doivent
être bloqués par l'hyperviseur, mais certains systèmes d'exploitation
invités (en particulier Windows et Solaris) écrivent très souvent
dans ce registre, ce qui porte une atteinte certaine aux performances
de virtualisation.
Pour corriger ces problèmes de performances et de sécurité, VirtualBox
contient un gestionnaire d'analyse et de scan de code
(Code Scanning and Analysis Manager (CSAM)), qui désassemble le code invité,
et un gestionnaire de correctifs (Patch Manager (PATM)), qui peut le remplacer
pendant l'exécution.
Avant d'exécuter du code ring 0, CSAM le scanne de manière récursive
pour trouver des instructions problématiques. PATM le corrige in-situ
, c'est-à-dire qu'il remplace l'instruction par un passage à la
mémoire de l'hyperviseur, où un générateur intégré a mis une implémentation
plus convenable. En réalité, c'est une tâche très complexe car il existe
de nombreuses situations compliquées à trouver et à gérer correctement. Donc,
vu son actuelle complexité, on pourrait dire que PATM est un recompilateur
avancé in-situ.
De plus, à chaque fois qu'une erreur survient, VirtualBox analyse
le code problématique pour déterminer s'il est possible de le corriger afin
de l'empêcher de provoquer davantage de futures erreurs. Cette approche
fonctionne bien en pratique et améliore de façon drastique les performances
de la virtualisation logicielle.
Détails sur la virtualisation matérielle
Avec VT-x d'Intel, il existe deux modes opératoires du processeur :
le mode racine VMM et le mode non-racine.
En mode racine, le processeur se comporte beaucoup comme les
anciennes générations de processeurs sans le support VT-x. Il y a quatre
niveaux de privilèges ("rings") et le même jeu d'instructions est
supporté avec, en plus, des instructions spécifiques de virtualisation.
Le mode racine est ce que le système d'exploitation hôte utilise sans
virtualisation, et il est aussi utilisé par l'hyperviseur quand la
virtualisation est active.
En mode non-racine, le fonctionnement du processeur est très
différent. Il y a toujours quatre niveaux de privilèges et le même
jeu d'instructions, mais une nouvelle structure, qui s'appelle VMCS
(Virtual Machine Control Structure), contrôle désormais le fonctionnement
du processeur et elle détermine la manière dont se comportent certaines
instructions. Le mode non-racine est celui dans lequel les systèmes invités
fonctionnent.
Le passage du mode racine au mode non racine s'appelle "l'entrée VM",
celui en sens inverse s'appelle "Quitter VM". Le VMCS inclut une zone d'état
invité et hôte sauvegardée/restaurée à chaque entrée et sortie en VM.
Surtout, les VMMS contrôlent les opérations de l'invité qui feront quitter
la VM.
Les VMCS permettent un contrôle très fin via ce que les invités
peuvent et ne peuvent pas faire. Par exemple, un hyperviseur peut autoriser
un invité à écrire certains bits dans des registres de contrôle protégés,
mais pas dans d'autres. Cela permet une virtualisation efficace dans des cas
où les invités peuvent être autorisés à écrire des bits de contrôle sans
gêner l'hyperviseur, tout en les empêchant de modifier les bits de contrôle
dont l'hyperviseur a besoin pour avoir un contrôle total. Le VMMS fournit
aussi un contrôle via l'affichage d'interruptions et les exceptions.
Chaque fois qu'une instruction ou un événement fait quitter une VM,
le VMCS contient des informations sur les raisons de la sortie, ainsi que,
souvent, des détails environnants. Par exemple, si une écriture dans le
registre CR0 fait quitter, l'instruction en cause est enregistrée, ainsi
que le fait qu'un accès en écriture sur le registre de contrôle a provoqué
la sortie, ainsi que les informations sur le registre source et destination.
L'hyperviseur peut ainsi gérer efficacement la condition sans avoir besoin
de techniques avancées telles que CSAM et PATM décrits ci-dessus.
VT-x évite intrinsèquement plusieurs problèmes qui se posent avec la
virtualisation logicielle. L'invité a son propre espace d'adresse distinct,
qu'il ne partage pas avec l'hyperviseur, ce qui élimine les plantages
potentiels. De plus, le code du noyau de l'OS invité se lance avec le
privilège ring 0 en mode non racine VMX, rendant inopérants les problèmes
d'exécution de code en ring 0 sur des niveaux moins privilégiés. Par exemple,
l'instruction SYSENTER peut faire une transition vers le ring 0 sans problèmes.
Naturellement, même en ring 0 en mode non-racine VMX, tous les accès E/S par
le code invité amène toujours la VM à quitter, permettant l'émulation
de périphérique.
La plus grosse différence entre VT-x et AMD-V est qu'AMD-V fournit
un environnement de virtualisation plus complet. VT-x exige que le code
non-racine VMX s'exécute en mode pagination activée, ce qui rejette la
virtualisation matérielle de logiciels dont le code est en mode réel et en
mode protégé non paginé. Cela n'inclut en général que les firmwares et les
chargeurs d'OS, néanmoins cela complique l'implémentation d'un hyperviseur
avec VT-x. AMD-V n'a pas cette restriction.
Bien entendu, la virtualisation matérielle n'est pas parfaite. Par
rapport à la virtualisation logicielle, la surcharge (overherad) des sorties des VMs est
relativement élevée. Cela pose des problèmes aux périphériques dont l'émulation
requiet un grand nombre de captures (traps). Par exemple, avec le périphérique
VGA en mode 16 couleurs, mon seulement tous les accès au port en E/S, mais
aussi tous les accès à la mémoire tampon (framebuffer) doivent être
capturés.
Pagination imbriquée (imbriquée) et VPIDs
En plus de la virtualisation matérielle "brute", votre processeur peut
supporter aussi des techniques sophistiquées supplémentaires :
VirtualBox 2.0 a ajouté le support de la pagination imbriquée d'AMD ;
le support de l'EPT et des VPIDs d'Intel a été ajouté à la version 2.1.
Une fonctionnalité récente, qui s'appelle la
"pagination imbriquée" implémente la
gestion de la mémoire dans le matériel, ce qui peut beaucoup accélérer
la virtualisation matérielle puisque ces tâches n'ont plus besoin d'être
accomplies par le logiciel de virtualisation.
Avec la pagination imbriquée, le matériel fournit un autre niveau
d'indirection en passant du linéaire aux adresses physiques. Les
tables de page fonctionnent comme avant mais les adresses linéaires
sont désormais d'abord traduites en adresses physiques de "l'invité"
et pas directement en adresses physiques. Il existe maintenant un
nouveau jeu de registres de pagination sous le mécanisme de pagination
traditionnel et qui traduit les adresses physiques invitées en adresses
physiques de l'hôte, qui sont utilisées pour accéder à la mémoire.
La pagination imbriquée élimine la charge causée par les sorties de
VM et les accès aux tables de pages. Par définition, avec les tables
de pages imbriquées, l'invité peut gérer la pagination sans que l'hyperviseur
n'intervienne. La pagination imbriquée améliore ainsi substantiellement
les performances de virtualisation.
Sur les processeurs AMD, la pagination imbriquée est disponible
depuis l'architecture Barcelona (K10) -- on l'appelle maintenant la
"rapid virtualization indexing" (RVI). Intel a ajouté le support de
la pagination imbriquée, qu'ils appellent la "extended page tables" (EPT),
à leurs processeurs Core i7 (Nehalem).
Si la pagination imbriquée est activée, l'hyperviseur de VirtualBox
peut également utiliser grandes pages,
pour réduire l'utilisation du TLB et la charge. Cela peut provoquer
une amélioration jusqu'à 5% des performances. Pour activer cette
fonctionnalité pour une VM, vous avez besoin d'utiliser la commande
VBoxManage modifyvm
--largepages ;
voir .
Sur les processeurs Intel, une autre fonction matérielle, qui
s'appelle "Virtual Processor Identifiers" (VPIDs),
peut beaucoup accélérer le changement de contexte en réduisant le
besoin coûteux de mémoriser les Translation Lookaside Buffers
(TLBs) du processeur.
Pour activer ces fonctions pour une VM, vous devez utiliser
les commandes VBoxManage modifyvm --vtxvpid et
--largepages ; voir .