# Sistemi operativi/Funzioni base

Sistemi operativi
Copertina Tutti i moduli · Sviluppo
    Copertina
* Introduzione
* Breve storia
* Le funzioni di base
** Funzionalità dei sistemi operativi
** Evoluzione dei sistemi operativi
Modifica il sommario

## Indice delle sottopagine

* Funzionalità dei sistemi operativi
* Evoluzione dei sistemi operativi

## Gestione del processore

Il processore, o unità centrale di elaborazione (o CPU, dall'inglese Central Processing Unit), è una risorsa hardware la cui gestione presenta due problemi.
* In ogni momento, più task possono essere pronti per l'esecuzione, ma solo uno può essere eseguito da un processore; pertanto, occorre decidere quale task eseguire, facendo attendere gli altri.
* Quando è in esecuzione il sistema operativo, il processore deve poter accedere a tutte le risorse dell'elaboratore; ma, per assicurare l'integrità del sistema, quando è in esecuzione un programma applicativo, il processore deve poter eseguire solo le operazioni consentite dal sistema operativo. Pertanto, occorre fare in modo che il processore funzioni in due modalità: modalità supervisore o modalità utente.

## Gestione della memoria principale

La memoria principale, o spesso chiamata semplicemente "memoria", è l'insieme dei dispositivi di memorizzazione esterni al processore ma indirizzabili esplicitamente da istruzioni in linguaggio macchina. I problemi che deve risolvere il sistema operativo relativamente alla memoria sono i seguenti:
* Suddividere equamente la memoria principale tra i processi in esecuzione.
* Impedire che ogni processo acceda (cioè legga o scriva) alle parti di memoria principale assegnate ad altri processi o al sistema operativo stesso.
* Per sfruttare meglio la memoria principale disponibile, spostare trasparentemente su memoria secondaria (normalmente un disco fisso) il contenuto di porzioni inutilizzate di memoria principale, e riportare altrettanto trasparentemente in memoria principale dalla memoria secondaria le informazioni indirizzate dai processi.
Per agevolare la risoluzione di questi problemi, i processori sono stati dotati di una componente hardware chiamata "unità di gestione della memoria" (o MMU, dall'inglese Memory Management Unit). L'uso della MMU consente di avere due concetti di memoria: la "memoria reale" e la "memoria virtuale".
Vediamo però prima i tentativi di gestire la memoria in sistemi multiprogrammati in assenza di MMU, e quindi con la sola memoria reale. In realtà per risolvere il problema della protezione della memoria è comunque necessario un supporto hardware, costituito dal registro base e dalla soglia di indirizzamento. Quando viene creato un processo, si cerca nella memoria un intervallo di indirizzi liberi abbastanza grande da contenere il codice del programma e lo spazio per i dati. Ogni volta che il processo esegue un'istruzione di accesso alla memoria, un circuito somma l'indirizzo al contenuto del registro base, e questo fornisce l'indirizzo reale della cella indirizzata. Contemporaneamente, un altro circuito verifica che l'indirizzo emesso dal processore abbia un valore inferiore alla soglia dello spazio di indirizzamento del processo. In caso negativo, viene sollevata un'eccezione hardware e il controllo torna al sistema operativo.
Questi due registri non vengono usati nell'eseguire il codice del sistema operativo stesso, e vengono reimpostati ogni volta che il sistema operativo passa il controllo a un altro processo.
Tale architettura assume che ogni processo abbia codice e dati di lunghezza definita in fase di compilazione. Infatti, i primi linguaggi di programmazione ad alto livello, FORTRAN e COBOL, ammettevano solamente dati statici.
Un altro problema con questa architettura era quello della gestione della memoria dinamica. Infatti, se si creano due processi e poi il primo termina, rimane uno spazio libero prima dello spazio occupato dal secondo processo. Quando si crea un terzo processo, tale spazio potrebbe essere troppo piccolo, per cui è necessario cercare uno spazio sufficientemente grande. Ci sono vari algoritmi di allocazione di segmenti di memoria, ma tutti soffrono di problemi di prestazioni e di frammentazione della memoria. Si ha la memoria frammentata quando si vorrebbe allocare un nuovo segmento (per lanciare un nuovo processo), ma non c'è nessun intervallo libero abbastanza grande, e tuttavia la somma degli intervalli liberi sarebbe abbastanza grande. Alcuni algoritmi di allocazione della memoria, eseguono saltuariamente un compattamento della memoria per deframmentarla. Il compattamento consiste nel traslare il contenuto di segmenti di memoria in modo da concentrare alla fine tutto lo spazio libero.