Memoria Virtuale in Linux
Architetture x86 Su architetture x86 si utilizza segmentazione con paginazione per proteggere la memoria (modalita' user/kernel) segmento per processi kernel (suddiviso in dati e codice) nella parte alta della memoria segmento per processi user (suddiviso in dati e codice) nella parte bassa della memoria segmenti di servizio del sistema
Descrittori dei segmenti in x86 I descrittori dei segmenti sono mantenuti nella Global Descriptor Table (GDT) gestita dall'architettura x86 I descrittori specificano privilegi per l'accesso ai corrispondenti dati (3=user, 0=kernel) Si potrebbero usare i descrittori della GDT per gestire direttamente i segmenti dei processi (le entry della GDT possono puntare a tabelle locali chiamate LDT) Tuttavia in Linux la segmentazione dei singoli processi viene gestita via software
Chiamate di sistema Le interrupt e le chiamate di sistema vengono gestite attraverso la IDT (Interrupt Description Table) che contiene un “gate” per ogni possibile tipo di interrupt Le chiamate di sistema (trap) vengono gestite con un unico “gate” associato all'entry 80 Il tipo di chiamata viene memorizzato in un registro Il gate 80 contiene le informazioni sul segmento e sull'offset associato al codice della system call (segmento kernel)
Segmentazione in Linux La suddivisione logica dei dati di un processo (dati, stack, codice) viene gestita da Linux via software con una struttura dati chiamata vm_area_struct Inoltre i segmenti vengono paginati
Paginazione virtuale La paginazione e' virtualizzata in modo da poter essere mappata su diverse architetture La paginazione “virtuale” e' a 3 livelli anche se alcune architetture non li sfruttano completamente (2 livelli in x86) Ogni piattaforma fornisce macro di traduzione degli indirizzi di pagina in modo da rendere il kernel indipendente dall'architettura sottostante
Tabella delle pagine Ogni processo ha una tabella delle pagine (a sua volta paginata) La page directory di primo livello contiene sia indirizzi di pagine user (parte bassa della memoria) che kernel (parte alta della memoria) In uno schema a due livelli Le directory interne dello spazio kernel sono comuni a tutti I processi Le directory interne dello spazio user sono private
Core map Il kernel mantiene una “core map” (mem_map) per tenere traccia delle pagine libere in memoria Ogni entry nella mem_map mantiene informazioni su una singola pagina fisica (frame) Numero di riferimenti alla pagina (>1 condivisa) Eta' della pagina (per rimpiazzamento/swap) Inoltre si mantiene un'insieme di mappe di bit che corrisponde a insiemi di pagine libere (raggruppate in base al numero di pagine: 2, 4, ...)
Memoria virtuale di un processo La memoria virtuale viene organizzata via software Ad ogni processo viene assegnata una task_struct che punta ad una mm_struct che descrive il suo spazio di indirizzi virtuali La mm_struct punta ad una lista di vm_area_struct
vm_area_struct Ogni vm_area_struct punta ad un area (es. codice e dati) di memoria associata al processo Le strutture vm_area_struct sono inoltre organizzate ad albero binario bilanciato (AVL) per rendere piu veloce la risoluzione degli indirizzi virtuali Una volta individuata la vm_area_struct che contiene l'indirizzo virtuale si utilizza la tabella delle pagine per accedere all'indirizzo fisico
Riassunto In Linux la gestione della memoria virtuale e' a sua volta “virtualizzata” sia a livello di segmenti che di paginazione Questo rende portabile il codice Inoltre si ottiene maggior flessibilita' per gestire la rilocazione (es. ricerca su AVL)