cerca
Riassunto Capitolo 3 - Struttura dei SO
modifica cronologia stampa login logout

Wiki

UniCrema


Materie per semestre

Materie per anno

Materie per laurea


Help

Riassunto Capitolo 3 - Struttura dei SO

 :: Riassunto Capitolo 3 - Struttura dei SO ::

Torna alla pagina di Sistemi Operativi

Diversi punti di vista per considerare un SO:

  1. servizi che offre
  2. interfaccia ad utenti
  3. interfaccia ai programmatori
  4. componenti
  5. interconnessioni

3.1 Componenti del SO

3.1.1 La gestione dei processi

Processo = programma in esecuzione => chiamate di sistema per permettere ai processi di creare sottoprocessi da eseguire in modo concorrente.

OCIO: programma != processo: programma = passivo processo = attivo

Processo: esecuzione sequenziale => contatore di programma che dice qual'è la prossima istruzione da eseguire.

In relazione ai processi, il SO deve:

  1. generare e cancellare processi di sistema
  2. generare e cancellare processi utente
  3. sospendere e riattivare i processi
  4. meccanismi per sincronizzare processi
  5. meccanismi per far comunicare i processi
  6. meccanismi per gestire i deadlock

3.1.2 La gestione della memoria centrale

Durante la fase di fetch la CPU preleva istruzioni dalla memoria. La fase di data-fetch invece legge e scrive sulla memoria.

Multiprogrammazione => occorre gestire la memoria centrale:

  1. sapere chi ha la proprietà su quale parte della memoria
  2. decidere quali processi caricare in memoria quando lo spazio si libera
  3. allocare e deallocare spazio in memoria quando è necessario

3.1.3 La gestione dei file

Uso comodo del computer => visione logica di memorizzazione delle info => file = unità logica di memorizzazione.

File = insieme di info correlate dal creatore del file. Organizzati in directory per facilitarne l'uso.

Operazioni che il SO fa riguardo ai files:

  1. creare e cancellare i files
  2. creare e cancellare directory
  3. manipolare files e directory
  4. copiare i files
  5. salvare i files

3.1.4 La gestione dell I/O

Sottosistema di I/O = nasconde le caratteristiche dei dispositivi I/O al resto del SO.

