Skip to content
Snippets Groups Projects
Commit 591d5631 authored by Florent Gluck's avatar Florent Gluck
Browse files

updated 02-KVM.md and lab-virtual_game_machine.md

parent 130375da
No related branches found
No related tags found
No related merge requests found
...@@ -457,7 +457,7 @@ while (!done) { ...@@ -457,7 +457,7 @@ while (!done) {
## Example of MMIO driver code: write to UART ## Example of MMIO driver code: write to UART
```{.tiny .c} ```{.tiny .c}
// Base UART register // Base UART register (MMIO)
#define UART_BASE 0x10009000 #define UART_BASE 0x10009000
// Data register // Data register
...@@ -491,23 +491,23 @@ The following code reads a sector from the first IDE[^10] disk (on the first bus ...@@ -491,23 +491,23 @@ The following code reads a sector from the first IDE[^10] disk (on the first bus
// A sector has a size of 512 bytes // A sector has a size of 512 bytes
#define SECTOR_SIZE 512 #define SECTOR_SIZE 512
// IDE status register (on first bus) // Status register on the primary bus (read-only)
#define STATUS_PORT 0x1F7 #define STATUS_REG 0x1F7
// IDE base port (on first bus) // Command register on the primary bus (write-only)
#define DATA_PORT 0x1F0 #define CMD_REG 0x1F7
// IDE control register (on first bus) // Base data register on primary bus (write-only)
#define CONTROL_PORT 0x3F6 #define DATA_BASE_REG 0x1F0
// Assembly function that writes 8-bits data to address port // Assembly function that writes 8-bits data to address port (PMIO)
extern void outb(uint16_t port, uint8_t data) void outb(uint16_t port, uint8_t data)
// Assembly function that reads 8-bits from address port // Assembly function that reads 8-bits from address port (PMIO)
extern uint8_t inb(uint16 port) uint8_t inb(uint16 port)
// Assembly function that reads 16-bits from address port // Assembly function that reads 16-bits from address port (PMIO)
extern uint16_t inb(uint16 port) uint16_t inw(uint16 port)
``` ```
[^10]:\scriptsize IDE is the grandfather of the SATA protocol [^10]:\scriptsize IDE is the grandfather of the SATA protocol
...@@ -519,24 +519,24 @@ extern uint16_t inb(uint16 port) ...@@ -519,24 +519,24 @@ extern uint16_t inb(uint16 port)
This function reads a sector in LBA[^11] mode: This function reads a sector in LBA[^11] mode:
```{.tiny .c} ```{.tiny .c}
// Read sector n into buffer data (512 bytes and already allocated). // Read sector n into data (allocated by the caller).
void read_sector(int n, uint8_t *data) { void read_sector(int n, uint8_t *data) {
while ((inb(STATUS_PORT) & 0xC0) != 0x40); // Wait for drive to be ready while ((inb(STATUS_REG) & 0xC0) != 0x40); // Wait for drive to be ready
// Prepare disk for read or write at specified sector in 28-bit LBA mode // Prepare disk for read or write at specified sector in 28-bit LBA mode
outb(0x1F2, 1); // Set sector count outb(DATA_BASE_REG+2, 1); // Set sector count
outb(0x1F3, n & 0xff); // Set bits 00-07 of LBA outb(DATA_BASE_REG+3, n & 0xff); // Set bits 00-07 of LBA
outb(0x1F4, (n >> 8) & 0xff); // Set bits 08-15 of LBA outb(DATA_BASE_REG+4, (n >> 8) & 0xff); // Set bits 08-15 of LBA
outb(0x1F5, (n >> 16) & 0xff); // Set bits 16-23 of LBA outb(DATA_BASE_REG+5, (n >> 16) & 0xff); // Set bits 16-23 of LBA
outb(0x1F6, ((n >> 24) & 0x0f) | 0xe0); // Set bits 24-27 of LBA outb(DATA_BASE_REG+6, ((n >> 24) & 0x0f) | 0xe0); // Set bits 24-27 of LBA
// + set LBA mode // + set LBA mode
outb(STATUS_PORT, 0x20); // Command: read sector with retry outb(CMD_REG, 0x20); // Command: read sector with retry
while ((inb(STATUS_PORT) & 0xC0) != 0x40); // Wait for drive to be ready while ((inb(STATUS_REG) & 0xC0) != 0x40); // Wait for drive to be ready
uint16_t *data = (uint16_t *)src; uint16_t *data = (uint16_t *)src;
for (int i = 0; i < SECTOR_SIZE/2; i++) { // Read the sector, for (int i = 0; i < SECTOR_SIZE/2; i++) { // Read sector content,
*data = inw(DATA_PORT); // 16-bits at a time *data = inw(DATA_BASE_REG); // 16-bits at a time
data++; data++;
} }
} }
...@@ -600,14 +600,18 @@ void read_sector(int n, uint8_t *data) { ...@@ -600,14 +600,18 @@ void read_sector(int n, uint8_t *data) {
::: incremental ::: incremental
- The idea behind paravirtualization is simple: the guest OS sends a service request to the VMM - In a OS, a user app can request a service from the OS
- Conceptually very similar to a user app requesting a service from the OS
- this mechanism is called a **syscall** - this mechanism is called a **syscall**
- \textcolor{myblue}{In paravirtualization, guest requests a service from the VMM}
- \textcolor{myblue}{this mechanism is called an \textbf{hypercall}} \vspace{.2cm}
- Device paravirtualization is simpler and much easier to implement than emulation, hence we describe it first
- The idea behind paravirtualization is very similar:
- \textcolor{myblue}{the guest OS \textbf{requests a service} from the VMM}
- this mechanism is called an **hypercall**
\vspace{.3cm} \vspace{.3cm}
- **\textcolor{mygreen}{How to implement paravirtualization?}**
- ![](images/hypercalls_vs_syscalls.png){ width=70% }
::: :::
...@@ -622,13 +626,6 @@ void read_sector(int n, uint8_t *data) { ...@@ -622,13 +626,6 @@ void read_sector(int n, uint8_t *data) {
- guest OS requests to display something - guest OS requests to display something
- guest OS requests to send a network packet - guest OS requests to send a network packet
[//]: # ----------------------------------------------------------------
## Hypercalls vs system calls
- Mechanism similar to a system call between an application and an OS:\
\vspace{1cm}
\centering ![](images/hypercalls_vs_syscalls.png){ width=80% }
[//]: # ---------------------------------------------------------------- [//]: # ----------------------------------------------------------------
## Benefits of hypercalls ## Benefits of hypercalls
...@@ -645,10 +642,14 @@ void read_sector(int n, uint8_t *data) { ...@@ -645,10 +642,14 @@ void read_sector(int n, uint8_t *data) {
[//]: # ---------------------------------------------------------------- [//]: # ----------------------------------------------------------------
## Hypercall principle ## Hypercall principle
::: incremental
- How does the guest OS request an hypercall to the VMM? - How does the guest OS request an hypercall to the VMM?
- An hypercall is simply a **specific `VMexit`** triggered by the guest OS, associated to a function **number** - An hypercall is simply a **specific `VMexit`** triggered by the guest OS, associated to a function **number**
- Hypercalls arguments (parameters) are stored in an area of **shared memory** between VMM and guest OS - Hypercalls arguments (parameters) are stored in an area of **shared memory** between VMM and guest OS
:::
[//]: # ---------------------------------------------------------------- [//]: # ----------------------------------------------------------------
## Hypercalls: PMIO or MMIO? ## Hypercalls: PMIO or MMIO?
......
...@@ -46,10 +46,10 @@ sudo apt-get install --no-install-recommends make gcc nasm lib32gcc-13-dev libc6 ...@@ -46,10 +46,10 @@ sudo apt-get install --no-install-recommends make gcc nasm lib32gcc-13-dev libc6
## Description de la plateforme à virtualiser ## Description de la plateforme à virtualiser
La plateforme à virtualiser, appelée "Game Machine", dispose d'un CPU à architecture Intel/AMD 32 bits (IA-32) et de 512KB de RAM. La plateforme à virtualiser, appelée "Game Machine", dispose d'un seul CPU à architecture Intel/AMD 32 bits (IA-32) et de 512KB de RAM.
Elle dispose d'un ensemble de périphériques réels (physiques), mais présente également les mêmes périphériques sous forme virtuelle. Elle expose un ensemble de périphériques réels (physiques) et expose les mêmes périphériques sous forme virtuelle.
Les périphériques exposés dans la VM sont les suivants\ : Les périphériques exposés par la VM sont les suivants\ :
- console virtuelle - console virtuelle
- timer - timer
...@@ -62,11 +62,11 @@ Les sous-sections qui suivent décrivent le but et les fonctionnalités de chaqu ...@@ -62,11 +62,11 @@ Les sous-sections qui suivent décrivent le but et les fonctionnalités de chaqu
### Mécanisme d'hypercall ### Mécanisme d'hypercall
Une demande d'hypercall est signalée par le guest en écrivant, sur 8 bits, le numéro d'hypercall à l'adresse 0xABBA en PMIO (port). Une demande d'hypercall est signalée par le guest en écrivant, sur 8 bits, le numéro d'hypercall à l'adresse `0xABBA` en PMIO (port).
### (1) Console virtuelle ### (1) Console virtuelle
Ce périphérique est uniquement virtuel, donc disponible de manière paravirtualisée. Il permet au guest de demander au VMM d'afficher un message (une chaîne de caractères) sur une console virtuelle. Cette console virtuelle est simplement la sortie standard du VMM. Ce périphérique est uniquement exposé virtuellement (c'est à dire de manière paravirtualisée). Il permet au guest de demander au VMM d'afficher un message (une chaîne de caractères) sur une console virtuelle. Cette console virtuelle est simplement la sortie standard du VMM.
**Comportement du VMM** **Comportement du VMM**
...@@ -88,7 +88,7 @@ Le VMM affiche le texte spécifié par le guest sur la sortie standard. ...@@ -88,7 +88,7 @@ Le VMM affiche le texte spécifié par le guest sur la sortie standard.
### (2) Timer ### (2) Timer
Ce périphérique est disponible physiquement et virtuellement (de manière paravirtualisée). Il offre une seule fonctionnalité\ : attendre un certain nombre de micro-secondes. Ce périphérique est exposé physiquement et virtuellement. Il offre une seule fonctionnalité\ : attendre un certain nombre de micro-secondes.
**Comportement du VMM** **Comportement du VMM**
...@@ -118,7 +118,7 @@ Comment attendre `n` micro-secondes\ ? ...@@ -118,7 +118,7 @@ Comment attendre `n` micro-secondes\ ?
### (3) Initialisation affichage ### (3) Initialisation affichage
Ce périphérique est disponible physiquement et virtuellement. Il offre une seule fonctionnalité\ : initialiser l'affichage à la résolution demandée. Ce périphérique est exposé physiquement et virtuellement. Il offre une seule fonctionnalité\ : initialiser l'affichage à la résolution demandée.
**Comportement du VMM** **Comportement du VMM**
...@@ -152,7 +152,7 @@ Comment initialiser l'affichage avec une résolution de `w` par `h`\ ? ...@@ -152,7 +152,7 @@ Comment initialiser l'affichage avec une résolution de `w` par `h`\ ?
### (4) Disque ### (4) Disque
Ce périphérique est disponible physiquement et virtuellement. Il offre une seule fonctionnalité\ : écrire un secteur avec le contenu souhaité. Un secteur a une taille d'exactement 512 bytes. Un disque est une collection de secteurs, donc la taille d'un disque est forcément un multiple de 512 bytes. Le numéro d'un secteur à écrire est au minimu 0 et au maximum $2^{28}-1$. Ce périphérique est exposé physiquement et virtuellement. Il offre une seule fonctionnalité\ : écrire un secteur avec le contenu souhaité. Un secteur a une taille d'exactement 512 bytes. Un disque est une collection de secteurs, donc la taille d'un disque est forcément un multiple de 512 bytes. Le numéro d'un secteur à écrire est au minimu 0 et au maximum $2^{28}-1$.
**Comportement du VMM** **Comportement du VMM**
...@@ -181,7 +181,7 @@ Le code pour programmer l'écriture d'un secteur vous est donné dans le fichier ...@@ -181,7 +181,7 @@ Le code pour programmer l'écriture d'un secteur vous est donné dans le fichier
### (5) Clavier ### (5) Clavier
Ce périphérique est disponible physiquement et virtuellement. Il offre une seule fonctionnalité\ : initialiser l'affichage à la résolution demandée. Ce périphérique est exposé physiquement et virtuellement. Il offre une seule fonctionnalité\ : initialiser l'affichage à la résolution demandée.
**Comportement du VMM** **Comportement du VMM**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment