(DMA)
Le operazioni di trasferimento dati prevedono:
Lettura da un registro e scrittura nella memoria, seguendo cicli ripetuti per ogni
elemento.
Il trasferimento può essere eseguito dall’unità di processamento, ma in sistemi
complessi può incidere sui tempi di esecuzione.
Il DMA (DIRECT Memory Access):
Viene programmato per gestire autonomamente il trasferimento di blocchi di dati
in determinate aree di memoria.
Permette al processore di eseguire altre istruzioni mentre il trasferimento dati
avviene in parallelo.
Al termine, la DMA segnala il completamento tramite un interrupt, che viene
gestito come descritto in precedenza.
Gerarchia della Memoria e Protezione del Sistema
Struttura della Memoria nei Sistemi di Elaborazione
La memoria di un sistema è organizzata in una gerarchia che comprende:
Memorie interne al processore: Registri e cache, caratterizzate da
tempi di accesso molto rapidi ma con capacità ridotta.
Memoria centrale: Comprende RAM ed ECROM; la RAM è più capiente
ma con tempi di accesso maggiori.
Memoria secondaria: Dispositivi non volatili (come dischi) con capacità
molto elevate e tempi di risposta più lunghi.
Nei programmi in esecuzione, la memoria viene suddivisa in aree specifiche:
Codice (Testo): La sequenza di istruzioni da eseguire.
Area dati: Dati statici (variabili globali) e dati dinamici (allocati in fase di
esecuzione).
IP (Heap): Utilizzata per l’allocazione dinamica dei dati.
Stack: Memorizza chiamate di funzione, parametri e informazioni di ritorno.
Meccanismi di Protezione: Modalità Utente e Modalità Kernel
I processori moderni operano in due modalità distinte:
Modalità utente: Consente l’esecuzione di istruzioni non privilegiate,
limitando l’accesso diretto a risorse critiche del sistema.
Modalità kernel (o di sistema): Permette l’esecuzione di tutte le
istruzioni, incluse quelle privilegiate (es. disabilitazione degli interrupt o
accesso diretto all’hardware).
La commutazione tra modalità è controllata da un bit nel registro di stato del
processore:
L’istruzione che modifica questo bit è privilegiata e può essere eseguita solo in
modalità kernel.
Se un programma in modalità utente tenta di eseguire un’istruzione privilegiata,
viene generata una trap.
Questo meccanismo protegge:
Le aree di memoria riservate (come la tabella degli interrupt e la tabella delle
chiamate di sistema).
L’integrità del sistema, impedendo che un programma acceda o modifichi dati
altrui o componenti critici del kernel.
Il Meccanismo delle Chiamate di Sistema
chiamate di sistema
Le permettono a un programma utente di richiedere
servizi al sistema operativo.
Il procedimento prevede:
Invocazione di un’istruzione (ad es. syscall) che trasmette un codice numerico e
relativi parametri identificativi.
Generazione di una trap che commuta l’esecuzione dalla modalità utente a
quella kernel. tabella delle chiamate di sistema,
Consultazione di una che mappa
ciascun codice numerico all’indirizzo della routine del kernel corrispondente.
Esecuzione della routine e, al termine, ritorno in modalità utente con ripristino
del contesto.
Questo meccanismo assicura che operazioni sensibili (come l’accesso alla memoria,
agli I/O e l’allocazione dinamica) siano gestite in ambiente controllato.
Sistemi di Elaborazione e Multiprogrammazione
Sistemi Monoprocessore, Multiprocessore e Multi-Core
Sistema Monoprocessore:
Possiede una sola unità di processamento.
Un’unica istruzione viene eseguita in un dato istante; la multiprogrammazione
è ottenuta attraverso una rapida alternanza delle istruzioni.
Sistema Multiprocessore:
Contiene più processori fisici, che condividono la memoria centrale (SMP –
multiprocessazione simmetrica).
Permette l’esecuzione parallela di istruzioni, aumentando l’efficienza ma
richiedendo una gestione complessa del bus condiviso.
Processori Multi-Core:
Un singolo microprocessore con più unità di processamento interne (core).
Ogni core possiede registri e, talvolta, cache private, pur condividendo
l'interfaccia del bus di sistema.
Consente l’esecuzione di più istruzioni in parallelo all’interno dello stesso chip.
Gestione Software, Sistema Operativo e
Multiprogrammazione
Il sistema operativo ha il compito di:
Gestire le risorse hardware (memoria, processori, bus, ecc.).
Garantire la protezione degli spazi di memoria, distinguendo lo spazio utente
dallo spazio kernel.
Abilitare la multiprogrammazione, caricando più programmi in memoria
centrale e alternando rapidamente la loro esecuzione.
Le interruzioni, sia hardware che software (trap ed eccezioni), sono gestite in modo
da far intervenire il kernel quando necessario per mantenere la stabilità e
l’efficienza del sistema.
Le chiamate di sistema sono il mezzo attraverso il quale il programma utente
interagisce con il kernel per accedere a funzionalità critiche (es. allocazione
memoria, operazioni di I/O).
Accesso non uniforme alla memoria o NUMA
Cluster di elaboratori (clustered systems) o cluster:
un altro tipo di sistemi multiprocessore, basati sull’uso congiunto di più CPU, ma
differiscono dai sistemi multiprocessore perché composti di due o più calcolatori
completi detti nodi collegati tra loro. (debolmente accoppiati.)
– –
Approfondimenti sulla Protezione del Sistema e Chiamate di
Sistema
Protezione della Memoria e Modalità di Esecuzione
Nei sistemi moderni, ciascun programma è eseguito in un’area di memoria isolata:
dati (statici e dinamici),
Il programma occupa zone distinte per codice,
IP (heap) stack.
e
L’isolamento impedisce a un programma di accedere alle aree di memoria di altri
programmi o alle strutture dati critiche del kernel (come la tabella degli interrupt).
Il meccanismo di protezione si basa sulla distinzione delle modalità di esecuzione:
In modalità utente, il processore limita l’accesso alle istruzioni non
privilegiate.
In modalità kernel, il processore esegue istruzioni privilegiate e permette il
controllo diretto delle risorse hardware.
Se un programma utente tenta di eseguire un’istruzione privilegiata (ad esempio,
accedere liberamente alla memoria di massa o modificare la tabella degli interrupt),
viene generata una trap che blocca l’operazione e, in casi estremi, provoca un
segmentation fault.
Chiamate di Sistema: Funzionamento e Importanza
Le chiamate di sistema costituiscono l’interfaccia attraverso cui l’utente richiede
servizi al kernel:
Un’istruzione (spesso “syscall”) trasmette il codice numerico della chiamata e i
relativi parametri.
Questa invocazione genera una trap che commuta la modalità di esecuzione da
utente a kernel.
Una tabella delle chiamate di sistema, memorizzata nello spazio kernel, contiene gli
indirizzi delle routine corrispondenti a ciascun servizio.
Esempio pratico:
Se un dispositivo genera una richiesta per accedere alla memoria di massa, il
programma utente invoca una chiamata di sistema.
Il kernel, operando in modalità privilegiata, esegue la routine corrispondente, gestisce
l’operazione e, al termine, ripristina la modalità utente.
Questo meccanismo è essenziale per garantire la sicurezza, la stabilità e l’efficienza
nell’accesso alle risorse hardware, impedendo che errori o comportamenti malevoli
possano compromettere l’intero sistema.
Ricapitolando
Sì è parlato del funzionamento della memoria durante l’esecuzione di un programma e
i meccanismi di protezione implementati dall’hardware e dal sistema operativo.
All’interno di un’area di memoria dedicata al programma, non solo è presente il codice
(la sequenza di istruzioni) che viene eseguito, ma anche le strutture dati necessarie
all’esecuzione. Quando il programma definisce una variabile, nel sorgente viene indicata
la definizione, mentre in esecuzione essa corrisponde a un indirizzo di memoria dove i
dati vengono memorizzati.
Esistono due tipologie di dati:
Dati statici: Quelli globali, per i quali il compilatore conosce la quantità di
memoria necessaria. L’allocazione è fissa per tutta la durata dell’esecuzione.
Dati dinamici: Quelli che evolvono durante l’esecuzione del programma e
vengono allocati in apposite aree (come l’heap o IP).
Oltre all’area del codice e dei dati, esiste uno stack dove vengono memorizzate le
chiamate di funzione, i parametri e le informazioni di ritorno.
Un programma non deve poter accedere alle aree di memoria di altri programmi né a
quelle del kernel, per evitare danni o errori che possano compromettere il sistema.
Il meccanismo di protezione si fonda sulla distinzione tra modalità:
Modalità utente: Consente solo l’esecuzione di istruzioni non privilegiate.
Modalità kernel: Permette l’esecuzione di tutte le istruzioni, comprese quelle
che possono alterare il sistema (come la disabilitazione degli interrupt o operazioni
I/O dirette).
Quando un programma in modalità utente tenta di eseguire un’istruzione privilegiata,
viene generata una trap. Ad esempio, se si prova ad accedere direttamente a una
porzione di memoria non autorizzata (come quella dove risiede la tabella degli
interrupt), il sistema operativo interviene, causando un segmentation fault.
Le chiamate di sistema offrono all’utente un’interfaccia sicura per richiedere servizi
al kernel, come l’accesso ai file o la gestione della memoria. Esse funzionano tramite
un’istruzione dedicata, che genera una trap e commuta la modalità di esecuzione.