1️⃣ Capitolo 1 - Introduzione Contenuti: Il ruolo del sistema operativo nell’insieme del sistema di elaborazione Definizione di SO Organizzazione di un sistema elaborativo Interrupt Struttura della memoria Architettura degli elaboratori Attività del sistema operativo Protezione della memoria Il ruolo del sistema operativo nell’insieme del sistema di elaborazione Un sistema di elaborazione si può suddividere in: ● ● ● Hardware Software: Sistema operativo e programmi applicativi Un utente Definizione di SO Il SO è un software che agisce da intermediario tra un utente di un computer e l'hardware, in modo tale da utilizzarlo in modo efficiente, dato che l’utente non può (per varie ragioni di complessità e sicurezza) avere il controllo diretto e completo dell’hardware. E’ un allocatore di risorse e dunque un programma di controllo. Può essere considerato come un software in continua esecuzione dall'accensione allo spegnimento: funziona sempre, per questo viene generalmente chiamato kernel (nucleo). Oltre al kernel ci sono altri tipi di programmi che invece non sono sempre in esecuzione: i programmi di sistema, che sono associati al SO, ma non fanno necessariamente parte del kernel e i programmi applicativi, che sono tutti quei programmi non correlati al funzionamento di sistema (ad es. software di terze parti). I SO mobili hanno anche un middleware, una collezione di ambienti software che fornisce servizi aggiuntivi per chi sviluppa applicazioni. Organizzazione di un sistema elaborativo Un moderno calcolatore general-purpose è composto da una o più unità di elaborazione (CPU) e da un certo numero di controllori di dispositivi connessi attraverso un canale di comunicazione comune (bus) che permette l’accesso alla memoria condivisa dal sistema. I sistemi operativi possiedono in genere per ogni controllore di dispositivo un driver del dispositivo che gestisce le specificità del controllore e funge da interfaccia uniforme con il resto del sistema. La CPU e i controllori, essendo diversi, possono eseguire operazioni in parallelo, competendo per l’accesso in memoria. Come si decide l’ordine in cui le varie CPU devono accedere in memoria e svolgere operazioni? Attraverso gli Interrupt. Interrupt Nel momento in cui devono comunicare, CPU e controllori, hanno la necessità di prendere il controllo del bus di sistema; lo fanno con gli interrupt Il controllo alla routine di gestione degli interrupt avviene tramite il vettore delle interruzioni, il quale contiene tutti gli indirizzi delle routine di servizio per gestire diversi tipi di interruzioni. È necessario salvare l’indirizzo dell’istruzione interrotta per poter continuare dal punto in cui si è lasciato. Un interrupt generato da un software a causa di un errore o di una richiesta utente si dice trap. Quando la linea di interruzione è attiva, la CPU arresta l’esecuzione delle istruzioni esegue il software di gestione delle interruzioni, che si occuperà del trasferimento del controllo all’appropriata procedura di servizio, non prima però di aver memorizzato il contenuto dei registri della CPU per poter riprendere l’esecuzione del programma precedente alla fine dell’interrupt. La maggior parte delle CPU ha due linee di richiesta di interruzione (interrupt-request line): ● ● interrupt non mascherabile → linea riservata a eventi come errori irreversibili di memoria. Questo interrupt è causato dall’hardware. interrupt mascherabile → usata dai controllori dei dispositivi per richiedere un servizio (tipo I/O) Ad esempio... immaginiamo un calcolatore da una CPU single core, in esso è in esecuzione un programma. Improvvisamente viene rilevato un input da una periferica. La periferica invia un interrupt, l’interrupt passa dal bus di controllo alla CPU, essa legge l’indirizzo di memoria della periferica e agisce riferendosi a routine tabellari contenute nei più bassi indirizzi di memoria del kernel. Una volta terminata la routine viene continuata l’esecuzione del programma dove era stato interrotto. Concatenamento delle interruzioni (interrupt chaining) → ogni elemento nel vettore delle interruzioni punta alla testa di un elenco di gestori. Struttura della memoria Vi sono diversi tipi di dispositivi di storage, ognuno di dimensione e velocità diversa. La memoria principale o centrale (random access memory, RAM) è la più veloce del calcolatore. Essa è il solo dispositivo di immagazzinamento capiente a cui la CPU può accedere direttamente. La memoria secondaria è un’estensione della memoria principale che fornisce grande capacità di immagazzinamento non volatile. Esse vengono anche dette memorie di massa. (es. HDD o SSD) Il sistema di immagazzinamento è organizzato secondo una gerarchia: velocità, costo e volatilià. Questa gerarchia è fondamentale per il sistema di caching. Esso si basa sul copiare informazioni in sistemi di immagazzinamento più veloce. La memoria principale può essere vista come cache per la memoria secondaria. Architettura degli elaboratori Sistemi monoprocessore → Diversi anni fa la maggior parte dei sistemi utilizzava un solo processore contenente un’unica CPU con un unico nucleo di elaborazione (o unità di calcolo, o core). Oggi sono molto più comuni i Sistemi multiprocessore → Sistemi con più CPU, oppure ultimamente questa definizione include anche i sistemi multicore, in cui più unità di calcolo (core) risiedono tutte in un singolo chip. Aggiungere nuove CPU a un multiprocessore ne aumenta ovviamente la potenza di calcolo, ma ne peggiora le prestazioni, perchè ricordiamo che una sola CPU può accedere in memoria attraverso il bus in un determinato istante. Sarà necessario fornire dunque a ciascuna CPU la propria memoria locale accessibile per mezzo di un bus locale piccolo e veloce → sistemi NUMA (non uniform memory access), possono scalare in modo più efficace l’aggiunta di più processori. Un altro tipo di sistemi multiprocessore sono i Cluster di elaboratori, basati sull’uso congiunto di più CPU, ma sono composti da due o più calcolatori completi, detti nodi, collegati fra loro (sistemi distribuiti). Attività del sistema operativo 1. 2. 3. 4. 5. Programma di avviamento Il kernel iniza a offrire servizi al sistema e agli utenti. Interrupt ed eccezioni (traps o exceptions) System call Multiprogrammazione → Multitasking → Più istanze contemporaneamente In un sistema con multiprogrammazione la memoria sarà suddivisa in parti e il sistema operativo si posizionerà nella parte diù bassa della memoria, mentre i processi si posizioneranno uno dopo l’altro andando dalla parte più alta alla più bassa della memoria. Con questa suddivisione migliorano i tempi di esecuzione se si usa il multitasking, però si potrebbe incappare in problemi se in un processo volesse accedere ad un indirizzo di memoria utilizzato da un altro processo: questo ovviamente il SO non può permetterlo, infatti prevede dei meccanismi di protezione della memoria. Protezione della memoria La CPU prevede una duplice modalità di funzionamento (dual mode): modalità utente e modalità di sistema (detta anche modalità kernel, modalità supervisore, modalità monitor o modalità privilegiata). Per indicare quale modalità sia attiva, l’architettura della CPU deve essere dotata di un bit, detto bit di modalità: kernel (0) o user (1). Nella modalità Kernel la CPU può eseguire qualunque istruzione, anche quelle privilegiate. Nella modalità User il set di istruzioni eseguibili è un sottoinsieme. Se in questa modalità si prova a eseguire una istruzione non consentita, questa non viene eseguita e si genera una exception. Le istruzioni consentite sono ad esempio quelle di calcolo o di accesso a indirizzi di memoria consentiti. Se l’utente deve eseguire una istruzione consentita solo in modalità kernel, viene usata una system call, con la quale richiede al SO di eseguire operazioni in modalità kernel. L’uscita della chiamata riporta in modalità utente. Questa parte poi finisce con una breve descrizione di strutture dati utili al SO: liste, alberi, hashmaps.