Memoria centrale
La memoria centrale è la memoria principale di un elaboratore elettronico. In essa sono registrati i dati temporanei elaborati dal processore durante l’esecuzione di un programma. Essa risiede sulla scheda madre del calcolatore ed è molto vicina alla CPU; in questo modo la CPU può comunicare in maniera più veloce con essa. È molto più veloce rispetto alle memorie di massa e si suddivide in: memoria RAM, memoria ROM e memoria Cache.
Definizione di processo
Un processo è un programma in esecuzione completo del suo stato (completo del suo spazio di indirizzamento, contenuto dei registri, file aperti ecc.). Tutto o parte dello spazio di indirizzamento è residente in memoria centrale. Per funzionare correttamente, il Loader deve avere a disposizione un file eseguibile. Il file eseguibile viene creato a partire da un programma.
Quando scriviamo un programma, di solito lo scriviamo con un linguaggio di alto livello. Questo linguaggio non è direttamente interpretabile da parte della macchina su cui deve essere eseguito, per questo motivo deve essere “tradotto”, o meglio compilato. La compilazione avviene attraverso un compilatore che si occuperà dunque di trasformare un programma in un file eseguibile. Un file eseguibile è un file binario memorizzato sul disco che contiene tutte le informazioni necessarie all’esecuzione del programma da parte del processore. Il formato del file dipende dal sistema operativo che deve curarne l’esecuzione.
Spazio di indirizzamento
Lo spazio di indirizzamento è l’immagine della memoria visibile al programma durante la sua esecuzione. Esso viene caricato in memoria centrale. Un programma viene eseguito quando viene caricato nel Program Counter (registro della CPU che contiene l’indirizzo di memoria della prossima istruzione da far eseguire alla CPU) l’indirizzo di memoria della prima istruzione, nell’area testo del programma da eseguire, da far eseguire alla CPU. A questo punto, il programma ha il controllo del processore.
Spazio di indirizzamento – caso del linguaggio C
Nell’area dati BSS vanno memorizzate tutte le variabili globali o statiche che sono state inizializzate a zero oppure che non sono state esplicitamente inizializzate.
Magic number
Il magic number è una sequenza di bit posta prima della sequenza di dati che serve a definire il formato in cui i dati sono memorizzati. Sono nati negli ambienti UNIX per identificare il formato dei file binari e per la gestione dei dati nella memoria. Sebbene quasi tutti i formati di file siano identificati da un magic number, la Microsoft, sin dalle sue prime versioni del suo sistema operativo, ha deciso di adottare un nuovo identificativo: l’estensione.
- I file GIF iniziano con la stringa ASCII GIF87a oppure ASCII GIF89a.
- I file ZIP cominciano con la stringa PK (in esadecimale 50 4B), in onore dell’ideatore Phil Katz.
- I file ELF di Linux iniziano con la stringa 7F 45 4C 46: gli ultimi 3 byte di questa stringa formano la parola ELF.
Condivisione della RAM
La memoria RAM (Random Access Memory - Memoria ad accesso casuale) è una memoria di tipo volatile (necessita dell'alimentazione elettrica per mantenere memorizzate le informazioni) che permette l'accesso a qualsiasi indirizzo di memoria con lo stesso tempo di accesso. Nella memoria RAM vengono caricati i programmi che la CPU deve eseguire. Quando un programma viene chiuso, se le informazioni non vengono salvate sul disco rigido o su una memoria di tipo non volatile, verranno perse.
La RAM contiene lo spazio di indirizzamento di più processi e contiene anche un’area riservata che serve a contenere i processi del sistema operativo, perché anch’esso occupa risorse. La differenza tra un processo normale ed un processo del sistema operativo è che il processo normale lavora in user mode, mentre il processo del sistema operativo lavora in Kernel Mode e può fare tutto a differenza di un processo in user mode.
Siccome sulla RAM devono condividere più spazi di indirizzamenti di più processi, non deve accadere che un processo abbia la possibilità di accedere agli indirizzi fisici della RAM al di fuori della sua area. Quando il compilatore/linker va a compilare le istruzioni di un processo assume che lo spazio di indirizzamento del processo che sta compilando parta da 0 fino ad un valore di limite. Esso però non conosce il processo che deve compilare a quale indirizzo fisico (sulla RAM) è associato, quindi, se non viene effettuata un’operazione di rilocazione si rischia di far accavallare gli indirizzi sulla memoria RAM.
Nasce quindi la necessità di effettuare un processo di rilocazione degli indirizzi e viene fatta in hardware, ovvero usando componenti elettronici. Questa operazione consiste nell’andare a ricavare quale è l’indirizzo base del processo in esecuzione e sommare a quest’ultimo l’indirizzo proveniente dal Program Counter (che contiene l’indirizzo della prossima istruzione da eseguire e questo indirizzo se lo prende dallo spazio di indirizzamento del processo in esecuzione) a patto che sia minore del valore limite dello spazio di indirizzamento del processo.
Supponendo di star eseguendo il processo 2, il sistema operativo prima di cominciare l’esecuzione di quel processo, mette nel registro base l’indirizzo base di quel processo. In questa maniera tutti gli indirizzi, sia quelli delle istruzioni (Program Counter), sia gli indirizzi dei dati, prima di andare verso la memoria, quindi prima di essere messi sui fili dei bus, vengono incrementati di questo valore. Questo comporta che ad ogni passaggio da un processo ad un altro, il sistema operativo deve ricordarsi di aggiornare l’indirizzo base. Usando invece il registro limite, posso stabilire per ogni processo i vincoli di memoria in cui si può muovere quel determinato processo. Un tentato accesso allo spazio di memoria di un altro processo genera un errore.
Domande esami
- Classe semaforo codice
- Come viene dichiarata la system call “open”
- Come vengono rappresentati i permessi?
- Chi può modificare questi permessi?
- Cosa succede per il processo quando viene aperto un file?
- Cosa ci sta nella tabella dei file aperti?
- Cos’è il TLB?
- Come avviene la traduzione indirizzo logico ad indirizzo fisico?
- Mi scriva un programma in cui un padre genera 2 figli e passa al secondo figlio il PID del primo figlio tramite pipe. Il secondo figlio invia un segnale al primo figlio.
- Quando si verifica il page fault? E cosa succede quando si verifica? Quali sono i campi che vengono modificati?
- Come è visto un indirizzo logico? (Pagina logica, offset)
- Mi spieghi l’algoritmo LRU che utilizza il bit R, come funziona e che significa l’acronimo LRU. Cos’è il bit R? Come viene messo a 1?
- Cos’è un i-node e come viene fatto?
- Quali sono le strutture dati dei file system? (Oltre a inode abbiamo directory)
- Che informazioni ci sono nella directory?
- Questo numero di inode che sta nella directory come lo utilizzo per recuperare l’inode dal disco?
- Esercizio: lettore scrittore con lettori che possono lavorare insieme e scrittori che devono lavorare in mutua esclusione
- Esercizio: produttore-consumatore con una coda limitata di posti di cui 4 sono già occupati. Se invertiamo i due UP accade qualcosa?
- Come funziona l’istruzione test and set (TSL)? Scrivere l’istruzione a codice con gli operandi
- Cos’è il process control block (PCB)? Quali sono le sue componenti?
- Quali sono gli stati del processo e come si passa dall’uno all’altro? (Wait, ready, running)
- Che cos’è una system call?
- Come è fatta una directory DOS? (Minuto 24:50 registrazione) con riferimento alla parte di gestione della path
- Cos’è un monitor? Quali sono le caratteristiche che fanno di una classe un monitor? Che caratteristiche devono avere i metodi? Cosa sono le variabili di condizione, a che servono e come vengono utilizzate?
- Produttori-consumatori con coda limitata inizialmente piena
- Attivazione di un processo padre e un figlio. Il figlio fa l’exec mentre il processo padre deve ridigere lo stdout del figlio
- Com’è fatta la tabella delle pagine? Com’è fatta la singola riga della tabella delle pagine? Quali sono gli elementi principali del record? Quante righe deve avere la tabella delle pagine?
- Lettori e scrittori con memoria condivisa. La sequenza è una scrittura seguita da tre letture con scrittori e lettori che lavorano in mutua esclusione.
- Scriva l’interfaccia della funzione fopen
- Permessi + tabella dei file aperti
- Programma C in cui un padre crea il figlio il quale invia un segnale SIGUSR1 al padre che aspetta questo segnale e termina.
- Traduzione indirizzo logico-fisico in una memoria paginata
- LRU
- Applicazione multithread con una catena di montaggio di N thread che devono eseguire le operazioni 1 alla volta. Il thread che parte deve essere scelto dal thread zero in modo casuale.
- Cosa sono i monitor? Differenza con i semafori
- Thread che inseriscono uno alla volta un oggetto nel deposito (di dimensione infinita) e dobbiamo evitare che lo stesso thread inserisca 2 oggetti consecutivi
- Read
- Una volta identificata la riga della tabella dei file aperti che facciamo?
- Cos’è il TLB?
- Cosa fa il SO quando facciamo una open?
Rilocazione
Indirizzo iniziale del programma nella memoria RAM. Indirizzo corretto diretto alla memoria RAM. Ampiezza dello spazio di indirizzamento.
Protezione
Un processo, inoltre, nasce anche quando viene inizializzato il sistema, quando l’utente decide di eseguire un programma (facendo doppio click sull’icona o lancia un file eseguibile) oppure, nel caso dei sistemi batch, quando a una certa ora del giorno inizia un job batch.
Le system call, dette anche chiamate di sistema, permettono ai programmi a livello utente di richiamare i servizi del sistema operativo. Esse sono solitamente disponibili come speciali istruzioni assembler oppure come funzioni speciali nei linguaggi che supportano direttamente la programmazione di sistema (come ad esempio il linguaggio C). Per ottenere un servizio del sistema operativo quindi si usano queste system call e la richiesta del servizio avviene grazie al passaggio dalla modalità utente alla modalità kernel per mezzo di un’istruzione speciale chiamata trap.
Il codice relativo ai servizi del sistema operativo è eseguibile solo in kernel mode per ragioni di sicurezza. Una volta terminato il compito relativo alla particolare chiamata invocata, il controllo ritorna al processo chiamante passando dal kernel mode alla user mode.
Sono disponibili per il programmatore una serie di funzioni di libreria che variano da circa 70 a oltre 200 a seconda della versione di UNIX. POSIX, che è una famiglia di standard definiti dall’IEEE (associazione internazionale di scienziati con l’obiettivo della promozione delle scienze tecnologiche), standardizza un nucleo base di queste system call (circa 120) a livello di interfaccia per il linguaggio C.
Lo standard input è un canale standard da cui giunge un flusso di dati in ingresso al programma. Il programma li trasferisce effettuando operazioni di lettura. Il file descriptor ad esso associato è 0. Lo standard output è un canale standard su cui un programma scrive i suoi dati in output. Il programma trasferisce i dati effettuando operazioni di scrittura. Il file descriptor ad esso associato è 1. Lo standard error è un canale standard di output tipicamente usato dai programmatori per i messaggi d’errore o di diagnostica. È indipendente dal canale standard 1, ovvero quello di output, e il file descriptor ad esso associato è 2.
I file standard vengono aperti dalla shell (terminale) del sistema operativo.
Puntatore a carattere
Serve per spostare il cursore alla fine del file. È utile quando si vuole effettuare una write per scrivere senza cancellare ciò che c’è già scritto nel file.
Cancella tutto ciò che è scritto nel file e sposta quindi il cursore all’inizio del file. Un file può essere aperto più volte. In questo caso ad esso saranno associati più file descriptor contemporaneamente.
Set User ID
Il Set UID è un tipo di permesso che, se viene applicato ad un file eseguibile, indica che il file deve essere eseguito con i permessi dell’utente proprietario del file, anziché con quelli dell’utente che lo avvia. Viene usato quindi per consentire ad utenti ordinari di eseguire programmi che richiedono particolari privilegi di sistema di cui normalmente dispone solo l’amministratore. Ritorna 0 in caso di successo e -1 in caso di errore.
Quando un processo termina, tutti i file aperti da esso vengono automaticamente chiusi.
1 carattere = 1 byte
Il primo parametro è il file descriptor del file aperto da cui si vuole effettuare la lettura. Il secondo parametro è un array di caratteri di dimensione prefissata. Il terzo parametro indica il numero di byte da leggere dal file in base alla posizione attuale del cursore nel file (offset). Restituisce il numero di byte letti dal file partendo dalla posizione attuale del cursore nel file. In caso di errore restituisce -1. Chiamare una read subito dopo una write, restituisce 0 perché il cursore nel file è all’ultima posizione quindi non legge niente dopo. Bisogna usare la funzione lseek che sposterà il cursore in base ai parametri che inseriamo.
Questa system call inizia a scrivere da dove sta posizionato attualmente il cursore nel file. Il primo parametro è il file descriptor del file aperto nel quale si vuole effettuare la scrittura. Il secondo parametro è un array di caratteri di dimensione prefissata che all’interno in ogni casella tiene memorizzato un carattere. Il terzo parametro indica il numero di byte da leggere dal buffer di caratteri (array di caratteri) e da scrivere nel file. Restituisce il numero di byte scritti nel file oppure restituisce -1 in caso di errore.
Se non richiamo questa sistem call, quando viene aperto un file, il cursore è impostato di default all’inizio del file. Se per caso dopo una open si vuole scrivere con una write, le stringhe che verranno scritte nel file verranno scritte all’inizio del file, sovrascrivendo le prime stringhe e lasciando inalterate le restanti se sono presenti. Restituisce la posizione del file attuale dopo l’effetto della system call. Restituisce -1 in caso di errore.
DOVE VOGLIO CREARE LA CARTELLA
PERCORSO DOVE E' MEMORIZZATA QUESTA CARTELLA
Restituisce il nuovo file descriptor oppure restituisce -1 in caso di errore. Aspetta prima e poi procede con le prossimi istruzioni. Restituisce il pid del processo terminato oppure -1 in caso di errore. Quando il padre si accorge che il figlio è terminato attraverso la wait(), il processo figlio zombie viene eliminato. Un processo zombie occupa un insieme minimale di risorse. Non il nome del file .c! Ma il nome del file eseguibile.exe. In sostanza rimane inalterata l'esecuzione finché non viene eliminato.
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.
-
Soluzione teoria Sistemi operativi
-
Domande Teoria Sistemi operativi
-
Sistemi Operativi
-
Sistemi operativi - teoria completa