# 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 fonctionne VirtualBox "sous le capeau".

## Où VirtualBox stocke ses fichiers

Dans VirtualBox, une machine virtuelle et ses paramètres sont déscrits 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

1. le dossier `$HOME/VirtualBox VMs/VM Exemple/` et, dans ce dossier,

2. le fichier des paramètres `VM Exemple.vbox` et

3. 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 gui-createvm. 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`, and 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 vboxmanage-setproperty.

### 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 szstème de fichiers d'alors.

Avant la version 4.0, VirtualBox séparait les fichiers des paramètres de la machine des images de disque virtuel. Les fichiers de paramétrages 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.

1. 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 presqu'impossible si la machine avait des instantanés et, donc, des images de différenciation.

2. 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 respecteront 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 as of 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 XMK 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, ce ne sera pas des retistres de médias globaux ; 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 des modifications de la configuration de 4.0

### ignoreme

| 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` | In each machine's folder
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 n'était possible que d'activer ou de désactiver 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 vboxmanage) et son API (voir le VirtualBoxAPI).

## 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 :

1. `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 autres) 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.

2. 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`.

3. 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 :

1. `VirtualBox`, l'interface Qt implémentant le gestionnaire et les VMS en fonction ;

2. `VBoxManage`, une alternative moins conviviale mais plus puissante, décrite au vboxmanage.

3. `VBoxSDL`, une interface graphique simple basée sur la bibliothèque SDL ; voir vboxsdl.

4. `VBoxHeadless`, une interface de VM qui ne fournit pas directement de sortie graphiqke et d'entrée clavier/souris, mais qui permet une redirection par VirtualBox Remote Desktop Extension; voir vboxheadless.

5. `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 VirtualBoxAPI pour des détails.

6. 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 consiste 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 lese 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 guestadditions.

- Le composant "Main" est spécial : il croise tous les bits 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 VirtualBoxAPI).

## 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 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 szstè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 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 et son soin.

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 pport 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 uo 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 de fautes 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.

- Mour 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 :

1. 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é.

2. 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.

3. 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.

4. 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.

5. 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.

6. 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 performances. 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 szstè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é, vous pourriez trouver que PATM est un recompilateur avancé in-situ recompiler.

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 futures d'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é1 VM", celui en sens invers 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 prurnqué la sortie, et des informations sur la 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 en 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 charge des fins des VMs est relativement élevée. Cela pose des problèmes aux périphériques dont l'émulation requiet un grand nombre de blocages (trass). 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 bloqués.

## Vagination nesté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 nesté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 nestée" implémente la gestion de la mémoire dans le matériel, ae 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 nested, 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 depagination 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 nested élimine la charge causée par les fins de VM et les accès aux tables de pages. Par définition, avec les tables de pages nested, l'invité peut gérer la pagination sans que l'hyperviseur n'intervienne. La pagination nestée améliore ainsi substantiellement les performances de virtualisation.

  Sur les processeurs AMD, la pagination nested est disponible depuis l'architecture Barcelona (K10) -- on l'appelle maintenant la "rapid virtualization indexing" (RVI). Intel a ajouté le support de la pagination nested, qu'ils appellent la "extended page tables" (EPT), à leurs processeurs Core i7 (Nehalem).

  Si la pagination nested est activée, l'hyperviseur de VirtualBox peut également utiliser large 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 vboxmanage-modifyvm.

- 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 de flasher beaucoup les Translation Lookaside Buffers (TLBs) du processeur.

  Pour activer ces fonctions pour une VM, vous devez utiliser les commandes `VBoxManage modifyvm --vtxvpid` and `--largepages` ; voir vboxmanage-modifyvm.