Il Kernel

()

Kernel

Il kernel fondamentalmente è il cuore vero e proprio del sistema operativo. Esso si occupa di gestire tutti i processi dell’I/O e delle periferiche di sistema. Il kernel mantiene il controllo della CPU e la gestione dei processi in esecuzione. All’avvio del sistema il kernel è il primo programma ad essere eseguito, successivamente viene inizializzato l’hardware e poi il programma di init. Il kernel linux può essere configurato e compilato liberamente scegliendo in maniera granulare le funzionalità e i moduli che si desiderano attivare sul sistema.

I sorgenti del kernel si possono scaricare dal sito www.kernel.org

Un kernel non è strettamente necessario per far funzionare un computer: i programmi possono essere infatti direttamente caricati ed eseguiti sulla macchina, a patto che i loro sviluppatori ritengano necessario fare a meno del supporto del sistema operativo: questa era la modalità di funzionamento tipica dei primi computer, che venivano resettati prima di eseguire un nuovo programma. In un secondo tempo, alcuni programmi accessori come i program loader e i debugger venivano lanciati da una ROM o fatti risiedere in memoria durante le transizioni del computer da un’applicazione all’altra: essi formarono la base di fatto per la creazione dei primi sistemi operativi.

Un’altra situazione in cui l’assenza di sistema operativo è auspicabile è l’esempio dei microcontrollori minimalisti. L’accesso diretto al kernel da parte di un utente/amministratore può avvenire in modalità user mode o kernel mode.

Classificazione

Confronto tra i diversi kernel
L’accesso diretto all’hardware può essere anche molto complesso, quindi i kernel usualmente implementano uno o più tipi di astrazione dall’hardware, il cosiddetto: Hardware abstraction layer. Queste astrazioni servono a “nascondere” la complessità e a fornire un’interfaccia pulita ed uniforme all’hardware sottostante, in modo da semplificare il lavoro degli sviluppatori. I kernel si possono classificare – in base al grado di astrazione dell’Hardware – in quattro categorie:

Kernel monolitici, che implementano direttamente una completa astrazione dell’hardware sottostante.
Microkernel, che forniscono un insieme ristretto e semplice di astrazione dell’hardware e usano software (chiamati device driver o server) per fornire maggiori funzionalità.
Kernel ibridi (o microkernel modificati), che si differenziano dai microkernel puri per l’implementazione di alcune funzioni aggiuntive al fine di incrementare le prestazioni.
Esokernel, che rimuovono tutte le limitazioni legate all’astrazione dell’hardware e si limitano a garantire l’accesso concorrente allo stesso, permettendo alle singole applicazioni di implementare autonomamente le tradizionali astrazioni del sistema operativo per mezzo di speciali librerie.

Kernel monolitici

Rappresentazione grafica di un kernel monolitico
L’approccio monolitico definisce un’interfaccia virtuale di alto livello sull’hardware, con un set di primitive o chiamate di sistema per implementare servizi di sistema operativo come gestione dei processi, multitasking e gestione della memoria, in diversi moduli che girano in modalità supervisore.

Anche se ogni modulo che serve queste operazioni è separato dal resto, l’integrazione del codice è molto stretta e difficile da fare in maniera corretta e, siccome tutti i moduli operano nello stesso spazio, un bug in uno di essi può bloccare l’intero sistema. Tuttavia, quando l’implementazione è completa e sicura, la stretta integrazione interna dei componenti rende un buon kernel monolitico estremamente efficiente.

Il più considerevole svantaggio dei kernel monolitici è tuttavia che non è possibile aggiungere un nuovo dispositivo hardware senza aggiungere il relativo modulo al kernel, operazione che richiede la ricompilazione del kernel. In alternativa è possibile compilare un kernel con tutti i moduli di supporto all’hardware, al costo di aumentarne molto la dimensione. Tuttavia i kernel monolitici più moderni come il kernel Linux e FreeBSD possono caricare moduli in fase di esecuzione, se sono previsti in fase di configurazione (la fase di configurazione è la fase che precede quella di compilazione, durante la quale si può scegliere quali feature o driver debbano far parte del nuovo kernel), permettendo così l’estensione del kernel quando richiesto, mantenendo al contempo le dimensioni del codice nello spazio del kernel al minimo indispensabile.

Esempi di kernel monolitici:

I tradizionali kernel UNIX, quali ad esempio i kernel BSD.
Il kernel Linux.
Kernel di ricerca come AGNIX.

Microkernel

L’approccio microkernel consiste nel definire un kernel principale che fornisce esclusivamente un set di primitive o chiamate di sistema per implementare servizi minimali del sistema operativo quali gestione dei thread, spazi di indirizzamento o comunicazione interprocesso. Sopra tale kernel minimale (da cui il prefisso “micro”) vengono innestati dei server, ovvero programmi separati dal kernel che comunicano con questo tramite le suddette chiamate di sistema per implementare le varie funzionalità del sistema.

