back

Risulta perciò essenziale che lo stato dei processi non cambi nel momento in cui lo scheduler sta operando la scelta: se un processo terminasse in quel momento sarebbe necessario riesaminare tutto l'insieme altrimenti si correrebbe il rischio di affidare al processore un task esaurito.

È chiaro che procedure come lo scheduling del processore necessitano di una posizione privilegiata rispetto al resto del codice; tali operazioni non vanno interrotte, perciò devono avere durata breve e una particolare robustezza. Impedire l'interruzione di un processo vuol dire che, qualora si blocchi a causa di un errore, esso non potrà rilasciare la CPU causando probabilmente il blocco dell'intero sistema. La tendenza è quindi quella di evitare questa possibilità limitandosi alle meccaniche essenziali al funzionamento del Sistema Operativo.

Infine, come accennato in precedenza, occorre assicurare sufficiente protezione ai meccanismi interni della macchina e del Sistema Operativo stesso.

Immaginate un programma utente in grado di avere accesso alle aree dedicate all'avvio della macchina, oppure semplicemente ad aree dedicate ad altri programmi; il risultato sarebbe disastroso: un programma viziato da errori potrebbe sovrascrivere sezioni di codice critiche compromettendo dati utili per il corretto funzionamento del calcolatore. Lo stesso discorso è valido per i dispositivi di I/O: si potrebbe scrivere un programma che modifichi il buffer di una stampante durante la sua attività; il risultato sarebbe sicuramente curioso, se non fosse che l'utente con la stampante ci lavora.

L'hardware moderno è in grado di rilevare gran parte di questi errori. Nelle moderne CPU è introdotto un flag di dimensioni pari ad uno o due bit definito "bit di modo" che garantisce una duplice modalità di funzionamento: distinguiamo così una modalità utente se il bit è settato a "1" e una modalità detta di sistema (detta anche modalità privilegiata, supervisore, o modalità kernel) se il bit è settato a "0". In questo modo se un segmento di codice residente nel processore cerca di accedere ad un'area di memoria riservata e il bit di modo è settato a "1", l'hardware impedisce l'esecuzione del comando sollevando un'eccezione di sicurezza (una "trap", gestita come un' interrupt) avvisando il Sistema Operativo che agirà di conseguenza.

In conclusione quando avremo bisogno di accedere a spazi di memoria al di fuori del nostro dominio (ad esempio la lettura di un file) dovremo fare richiesta a entità che possiedono maggiori privilegi tramite l'uso di interfacce apposite (approfondiremo nel prossimo articolo trattando le system call).

Occorre aggiungere una precisazione: quanto detto non ha nulla a che vedere con i meccanismi di protezione per gli utenti introdotti da Unix, anche se principi e realizzazioni sono molto simili. Le modalità utente e superutente (o root) alle quali si è abituati presentano obiettivi similari e adottano meccanismi analoghi, ma risiedono a livelli di astrazione ben più elevati; quando vi autenticate come root non impostate nessun bit del processore, inoltre non è possibile accedere direttamente a nessuno spazio di memoria (essa è infatti del tutto trasparente all'utente). È utile osservare come gli stessi meccanismi possono risiedere in più livelli nella realizzazione di un sistema complesso; questa è un'altra peculiarità del metodo di astrazione dovuta proprio al fatto che ogni modulo, pur dipendendo dall'interfaccia del livello sottostante, è completamente celato agli altri.

back