Il sottosistema I/O è fatto di:

  1. componente per la gestione della memoria che include buffer, cache, processo di stampa (?? che c'entra? è un solo esempio?)
  2. interfaccia generale del driver
  3. driver per dispositivi hardware specifici

3.1.5 La gestione delle unità di memorizzazione secondarie

Dicevamo che la memoria centrale è troppo piccola per contenere tutto, e soprattutto è volatile => occorre avere un'unità di memorizzazione secondaria che supplisca, e da cui e verso cui copiare dati e programmi che man mano servono

Le unità di memorizzazione secondarie vanno ben gestite:

  1. gestire lo spazio libero
  2. allocare le unità disco
  3. occuparsi della schedulazione dei dischi

3.1.6 Le reti informatiche

Sistema distribuito = insieme di processori che non condivide memoria, periferiche o orologio => collegati con una rete di comunicazione

HW per realizzare la rete + SW per gestirla = rete informatica

3.1.7 Il sistema di protezione

Processi separati protetti l'un l'altro

Protezione = insieme dei meccanismi per il controllo dell'accesso alle risorse da parte dei processi o degli utenti dei computer.

3.1.8 L'interprete dei comandi

Interprete dei comandi = uno dei programmi di sistema più importanti = interfaccia tra utente e SO.

SO = differenti in base all'amichevolezza dell'interprete dei comandi, che può esere una shell testuale o una GUI (graphical user interface).

Comandi accessibili tramite interprete = tutti, eg gestire processi, I/O etc.

3.2 Servizi del sistema operativo

Ogni SO fornisce servizi diversi ma si possono raggruppare in categorie comuni

  • Esecuzione di un programma = caricare un programma in memoria ed eseguirlo, poi terminarlo in modo normale od erroneo
  • Operazioni di I/O = per sicurezza non deve essere l'utente a gestire direttamente le periferiche, ma deve chiedere al SO di farlo
  • Manipolazione del file system
  • Comunicazioni = tra processi (memoria condivisa, mailbox & co.)
  • Rilevamento degli errori = errori HW o SW

Gruppo di funzioni che servono ad assicurare un uso efficiente del sistema:

  • Allocazione delle risorse = assegnare risorse ai molteplici processi in funzione contemporaneamente
  • Contabilità = sapere quali utenti stanno usando quali risorse => eg far pagare in base all'uso, o fare statistiche per poi magari impostare meglio i parametri del SO in funzione dell'uso che se ne fa
  • Protezione e sicurezza = accessi controllati a tutte le risorse del sistema. Sicurezza esterna = rispetto agli utenti.

3.3 Chiamate di sistema

Chiamata di sistema = interfaccia tra processo e SO => accessibili in assembly o anche in linguaggi di alto livello => in questo caso assomigliano a chiamate di funzioni normali.

Dettagli di tale interfaccia = nascosti al programmatore.

Passare parametri al SO: tre metodi

  1. usare i registri, ma i registri sono pochi
  2. metterli in una tabella (blocco) in memoria e passare l'indirizzo di tale blocco
  3. metterli in uno stack

Gli ultimi 2 metodi non impongono limitazioni al numero di parametri.

Chiamate di sistema = raggruppabili in 5 categorie:

  1. controllo del processo
  2. gestione dei file
  3. gestione del dispositivo
  4. gestione delle informazioni
  5. comunicazioni

3.3.1 Il controllo del processo

Processo:

  • fine = termina correttamente
  • aborto = termina in modo anormale

load = caricare un altro programma. execute = eseguire l'altro programma. => i nuovi programmi possono essere eseguiti in sequenza (A crea B, lo esegue, B finisce e il controllo torna ad A) oppure in modo concorrente (A crea B e ognuno va per la sua strada).

Patria potestà sui processi generati:

  • richiedere ed impostare gli attributi dei processi generati (priorità, tempo massimo di esecuzione, ...)
  • terminare i processi generati
  • aspettare che finiscano l'esecuzione

Debug: dump della memoria per vedere eventuali errori; trace per seguire le istruzioni passo passo => alcune CPU hanno la modalità single step in HW, in cui dopo ogni istruzione si esegue una TRAP.

Tracciamento = con trace e temporizzatore vedo quali porzioni di codice sono più usate dal mio processo => utile per i programmatori.

Esempi: MSDOS: SO a processo singolo => carico un programma e questo sostituisce una parte dell'interprete dei comandi. Quando termina, ricarica l'interprete dei comandi. TSR = terminate and stay resident = intercetta interrupt, viene eseguito e termina, ma non viene tolto dalla memoria => l'interprete gli riserva dello spazio non sovrascrivibile.

FreeBSD: multitasking. Un utente lancia un comando dalla shell => la shell fa una fork e poi nella copia ottenuta viene chiamata la exec, che sostituisce il codice della shell con quello del programma invocato. Si può scegliere di attenderne l'esecuzione, o di eseguirlo in parallelo.

3.3.2 La gestione dei file

Generare, cancellare, read, write, reposition, close. Idem per le directory. Occorre anche saper leggere e impostare gli attributi dei files.

3.3.3 La gestione dei dispositivi

File = si possono vedere come dispositivi astratti => le chiamate di sistema per i files vanno bene anche per i dispositivi.

Infatti molti SO (eg UNIX) mappano i dispositivi nel filesystem.

3.3.4 La gestione delle informazioni di sistema

Ora, data, numero di utenti, versione del SO, RAM libera, disco utilizzato; info per ogni processo (chi lo ha eseguito, da quanto, quanta RAM occupa etc. => Capitolo 4.1.3)

3.3.5 Le comunicazioni

2 modelli:

  1. message passing
  2. shared memory

Message passing = il SO permette la creazione di un collegamento fra processi.

Shared memory = si elimina consensualmente tra processi la protezione della memoria, così che più processi possano accedervi.

3.4 Programmi di sistema

Programmi di sistema = ambiente opportuno per sviluppo ed esecuzione di programmi.

  • Gestione dei file
  • Informazioni di stato
  • Modifica dei file
  • Supporto ai linguaggi di programmazione
  • Caricamento ed esecuzione di programmi (linker, overlay etc.)
  • Comunicazioni

Ci sono anche i programmi applicativi.

Programma di sistema più importante = interprete dei comandi.

2 modi per implementare i comandi dell'interprete:

  1. l'interprete contiene in sé il codice del comando
  2. l'interprete chiama un programma di sistema per ogni comando

UNIX usa il metodo 2:

  • pro = si possono aggiungere comandi a piacimento, e lasciare uguale l'interprete
  • contro = occorre passare parametri ai comandi, e possono non essere uniformi (dipende da chi ha scritto il particolare programma)

L'utente vede il SO tramite i programmi di sistema, non tramite le chiamate di sistema.

OCIO: il SO non fa distinzione tra processi applicativi e processi di sistema: per lui sono tutti processi.

3.5 Struttura del sistema

Dopo aver visto le componenti, ora vediamo come metterle insieme in un kernel = nucleo.

3.5.1 Una struttura semplice

Sistemi che non sono divisi in moduli, per vari motivi progettuali o storici.

Interfaccia dei programmi applicativi = API = chiamate di sistema. Interfaccia utente = gruppo di programmi di sistema disponibili, che usano le chiamate di sistema.

=> Top-down: dall'utente all'hardware => le interfacce esterne possono rimanere identiche anche se quelle interne cambiano.

3.5.2 La struttura stratificata

SO = diviso in layer (strati). Il più basso è l'hw. Quello più alto è l'interfaccia utente.

Vantaggi:

  • modularità: ogni strato permette di usare solo le funzioni dello strato immediatamente sotto, e non di quelli più in fondo => debug semplice
  • progettazione facilitata
  • uno strato è implementato con le sole interfacce dello strato cui si appoggia => dettagli nascosti

Difficoltà:

  • definire i vari strati
  • efficienza: una chiamata da uno strato alto deve attraversare N strati prima di arrivare dove vuole => overhead delle chiamate

3.5.3 Microkernel

Microkernel = tutto ciò che non è indispensabile è levato dal kernel. Fondamentalmente rimangono i meccanismi di comunicazione tra processi.

Tutto il resto è implementato come programmi di sistema.

Pro:

  • il SO è estendibili aggiungendo programmi e lasciando inalterato il microkernel
  • il microkernel è facilmente mantenibile
  • il microkernel è semplice => facilmente portabile da un'architettura HW ad un'altra
  • siccome i servizi sono a livello utente, è in generale più sicuro

Contro:

  • calo di prestazioni, perché tutti i messaggi devono passare dal microkernel => sovraccarico

3.5.4 La struttura modulare

C'è un kernel centrale, e intorno, allo stesso livello, sono creati diversi moduli, raggruppabili in 7 categorie:

  1. classi di schedulazione
  2. file system
  3. chiamate di sistema caricabili
  4. formati eseguibili
  5. moduli degli stream
  6. driver dei dispositivi
  7. varie

In questo modo, il kernel offre le funzioni base, gli altri moduli forniscono il resto, e i vari moduli possono comunicare direttamente tra loro senza passare per gli strati.

3.6 Macchine virtuali

Virtualizzazione = dare al processo l'illusione di avere una macchina tutta per sé.

Sopra l'HW c'è l'implementazione di una macchina virtuale => la macchina virtuale riproduce una copia esatta dell HW sottostante => su ogni macchina gira un kernel diverso.

I processi girano quindi dentro il loro SO privato.

Pro:

  • protezione completa dei processi (ma anche problema nella condivisione di risorse)
  • ideale per sviluppare e provare SO nuovi
  • risolve problemi di compatibilità (uso un SO diverso su ogni macchina, per avere il meglio delle 2)

Implementazione: prima dicevamo che c'è una modalità utente, e una modalità di sistema (monitor) => qui le cose si complicano perché c'è la modalità utente virtuale e la modalità monitor virtuale.

Le macchine virtuali (VM) sono processi che, rispetto al SO vero e proprio sottostante (quello che offre una copia dell'HW), sono dei processi utente.

Un processo su una VM gira in modalità utente virtuale. Quando fa chiamate di sistema, queste vengono eseguite in modalità monitor virtuale.

=> una chiamata I/O fa questa strada: utente virtuale => monitor virtuale => utente fisico => monitor fisico; poi c'è il ritorno => può metterci molto tempo.

3.7 Java

Java = è una tecnologia, non un semplice linguaggio, perché fornisce un sacco di cose in più rispetto ad un semplice linguaggio:

  1. specifiche del linguaggio di programmazione
  2. interfaccia di programmazione (API) => è vastissima ed onnicomprensiva
  3. specifiche della macchina virtuale

Unisce l'idea di macchina virtuale, realizzata come processo utente su di un SO => i concetti visti nei paragrafi sopra non sono mutuamente esclusivi.

3.7.1 Il linguaggio di programmazione

Orientato agli oggetti, indipendente dall'architettura, distribuito, multithread.

Le classi sono compilate in bytecode, a sua volta eseguito dalla macchina virtuale (realizzata in SW o anche in HW, volendo).

Applet = programmi con accesso limitato alle risorse eseguibili direttamente in un browser web.

Garbage collection = l'allocazione e la deallocazione della memoria è a carico di Java e non dell'utente.

3.7.2 L'interfaccia per i programmi applicativi (API)

  1. API standard per appli desktop, applet, grafica, I/O, utilità, rete
  2. API industriale per server, database
  3. API per piccoli dispositivi eg palmari, cellulari

Nel testo ci si concentra sulle API standard.

3.7.3 Java Virtual Machine

Java Virtual Machine = JVM => caricatore di classi ed interprete che esegue i bytecode.

Bytecode = formato in cui sono compilate le classi => è indipendente dall'architettura HW => un programma Java funziona su qualsiasi JVM su qualsiasi sistema operativo.

Interprete = esegue i comandi uno alla volta, o li compila in tempo reale (JIT = just in time) in linguaggio nativo del computer ospite.

Piattaforma Java = astrazione dalla macchina fisica => permette la portabilità.

3.7.4 L'ambiente di sviluppo per Java

Ambiente di compilazione e di run-time. Ambiente di compilazione = trasforma una classe in bytecode Run-time = la JVM su cui viene eseguito il codice

3.7.5 Sistemi operativi in linguaggio Java

È basato sul linguaggio => tutto funziona nello stesso spazio di indirizzamento => la protezione della memoria è affidata al linguaggio e non al SO.

3.8 Progettazione ed implementazione di un sistema operativo

3.8.1 Obiettivi del progetto

Primo problema = definire obiettivi e specifiche.

Alto livello:

  • su quale HW gira
  • tipo di sistema: a batch, a condivisione di tempo, realtime, mono|multi utente, distribuito etc.

Obiettivi dell'utente:

  • comodo e facile da usare
  • affidabile
  • sicuro
  • veloce

Obiettivi del programmatore:

  • facile da progettare e mantenere
  • flessibile
  • affidabile
  • efficiente

=> In conclusione, sono tutti obiettivi vaghi e non c'è accordo su come realizzarli => creatività ed esperienza.

Ci sono però principi generali, che vediamo qui sotto.

3.8.2 Meccanismi e politiche

Meccanismo = come fare qualcosa. Politica = che cosa fare, e quando

Desiderabile avere meccanismi slegati dalle politiche:

  • se il meccanismo cambia, la politica resta uguale
  • se la politica cambia, il meccanismo resta uguale

=> posso provare e sperimentare diverse politiche e meccanismi

3.8.3 Implementazione

Dopo la progettazione, devo realizzare il SO.

Tradizonalmente = assembly o linguaggio macchina.

Ora = linguaggi a più alto livello (in genere C).

Vantaggi dell'utilizzo di linguaggi ad alto livello:

  • scrivere codice più velocemente
  • mantenibilità del codice
  • portabilià
  • se migliora il compilatore, basta ricompilare il tutto per avere vantaggi

Svantaggi:

  • velocità inferiore rispetto all'assembly
  • più memoria necessaria

Però:

  • i miglioramenti si hanno quando si usano algoritmi migliori, non quando si scrive meglio in assembly
  • solo piccole parti del SO sono critiche per la velocità

=> uso l'ASM per le parti critiche, dopo aver identificato i colli di bottiglia (trace e debug, vedi sopra).

3.9 Generazione del SO

Posso scrivere SO specifici per una certa macchina.

Ma in generale sono più versatili (girano su più HW etc.) => il procedimento chiamato SYSGEN (system generation) configura il SO in base ai parametri:

  • Quale CPU si usa? (x86, MIPS, PPC... ha coprocessore matematico...) E quante?
  • Quanta memoria è disponibile? => molti SO lo scoprono da soli all'avvio
  • Quali dispositivi sono disponibili?
  • Quali opzioni del sistema attivo, e quali no?

Queste scelte possono essere prese una volta, oppure organizzate in tabelle => all'avvio, il SO legge dalle tabelle e si autoconfigura.

L'avvio del sistema operativo avviene nella fase di boot.

3.10 Avvio del SO

Bootstrap: all'avvio o al reset, viene caricato il program counter con una locazione di memoria prestabilita => l'esecuzione parte da lì.

Il programma di bootstrap di solito è in ROM. Può fare tutto quello che vuole (diagnostica etc.). Alcuni SO hanno tutto in ROM (eg i palmari) => EPROM riscrivibili etc.

Sistemi operativi grandi:

  1. il bootstrap fa la diagnostica
  2. carica un programma da un punto predeterminato in memoria secondaria, eg il blocco di avvio di un disco
  3. questo programma (piccolo e semplice perché sta in un singolo blocco) conosce l'indirizzo sul disco del SO e lo carica da lì: sa come trovare le info nel filesystem
  4. il sistema è finalmente avviato.

Torna alla pagina di Sistemi Operativi