Appunti di Fabio Missagia parte 1.pdf
Document Details
Uploaded by ClearerClover587
Pontificia Università Gregoriana
Tags
Full Transcript
2. Componenti di un sistema operativo Interprete dei comandi Elemento principale di interfaccia tra SO e utente è l'interprete dei comandi (shell), che ha il compito di prendere i comandi specificati dall’utente e di eseguirli. Esso può fornire diversi tipi di interfaccia utente, come CLI, GUI, o b...
2. Componenti di un sistema operativo Interprete dei comandi Elemento principale di interfaccia tra SO e utente è l'interprete dei comandi (shell), che ha il compito di prendere i comandi specificati dall’utente e di eseguirli. Esso può fornire diversi tipi di interfaccia utente, come CLI, GUI, o batch. Command Line Interface (CLI): I comandi sono inseriti in forma testuale in un interprete (o shell), che li legge e li esegue. A seconda dell'implementazione l'interprete può essere un processo separato o eseguito dal kernel stesso. Il codice di ogni comando può essere parte dell'interprete stesso o fare riferimento ad un file separato che specifica il codice (shell script). Questo permette un'elevata possibilità di customizzazione. Graphical User Interface (GUI): Classica implementazione a desktop, interagibile con mouse e tastiera. Generalmete più user friendly, cala il livello di prestazioni e di specificità delle operazioni. System Calls e API Fra SO e i comandi dettati da un utente si interpongono system call e API(Application Program Interface). Una system call è un meccanismo usato a livello utente per richiedere un servizio a livello kernel e permettono di eseguire operazioni riservate, quali l'accesso all'hardware o alla memoria. Le system call sono specifiche di ogni SO, alcuni esempi sono open(), read(), write(), wait(). Per quanto riguarda le API, queste, a seconda del SO, invocano le system call e restituiscono i risultati all'utente, aggiungendo un ulteriore livello di astrazione. Le API non fanno quindi parte del kernel. Un esempio di API è l'app del meteo nel nostro cellulare. Essa mette in comunicazione il nostro cellulare con i server del meteo. Le 2 API piú comuni sono Win32 API (insieme di API usate su Windows) e POSIX (Portable Operating System Interface for Unix, insieme di API usate su tutte le versioni di UNIX). Implementazione delle System Calls Tipicamente, viene associato un numero ad ogni system call. È compito poi dell’interfaccia alle chiamate di sistema di mantenere una tabella che associa del codice (le system calls vere e proprie) ad ogni numero. L’interfaccia invoca la system call nel kernel del SO e poi ritorna lo stato della system call e gli eventuali valori di ritorno. In questo modo il chiamante non ha necessitá di conoscere nulla di come la system call è implementata. In breve, quando viene invocata una system call. accadono i seguenti eventi: 1. La system call viene invocata dal programma utente 2. Si passa dalla modalità utente (user mode) alla modalità kernel (kernel mode). Questa operazione è detta trap. 3. Viene usata la tabella per chiamare la system call corretta 4. Si passa dalla modalità kernel alla modalità utente ritornando il risultato. Ma quando invoco la system call come fa il sistema operativo a passare i parametri al processo che si occupa di eseguirla? Si possono passare principalmente in 3 modi: Passare i parametri (della system call) tramite registri Passare i parametri tramite lo stack del programma Lo stack è FIFO (First In First Out), quindi i parametri vengono salvati uno sopra l'altro Quando non servono più, questi non vengono cancellati (sarebbe uno spreco di tempo), ma vengono sovrascritti da nuovi parametri Memorizzare i parametri in una tabella in memoria L’indirizzo della tabella è passato in un registro o nello stack 3. Architettura La progettazione di un SO segue i due principi KISS (Keep It Simple Stupid) e POLA (Principle of Least Privileges), per il quale ogni componente deve avere tutti e solo i privilegi che gli permettono di svolgere la funzione per cui è stato scritto. Si pone inoltre una netta divisione tra policy (caratteristiche che definiscono il sistema) e meccanismi (come queste caratteristiche vengono implementate). Oggi la maggior parte dei SO è suddiviso in componenti, il modo in cui questi interagiscono definisce i vari tipi di architettura. Sistemi monolitici I sistemi operativi monolitici sono caratterizzati dalla mancanza di una gerarchia interna: tutti i componenti del sistema sono allo stesso livello e vi è un unico strato software che agisce da interfaccia tra l'utente e l'hardware. Questo significa che tutte le funzionalità del sistema operativo sono disponibili per ogni processo, senza alcuna limitazione gerarchica. Uno dei principali vantaggi di questo approccio è la sua semplicità: il kernel del sistema operativo è composto da un insieme di procedure che possono chiamarsi reciprocamente, senza la necessità di un'organizzazione gerarchica complessa. Questo rende la progettazione e l'implementazione del sistema operativo relativamente semplice e veloce. Tuttavia, i sistemi operativi monolitici presentano svantaggi importanti. Uno di questi è che il codice del sistema operativo dipende strettamente dall'architettura dell'hardware su cui è eseguito. Inoltre, poiché vi è un unico strato software, la fase di test e debug può risultare difficile. Problemi in una singola parte del kernel possono infatti avere effetti negativi su altre parti del sistema, rendendo il processo di ricerca dei bug più complesso e oneroso. Sistemi a struttura semplice SO semplice, organizzato con una minima struttura gerarchica, con una strutturazione che mira a ridurre i costi di sviluppo e di manutenzione. La definizione dei livelli della gerarchia è molto flessibile e varia da sistema a sistema. Un esempio di sistema operativo a struttura semplice è MS-DOS, il quale è stato progettato per fornire il maggior numero di funzionalità possibile nel minor spazio. MS-DOS possiede un minimo di struttura, ma le interfacce e i livelli di funzionalità non sono ben definiti. Inoltre, non prevede la modalità dual (modalità utente e modalità kernel) poiché l'Intel 8088, l'architettura hardware su cui è stato progettato, non lo forniva. Un altro esempio di sistema a struttura semplice è l'originale versione di UNIX. Questo sistema operativo presenta una struttura base limitata a causa delle limitate funzionalità dell'hardware dell'epoca. La struttura di UNIX consiste in due principali componenti: i programmi di sistema e il kernel, che rappresenta tutto ciò che sta tra il livello dell'interfaccia delle system call e l'hardware. Il kernel di UNIX fornisce funzionalità come il file system, lo scheduling della CPU, la gestione della memoria e altre funzioni. Struttura a livelli I componenti sono raggruppati in livelli gerarchici, che vanno dall'interfaccia utente (il livello più alto) all'hardware (il livello più basso). Ogni livello utilizza solo le funzionalità del livello inferiore e fornisce servizi al livello superiore, specificando l'interfaccia. Tra i vantaggi dei sistemi a livelli, vi è la modularità che facilita lo sviluppo e la manutenzione del sistema. Tuttavia, ci sono anche alcune difficoltà significative, prima fra tutti è la definizione efficace di livelli, dovuta al fatto che le funzionalità dipendenti dall'architettura sono sparse tra i vari livelli e questo diminuisce la portabilità. Inoltre, si ha una minore efficienza a causa di un overhead non trascurabile, dovuto al fatto che eventuali chiamate devono passare attraverso l'intera gerarchia del SO. Tra gli esempi di sistemi operativi a livelli, si possono citare THE, MULTICS e OS/2. THE, creato da Edsger Dijkstra nel 1968, è considerato il primo esempio di sistema a livelli. Sistemi basati su kernel Il sistema è suddiviso in servizi kernel e non kernel, in modo tale che il kernel sia il più piccolo possibile. Abbiamo praticamente gli stessi vantaggi del sistema a livelli, ma senza averne troppi. Questi SO sono facili da mantenere e da estendere, ma non esiste una chiara definizione per cosa dovrebbe stare nel kernel e cosa no. Kernel complessi e di grandi dimensioni diventano monolitici. Sistemi basati su micro-kernel I sistemi operativi basati su micro-kernel cercano di mantenere nel kernel solo ciò che è strettamente necessario. Il file system, l'interprete del sistema e altre funzionalità vengono eseguite in modalità utente, in modo da ridurre la complessità del kernel. Questo approccio presenta alcuni vantaggi rispetto ai sistemi operativi basati su kernel, tra cui una maggiore sicurezza, una maggiore stabilità e una maggiore modularità. Tuttavia, il principale svantaggio è che le performance sono generalmente peggiori, a causa della necessità di alternarsi continuamente tra la modalità kernel e la modalità utente. Sistemi a virtual machine Sono sistemi pensati per poter eseguire sulla stessa macchina più SO contemporanemante, in modo indipendente. Componente chiave è l'hypervisor, il software che crea e gestisce le VM, e che si pone fra l'hardware e il SO, emulando un hardware diverso da quello effettivo. Abbiamo due tipi di hypervisor, di tipo 1 e 2. Tipo 1: sopra l'hardware ci sta direttamente l'hypervisor con i vari SO (utilizzato dai Cloud Provider) Tipo 2: sopra l'hardware ci sta il SO principale,e sopra, l'hypervisor con il SO secondario. Questo gira come un programma qualsiasi. Questo è il tipo di VM che usiamo per virtual box, è meno performante ma ci permette di usare due SO allo stesso tempo. Gli hypervisor di tipo 1 si distinguono poichè girano direttamente sull'hardware e sopra di loro i sistemi operativi da eseguire, mentre l'hypervisor di tipo 2 gira come un normale processo su una macchina con un SO (e sopra di esso ancora altri SO). Uno dei vantaggi principali delle VM è che ogni macchina virtuale è completamente isolata dalle altre, il che significa che se una VM si blocca o presenta problemi, le altre VM continuano a funzionare normalmente senza essere influenzate. Questa isolazione è un grande vantaggio per l'affidabilità e la sicurezza del sistema. Un altro vantaggio delle VM è che è possibile eseguire più sistemi operativi sulla stessa macchina fisica contemporaneamente. Inoltre, le VM offrono un'ottima portabilità, in quanto le macchine virtuali possono essere facilmente spostate da una macchina fisica a un'altra, senza dover riprogrammare l'applicazione o il sistema operativo. Le VM sono anche una scelta popolare per gli sviluppatori di sistemi operativi e software, in quanto consentono di testare le applicazioni in un ambiente sicuro e isolato senza dover acquistare hardware aggiuntivo. Tuttavia, ci sono anche degli svantaggi nell'utilizzo delle VM. Il primo svantaggio è che ogni macchina virtuale è completamente isolata dalle altre, il che può essere sia un vantaggio sia uno svantaggio, dipende da cosa si vuole fare. Inoltre, poiché ogni VM richiede la propria memoria e le proprie risorse di elaborazione, ci possono essere problemi di performance se troppe VM vengono eseguite contemporaneamente sulla stessa macchina fisica. Sistemi client-server Simile al micro-kernel nel modo in cui sposta ai livelli superiori le funzioni non essenziali. Il kernel si occupa della comunicazione tra client e server. Questa architettura è essenzialmente usata nei sistemi distribuiti. Per quanto riguarda l'implementazione di un sistema operativo, attualmente si utilizzano soprattutto linguaggi ad alto livello come C/C++ per la rapidità di implementazione, portabilità e debugging. Tuttavia molte direttive, laddove più efficiente, sono scritte in assembler.