L'implementazione della macchina virtuale è un kernel per il kernel.
In un tipico sistema operativo, c'è application code (aka "userland") e kernel code . Usano lo stesso insieme di istruzioni; tuttavia, la CPU sa, in qualsiasi momento, se sta eseguendo l'applicazione o il codice del kernel. Quando il codice dell'applicazione tenta di eseguire alcuni codici opzionali che accedono all'hardware (il in
e il out
opcode per x86), la CPU trap : passa temporaneamente al codice del kernel (l'indirizzo di quel codice è registrato in una tabella specifica). Il codice del kernel decide cosa fare con l'accesso (concedilo, modificalo, uccidi il processo di applicazione ...). Se il codice del kernel decide di concedere l'accesso, o il kernel lo blocca, ma fa finta di averlo eseguito, allora il codice dell'applicazione può credere che possa accedere direttamente all'hardware.
Allo stesso modo, quando il codice dell'applicazione legge o scrive dati in memoria, utilizza un'astrazione di memoria: uno spazio di indirizzo virtuale che viene mappato alla memoria fisica (o meno ...) tramite MMU . La MMU usa le tabelle che il kernel riempie (e, ovviamente, il kernel si preoccupa di non rendere queste tabelle parte dello spazio degli indirizzi visibile dal codice dell'applicazione). In questo modo, l'applicazione si trova in un mondo magico in cui è solo in un grande spazio di indirizzamento, mentre in realtà ci sono diverse applicazioni eseguite simultaneamente, che non possono vedersi.
Una macchina virtuale utilizza la stessa struttura, un livello più alto. Quando il kernel accede all'hardware o alla MMU, in realtà è sotto esame dell'implementazione della macchina virtuale (il hypervisor ) che intrappola gli accessi indesiderati.
I dettagli variano molto. La distinzione principale è se il kernel è consapevole del fatto che viene eseguito in una macchina virtuale o meno. Con Xen , il kernel è a conoscenza; sa che è sotto il controllo di una divinità superiore (l'hypervisor) e non tenta di attingere direttamente all'hardware; invece, chiede graziosamente attraverso un'interfaccia dedicata. Con VirtualBox , il kernel non è a conoscenza; il sistema operativo guest crede che funzioni su hardware vero, e la VM lavora duramente per mantenere l'illusione.
Altre differenze possono essere fatte sulle modalità con cui viene applicata la virtualizzazione (cioè come l'hypervisor può intercettare il codice del kernel). I processori x86 recenti offrono un supporto specifico con codici opzionali dedicati . I processori x86 più vecchi, in modalità a 32 bit, possono utilizzare i vari resti di meccanismi di protezione meno recenti (i registri di segmento ei quattro "anelli", per lo più) (questi sono stati rimossi dalla modalità a 64 bit, motivo per cui la macchina virtuale a 64 bit deve usa AMD-V / VT-x). Altre tecniche includono l'emulazione di ogni opcode virtualizzato (per l'intera macchina emulata, o parti di esso), possibilmente con una traduzione dinamica più o meno (ovvero una compilazione JIT), aas QEMU funziona in situazioni cross-CPU.
C'è un intero armamentario di termini sull'argomento (virtualizzazione, paravirtualizzazione, emulazione, simulazione, hypervisor ...) che non è completamente consensuale e spesso abbastanza bizantino. Alcuni lettori che si aggrappano a determinate dottrine di terminologia probabilmente sono stati in qualche modo irritati dal modo sciolto in cui uso i termini.