Sistemi Operativi
1) Definizione di Sistema Operativo
Un Sistema Operativo (SO) è un software, quasi sempre molto complesso, che virtualizza una macchina reale
( ) e le sue risorse, gestendone e coordinandone l'uso da parte delle applicazioni. Il SO crea un
elaboratore elettronico
ambiente di lavoro nel quale le applicazioni vengono eseguite ed assegna (alloca) loro le risorse della macchina reale
in base alle richieste e alla disponibilità. Il SO è schematizzabile come costituito da un nucleo detto Kernel (insieme di
tutto ciò che può essere eseguito sulla macchina in stato supervisore, normalmente interdetto all'utilizzo da parte
dell'utente, e responsabile della creazione dell'ambiente di lavoro) e da un interprete dei comandi (espressi in apposito
linguaggio di comando simbolico detto JCL, Job Control Language) detto Shell ( ).
si pensi al prompt dell'MS-DOS
Per i primi sistemi di elaborazione l'unico tipo di programmazione previsto era il Linguaggio Macchina (il
programmatore si occupava di tutto: algoritmo, controllo periferiche, settaggio dei bit di stato, flag del processore, e così
via). I primi SO erano semplici insiemi di Drivers, programmi che fungono da interfaccia tra l'unità centrale e i dispositivi
periferici. Successivamente fu ideato il primo programma Caricatore, il cui compito era caricare programmi e dati, da
schede perforate o nastri magnetici, nella memoria dell'elaboratore (un programma in linguaggio simbolico poteva
richiedere per la sua esecuzione più operazioni di caricamento... prima l'opportuno compilatore che generava il testo in
Assembly, poi l'assemblatore che produceva il codice oggetto in formato binario e che veniva infine caricato in memoria
per l'esecuzione). La necessità di limitare progressivamente l'uso delle schede perforate diede impulso alla creazione di
macchine dedicate al trasferimento dei “contenuti” da schede perforate a nastri magnetici e, poiché se ne occupava un
operatore umano, fu presto evidente che il processo di trasferimento era tanto più efficace se applicato ad un numero
considerevole di schede per volta: nacque il concetto di Batch o Lotto. Si capì che la CPU di una macchina poteva
essere sfruttata per eseguire alternativamente diversi Processi attivi purchè questa Multiprogrammazione (e i problemi
che comportava) fosse opportunamente gestita. Il trasferimento di contenuti dalle schede perforate venne presto
indirizzato alle unità a disco (che hanno il vantaggio di essere ad accesso casuale, anziché sequenziale come i nastri
magnetici) e la procedura adottata prese il nome di Spooling (Spool è acronimo di Simultaneous Peripheral Operations
On-Line e si riferisce allo spostamento di immagini di lavoro, da svolgere o da inviare a dispositivi periferici, attraverso la
temporanea memorizzazione in un buffer, in memoria o più frequentemente su disco rigido): in pratica i contenuti delle
schede perforate e dei nastri venivano massicciamente trasferiti a lotti su unità a disco, indicizzati in una tabella, in modo
da poter essere poi all'occorrenza caricati in memoria su richiesta di utenti e programmi in tempi molto rapidi grazie
all'accesso casuale dei dischi; naturalmente lo Spooling valeva non solo in Input ma anche in Output, consentendo di
usare il disco come buffer temporaneo per l'invio differito nel tempo di dati a dispositivi periferici (la più comune
applicazione dello Spool è proprio lo spooling di stampa, un sistema che attraverso una coda FIFO è in grado di
somministrare ad una stampante una grande quantità di pagine, secondo i tempi che le sono congeniali, agendo in
background, in modo che, durante la stampa, i tempi morti della CPU siano sfruttati dall'utente per eseguire processi a
più alta priorità); con questo meccanismo era possibile caricare su disco un grosso pool di jobs, trasferirne di volta in
volta una parte in memoria ed eseguirli uno per uno fino ad esaurimento, attingendo quando necessario direttamente dal
disco i dati utili, con la possibilità di swappare un processo (in attesa di un evento o sospeso) su disco a vantaggio di un
altro, così da tenere sempre in attività la CPU: si parla di Multiprogrammazione di tipo Batch o Batch
Multiprogrammato. Diverso approccio alla gestione di job multipli è la Multiprogrammazione di tipo Time Sharing, nel
quale la potenza di calcolo della CPU viene distribuita ciclicamente, per piccole frazioni di tempo, ad N utenti attraverso N
terminali (ciascun utente ha l'impressione di avere le risorse del sistema tutte per sé, il singolo processo del singolo
utente diventa Running per un breve intervallo di tempo e poi resta Ready nel tempo in cui operano gli altri utenti). Nel
Batch Multiprogrammato con Partizione Time Sharing i jobs degli utenti (considerati prioritari perchè
conversazionali, ovvero richiedono interazione con l'utente e devono sottostare a stringenti tempi di risposta) sono
gestiti tramite il Time Sharing (Scheduling a Breve Termine), e solo in assenza di jobs conversazionali vengono avviati i
jobs di background in modalità Batch (Scheduling a Lungo Termine); una possibile variante del modello consiste nel non
fare sì che la CPU sia monopolizzata totalmente dai processi utente e prevede che una piccola frazione di tempo utile
ciclico della CPU sia comunque concessa al carico di lavoro Batch. I sistemi che forniscono risposte in tempi brevi sono
classificati in Hard Real Time o Real Time (non Hard) rispettivamente se tempi di risposta estremamente rapidi sono
decisivi per la correttezza del sistema oppure se tempi “medi” di risposta sono comunque accettabili. Con l'avvento dei
MicroProcessori i computer divennero personal e i SO offrirono un ambiente di lavoro più user friendly: il concetto di
multiprogrammazione era inizialmente assente nei primi SO (si riteneva fosse legato necessariamente ad una pluralità di
utenti e comunque richiedeva potenze di calcolo proibitive per l'epoca) ma oggi è supportato da tutti i SO moderni. Negli
ultimi 20 anni, infine, si è dato impulso all'aggregazione di PC per costituire Sistemi Distribuiti, comunemente detti Reti,
geograficamente dislocate.
Dal punto di vista dell'utente, i SO possono essere classificati in sistemi dedicati, sistemi batch (a lotti), sistemi
interattivi o conversazionali, sistemi in tempo reale e sistemi transazionali. Un sistema dedicato fornisce un interprete
dei comandi, la possibilità di lanciare programmi e di gestire file, il tutto dedicato ad un unico utente, caratterizzandosi per
il basso sfruttamento della CPU durante le interazioni con l'utente e l'assenza di una virtualizzazione delle risorse: viene
denominato Supervisore o DOS, per evidenziare rispettivamente il controllo esercitato sull'esecuzione dei lavori o il
supporto alla gestione del disco. Un sistema batch (a lotti) gestisce singolarmente l'avanzamento di lavori raggruppati in
lotti memorizzati su disco, privilegiando lo sfruttamento della CPU ( ) a prezzo dell'assenza di interazione con
vantaggio
l'utente, che deve fornire il suo lavoro in via preliminare e che può attenderne il completamento anche per ore o giorni
( ): le unità di I/O sono virtualizzate e ciò rende le operazioni su di esse più veloci ( ). Un sistema
svantaggio vantaggio
interattivo o conversazionale assegna, agli utenti che interagiscono attraverso terminali, le risorse per “quanti di tempo”,
riducendo il tempo di risposta e dando loro la sensazione di operare su un sistema dedicato ( ): questo
vantaggio
meccanismo produce necessariamente un overhead ( ). Un sistema transazionale consente ad utenti ed
svantaggio
1
applicazioni di eseguire sequenze di operazioni elementari ( ) in forma di transazioni,
tipicamente manipolazione di archivi
rispettando le proprietà di atomicità, consistenza, isolamento e persistenza. Un sistema in tempo reale esegue programmi
che, interagendo con l'ambiente esterno, garantiscono a dati di ingresso risposte in tempo utile rispetto alle constanti di
tempo proprie dell'ambiente esterno stesso: la correttezza del sistema dipende in modo critico dalla velocità di
esecuzione. Si noti che in campo commerciale “real time” è sinonimo di conversazionale o transazionale, tuttavia i due tipi
di sistemi non coincidono.
In base all'organizzazione interna possono essere inoltre classificati in sistemi monoprogrammati, sistemi
multiprogrammati, sistemi time-sharing (a partizione di tempo) e sistemi ad uso speciale. In base infine all'architettura
del sistema di elaborazione su cui sono calati, i SO possono essere classificati in SO per sistemi di calcolo monolitici,
per sistemi di calcolo distribuiti e per sistemi di calcolo paralleli.
Struttura a livelli del SO
Il SO offre all'utente dei servizi e questi ne ha visibilità attraverso i comandi che consentono di richiamarli: i comandi
espliciti sono gestiti dalla Shell, i comandi impliciti sono invece generati da un compilatore/assemblatore. Le principali
funzioni offerte dal SO e viste dall'utente possono essere raggruppate in funzioni per la gestione dei lavori ( qualificarsi nei
), supporti per la
confronti del sistema, richiedere l'allocazione di risorse, richiedere l'esecuzione di una o una successione di azioni
programmazione ( programmi per il trattamento testi, per la gestione delle librerie, per il supporto al testing e al debugging del codice dei
), meccanismi di I/O (
programmi mascheramento delle modalità con cui le operazioni di I/O vengono eseguite, mascheramento dei conflitti
) e funzioni di gestione archivi (
nell'uso di periferiche condivise, gestione dei malfunzionamenti accesso tramite riferimenti logici, garanzia di
).
sicurezza negli accessi e dell'integrità dei dati
Una tipica schematizzazione del SO a livelli consente di riconoscere 8 livelli, via via più bassi quanto più ci si
avvicina alla macchina reale, via via più alti quanto più le macchine virtuali sono astratte e mettono a disposizione
funzionalità evolute:
1) Programma Utente
2) Shell Interprete dei comandi
3) Utility Supporto allo sviluppo (editor, testing, debugging) dei programmi, fogli elettronici e altre utilità
4) File System Gestione (con controllo degli accessi) di blocchi di informazioni logicamente strutturati registrati su disco, ovvero i File
5) Periferiche Virtuali Simulazione di periferiche virtuali (implementazione primitive I/O e gestione malfunzionamenti)
6) Memoria Virtuale Allocazione memoria ai programmi che la richiedono usando se necessario la memoria secondaria (gestione
corrispondenza indirizzi fisici / logici, caricamente / scaricamento / swapping, protezione dalle violazioni)
7) Nucleo Allocazione della CPU ai processi (Sheduling), primitive di gestione degli eventi asincroni e di sincronizzazione (richiamate
tramite SVC)
8) Hardware Macchina Base o Reale
Ogni macchina virtuale di livello superiore utilizza i servizi offerti dalla macchina virtuale (eventualmente reale) di livello
inferiore, che espone una apposita interfaccia; i livelli (2) e (3) sono da considerarsi paritari, ovvero non necessariamente
dipendenti l'uno dall'altro; i livelli da (1) a (3) formano un macrolivello costituito da processi dedicati, mentre i restanti dal
(4) al (7) costituiscono il Kernel del SO in senso esteso; al livello (8) c'è un'unica CPU, Memoria, Disco e un insieme
discreto di periferiche; il livello (7) costituisce una macchina virtuale rispetto alla quale tutti i processi vedono ciascuno
una propria CPU; il livello (6) costituisce una macchina virtuale rispetto alla quale tutti i processi vedono ciascuno una
propria CPU e una propria memoria; il livello (5) costituisce una macchina virtuale rispetto alla quale tutti i processi
vedono ciascuno una propria CPU, una propria memoria e un insieme non condiviso di periferiche... ogni livello insomma
astrae sempre di più la macchina reale facendola apparire progressivamente, in ogni suo componente, dedicata al
singolo processo attivo.
Interrupt e Supervisor Call
Una Interrupt o Interruzione è il più facile meccanismo ( comunemente adottato da tutti i sistemi programmabili e da tutti i modelli
) che consente di interrompere e modificare il normale flusso di esecuzione delle operazioni da parte della
di CPU sul mercato
CPU al verificarsi di un evento. Una Interrupt Hardware è generata da dispositivi esterni alla CPU e serve a comunicare
il verificarsi di un evento generalmente asincrono ( un dispositivo I/O informa la CPU che è disponibile a fornire o ricevere dati, il clock
). Un Interrupt Software o Trap è generata invece da istruzioni assembly (
segnala la scadenza di un quanto di tempo, ... INT x,
) assimilabili a chiamate a sottoprogrammi con le quali un processo richiede una System Call o Supervisor Call
SYSCALL
( ) oppure segnala una exception (
esecuzione di una primitiva del SO, accesso diretto a risorse controllate dal SO, ... tentata divisione per zero,
). Le interruzioni possono inoltre essere abilitate o
la violazione della memoria, disconnesione dalla rete, errore di trasferimento dati, ...
disabilitate con apposite istruzioni assembly ( ).
STI Set Interrupt e CLI Clear Interrupt
Una Interrupt Request o IRQ o Richiesta di Interruzione ( ) è il
usata spesso erroneamente come sinnimo di Interrupt
meccanismo con cui lo specifico evento viene segnalato alla CPU, inviando opportuni segnali ai pin fisici di collegamento
della CPU stessa: a seconda dello stato in cui si trova la CPU, la IRQ può essere servita o accantonata per essere
eseguita in un secondo tempo, e questo perchè gli IRQ sono organizzati in gerarchie di priorità e una IRQ di livello più
basso può essere scavalcata - e l'interruzione da essa generata a sua volta interrotta - da una IRQ di livello alto, a meno
che non sia associata ad una Non Maskable Interrupt o NMI, che non può essere accantonata e va eseguita
immediatamente. Diversi tipi di CPU generalmente standardizzano i loro IRQ in modo che ad un certo IRQ corrisponda
sempre lo stesso tipo di evento: tasto premuto sulla tastiera, comunicazione in arrivo su porta seriale, e così via.
La gestione degli Interrupt prevede che, quando la CPU riceve una IRQ, la prima esigenza sia determinare quale
dispositivo l'ha generata e questo può essere fatto con due diversi sistemi, la scansione degli interrupt (o polling) e la
vettorizzazione degli interrupt. Nel prima caso si effettua l'interrogazione di ciascuno dei dispositivi collegati per una
eventuale conferma della richiesta di interruzione inviata. Nel secondo caso si usa invece un opportuno circuito integrato
detto Programmable Interrupt Controller o PIC, che riceve in ingresso un certo numero di linee di IRQ usate appunto
2
dai dispositivi per richiedere un'interruzione: quando il PIC riceve una IRQ, si occupa di segnalare alla CPU tale richiesta
di interruzione e - se la CPU conferma la richiesta ( ) – deposita nel bus
potrebbe non confermarla se le interruzioni sono disabilitate
dati l'indice di un Vettore di Interrupt o Vettore di Interruzione, cioè l'indice che consenta di indirizzare una vera e
propria tabella chiamata anche Interrupt Vector Table o Interrupt Descriptor Table, in cui siano memorizzati gli indirizzi
delle diverse Interrupt Service Routine o ISR o Interrupt Handler associata alle interruzioni, ovvero funzioni di tipo
callback ( ) che contengono le operazioni la cui
una funzione specializzata passata come parametro a un'altra funzione che invece è generica
esecuzione è prevista nel caso di ogni specifica interruzione. In sintesi, quando la CPU riceve una IRQ, recepisce un
indice di interruzione, lo usa per indirizzare la tabella o vettore delle interruzioni e trova un puntatore ad una specifica
procedura, predisposta dal programmatore o più spesso dal SO; affinchè il meccanismo di interruzione funzioni
correttamente, è necessario che l'esecuzione della ISR sia trasparente al processo interrotto e qundi serve che la CPU,
prima di mandare in esecuzione la ISR, faccia un salvataggio del contesto del processo in corso in un apposito stack e
che poi, a seguito del ritorno dall'interruzione tramite l'istruzione RTE, lo ripristini com'era; poichè l'interruzione va gestita
rapidamente non va perso tempo a salvare tutto il contesto del processo ( ) ma solo quello che
ad esempio le sue variabili globali
effettivamente verrà modificato dall'ISR, e siccome la CPU non conosce in anticipo che cosa l'ISR modificherà, quando si
verifica una interruzione essa provvede ad affettuare il salvataggio almeno del Registro di Stato del processo o
Program Status Word o PSW ( ) e
un'area di memoria o un registro che contiene informazioni sullo stato dei programmi in esecuzione sul SO
del Program Counter o PC.
Il compito del SO, relativamente al meccanismo di gestione degli interrupt, consiste essenzialmente nel predisporre
gli opportuni sottoprogrammi di gestione degli interrupt per tutte le periferiche, così come i sottoprogrammi di gestione
delle eccezioni, inserendo i loro indirizzi nella tabella degli interrupt.
Si definiscono istruzioni privilegiate di un SO quelle istruzioni riservate all'uso esclusivo da parte del SO (allo
scopo di rendere impossibili le interferenze reciproche di processi concorrenti) concernenti essenzialmente la
manipolazione del sistema delle interruzioni, la commutazione della CPU tra processi, le operazioni di I/O, l'accesso ai
registri utlizzati dall'hardware per la protezione della memoria e l'arresto della CPU (halt). La maggioranza degli
elaboratori opera in due modalità distinte, il Supervisor Mode ( ) e lo User
modo privilegiato, system mode, monitor mode
Mode ( ) e le istruzioni privilegiate sono permesse solo nel Supervisor Mode; il passaggio
modo utente, modo non privilegiato
dal modo utente al modo privilegiato ha luogo automaticamente al verificarsi di una delle 4 seguenti condizioni: un
processo utente effettua un richiamo del SO (Supervisor Call o SVC o System Call) allo scopo di eseguire una funzione
che richieda l'esecu
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Affidabilità di Sistemi Software Complessi
-
Riassunto processo e sviluppo del software
-
Appunti di Ingegneria del Software
-
Esercizi/appunti di ingegneria del software