Le classificazioni sono due: monolitico/microkernel e statico/modulare. La prima indica come è stato progettato il kernel, la seconda come è stato compilato.
Un kernel
monolitico implementa tutte le funzioni necessarie al suo interno. Il codice del kernel viene eseguito in modalità privilegiata (kernel). Linux è un kernel monolitico. I vantaggi del kernel monolitico sono:
- progettazione più facile
- prestazioni
Uno degli svantaggi è che modifiche a una funzione possono comportare la riscrittura di quelle parti di codice che la usano.
Un
microkernel implementa solo le funzioni essenziali. Le altre funzioni sono fornite da componenti esterne che comunicano fra di loro attraverso messaggi. Il microkernel viene eseguito in modalità kernel, mentre le componenti esterne sono eseguite in modalità utente. Hurd è un microkernel. I vantaggi del microkernel sono:
- la possibilità di aggiungere/rimuovere funzionalità senza dover modificare altri componenti: tutti i componenti interagiscono esclusivamente attraverso messaggi
- testing di una singola nuova componente più facile: ogni componente interagisce con un numero ristretto di altri servizi e fa uso di un numero ristretto di API
- portabilità: il codice che dipende dall'hardware è tutto nel microkernel, le componenti sono indipendenti dall'architettura
Un microkernel ha in genere uno svantaggio in termini di prestazioni: il sistema di scambio di messaggi e il numero di context switch (utente/kernel) generano un overhead.
Altro svantaggio è la difficoltà di progettazione (vedi di seguito).
Un kernel
statico è compilato senza il supporto ai moduli. Il vantaggio principale è in termini di sicurezza: senza il supporto ai moduli non è possibile per un attaccante installare rootkit basati appunto su moduli kernel.
Un kernel
modulare è compilato con il supporto ai moduli. I vantaggi sono la possibilità di avere supporto per una gran quantità di hardware; la possibilità di caricare/scaricare pezzi di kernel quando servono; la possibilità di estendere il kernel aggiungendo nuovi moduli senza dover ricompilare tutto il kernel.
Blizzard ha scritto:A parte gli scherzi la modularizzazione è in generale una tecnica molto buona. Consente una divisione del problema tale da rendere più agile progettazione, scrittura e soprattutto mantenimento del codice.
Quello che dici tu (l'onorabile pratica di separare il codice in file e sezioni logicamente indipendenti) è vero per quanto riguarda la gestione del codice sorgente: anche in Linux i sorgenti sono organizzati in modo che sia possibile gestirli più facilmente. Ma non è vero rispetto alla progettazione: nel caso del microkernel a quei vantaggi va aggiunto il lavoro necessario affinchè le varie componenti possano comunicare. Ed è un lavoro molto complicato perchè è difficile trovare bug in problemi di scambio asincrono di messaggi. Hurd ne è un esempio. Il suo sviluppo è stato rallentato dalla difficoltà di far funzionare insieme i vari pezzi, nonostante ognuno di essi fosse in grado di funzionare singolarmente. Uno dei motivi per cui Linux ha avuto subito successo è perchè ha funzionato da subito: non è stato necessario progettare un sistema di scambio di messaggi e lo sviluppo è stato concentrato sull'aggiunta di nuove caratteristiche e sulla risoluzione dei bug.