L’obiettivo principale è la separazione delle implementazioni dei servizi di base dalle strutture operative del sistema. Per esempio, il processo di blocco (locking) dell’input/output può essere implementato come modulo server a livello utente. Questi moduli a livello utente, usati per fornire servizi di alto livello al sistema, sono modulari e semplificano la struttura e la progettazione del kernel. Un servizio server che smette di funzionare non provoca il blocco dell’intero sistema, e può essere riavviato indipendentemente dal resto.

Vi sono alcuni tipi di microkernel che non possono essere definiti esattamente come tali, perché non implementano alcune funzioni sotto forma di server, sebbene siano caratterizzati da altre prerogative che definiscono i microkernel. Il più noto di essi è Exec, abbreviazione di Executive Multitasking (e il suo diretto successore ExecSG) che è il kernel di AmigaOS.

Esempi di microkernel e Sistemi operativi basati su microkernel:

AIX
Amoeba
BeOS e il suo successore Haiku
Chorus microkernel
EROS
FreeRTOS

Kernel monolitici e microkernel: confronto


I kernel monolitici sono spesso preferiti ai microkernel a causa del minor livello di complessità nel controllo dei codici di controllo in uno spazio di indirizzamento. Per esempio XNU, il kernel di macOS, è basato su un kernel Mach 3.0 e componenti BSD nello stesso spazio di indirizzamento in modo da abbattere i tempi di latenza tipici dei microkernel. XNU risulta così un kernel dalle notevoli prestazioni poiché basato in parte su una soluzione ibrida e non può in ogni caso essere considerato un microkernel. Nella documentazione ufficiale di Apple si fa chiaro riferimento a XNU come Kernel Monolitico Modulare.

A partire dai primi anni novanta i kernel monolitici sono considerati obsoleti. Il kernel Linux come kernel monolitico anziché come microkernel è stato uno degli argomenti della famosa guerra di religione fra Linus Torvalds (il creatore di Linux) e Andrew Tanenbaum (celebre docente di sistemi operativi, autore di Minix) – in rete sono disponibili maggiori dettagli.

In realtà vi sono ragioni da entrambe le parti.

I kernel monolitici tendono ad essere più semplici da progettare correttamente, e possono quindi evolversi più rapidamente di un sistema basato su microkernel. Ci sono storie di successi in entrambi gli schieramenti. I microkernel sono spesso usati in sistemi embedded in applicazioni mission critical di automazione robotica o di medicina, a causa del fatto che i componenti del sistema risiedono in aree di memoria separate, private e protette. Ciò non è possibile con i kernel monolitici, nemmeno con i moderni moduli caricabili.

A parte il kernel Mach, che è il più noto microkernel di uso generico, molti altri microkernel sono stati sviluppati con scopi specifici. Kernel L3 in particolare è stato creato per dimostrare che i microkernel non sono necessariamente lenti. La famiglia di microkernel L4, successori di L3, dispongono di una implementazione chiamata Fiasco in grado di eseguire il kernel Linux accanto agli altri processi di L4 in spazi di indirizzamento separati.

QNX è un sistema operativo presente sulle scene dai primi anni ottanta e dispone di una implementazione a microkernel davvero minimalista. Questo sistema ha avuto molto più successo di Mach nel raggiungere gli obiettivi del paradigma a microkernel. È usato in situazioni in cui al software non è concesso di sbagliare, ad esempio nei bracci robotici dello space shuttle o in macchine che lavorano il vetro dove un errore anche piccolo può costare centinaia di migliaia di Euro.

Kernel ibridi

Rappresentazione grafica di un kernel ibrido

I kernel ibridi sono essenzialmente dei microkernel che hanno del codice “non essenziale” al livello di spazio del kernel in modo che questo codice possa girare più rapidamente che se fosse implementato ad alto livello. Questo fu un compromesso adottato da molti sviluppatori di sistemi operativi prima che fosse dimostrato che i microkernel puri potevano invece avere performance elevate. Molti sistemi operativi moderni rientrano in questa categoria: Microsoft Windows è l’esempio più noto. Anche XNU, il kernel di Mac OS X, è di fatto un microkernel modificato, per via dell’inclusione di codice BSD in un kernel basato su Mach. DragonFly BSD è stato il primo sistema BSD non basato su Mach ad adottare l’architettura a kernel ibrido.

Non si confonda il termine “kernel ibrido” con i kernel monolitici che possono caricare moduli dopo il boot, poiché “ibrido” implica che il kernel in questione condivide concetti architetturali e meccanismi tipici sia dei kernel monolitici che dei microkernel, specialmente il passaggio di messaggi e la migrazione di porzioni di codice “non essenziale” a più alto livello, mantenendo a livello kernel solo il codice necessario per ragioni di prestazioni.

Esempi di kernel ibridi:

Microsoft Windows NT che è usato su tutti i sistemi basati su NT
XNU kernel del macOS
DragonFly BSD
Quark, il kernel di MorphOS
Haiku

Esokernel

 

Nessuno meglio di uno sviluppatore sa come rendere efficiente l’uso dell’hardware disponibile, quindi l’obiettivo è dargli la possibilità di prendere le decisioni. Gli esokernel sono estremamente piccoli e compatti, poiché le loro funzionalità sono volutamente limitate alla protezione e al multiplexing delle risorse.

/ 5
Grazie per aver votato!

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?