La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione...

29
La memoria virtuale Tecniche di gestione della memoria nella famiglia x86 e in Os/2 A cura di Antonio Arreghini

Transcript of La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione...

Page 1: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

La memoria virtuale

Tecniche di gestione della memoria nella famiglia x86 e in Os/2

A cura di

Antonio Arreghini

Page 2: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Indice Generale

Premesse e cenni al funzionamento di un programma.........................................................................3

Capitolo 1: Tecniche per la gestione della memoria............................................................................5

1.1: La memoria reale......................................................................................................................5

1.2: La segmentazione.....................................................................................................................6

1.3: La paginazione..........................................................................................................................9

1.4: La segmentazione con paginazione........................................................................................11

Capitolo 2: La gestione della memoria sulle architetture x86............................................................13

2.1: La memoria nell'8086.............................................................................................................132.1: La memoria nell'8086.............................................................................................................132.2: La memoria nell'80286...........................................................................................................15

2.2.1: La modalità reale.............................................................................................................152.2.2: La modalità protetta........................................................................................................15

2.3: La memoria nell'80386-486-P5..............................................................................................162.3.1: La paginazione................................................................................................................172.3.2: La segmentazione............................................................................................................182.3.3: La paginazione con segmentazione.................................................................................192.3.4: La modalità V86.............................................................................................................20

Capitolo 3: La gestione della memoria in Os/2..................................................................................223.1: Os/2 a 16 bit............................................................................................................................223.2: Os/2 a 32 bit............................................................................................................................22

3.2.1: I 3 formati di indirizzi.....................................................................................................223.2.2: Primo livello di traduzione in indirizzo lineare..............................................................233.2.3: Le arene di sistema..........................................................................................................233.2.4: La Paginazione a 2 livelli................................................................................................253.2.5: La gestione delle pagine fisiche e virtuali.......................................................................263.2.6: La gestione dei moduli....................................................................................................273.2.7: Il file di pagina................................................................................................................273.2.8: L'High Memory Support.................................................................................................28

Page 3: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Premesse e cenni al funzionamento di un programma

Questo documento si propone di illustrare il funzionamento dei sistemi di indirizzamento a

memoria virtuale, con particolare attenzione alle implementazioni delle varie tecniche sui processori

x86 e a come Os/2 sfrutta queste possibilità. In ogni capitolo, per prima cosa vengono spiegati iconcetti generali, quindi vengono forniti maggiori chiarimenti di natura tecnica. Il lettore noninteressato ai «tecnicismi» può tranquillamente saltare dette parti senza pregiudicare lacomprensione grossolana dell'argomento.Per agevolare colore che non conoscono neanche in parte le nozioni che in questo documentovengono date per scontate, ho voluto scrivere le seguenti (ahimè tutt'altro che esaurienti) righe perindirizzare meglio la comprensione di un argomento piuttosto complesso.

Un programma è una sequenza ordinata di istruzioni che viene caricata nella memoria primaria (laRAM) e viene quindi ordinatamente eseguita dal processore. Il programma al suo interno contieneistruzioni (che sono i comandi che il processore deve eseguire, ad esempio somma, sottrai, carica undato...) e operandi. Queste due categorie di dati sono apparentemente indistinguibili dall'esterno,infatti si tratta semplicemente di numeri binari. Come vedremo è il processore (o meglio ilcompilatore) ad operare la distinzione: in pratica il processore legge il programma dall'iniziosupponendo che il primo dato sia un'istruzione, poi procede con i successivi dati sempresupponendo che siano istruzioni... se si arriva ad un blocco di operandi, questo dovrà esserepreceduto da un'apposita istruzione che dica alla CPU l'indirizzo della successiva istruzione.La memoria è quindi una sorta di pila di contenitori di numeri binari a 8 bit (ossia celle da 1 byte).Ogni locazione di memoria (ossia ogni «celletta di memoria») è identificata univocamente da unindirizzo, che a sua volta ovviamente è un numero. I dispositivi fisici di controllo della memoriapermettono di recuperare dati o salvarli in qualunque posizione si trovino (e per questo la memoriaè detta ad accesso CASUALE, in quanto i tempi di accesso non dipendono dalla posizione che ildato occupa).Il processore colloquia con la memoria tramite tre bus distinti o «multiplexati» (ossia «fusi» nellestesse piste) a seconda del processore stesso: questi sono il data bus, che permette di scambiare i

dati puri, l'address bus, che permette al processore di specificare su quale locazione di memoria

operare e il control bus, che permette di sincronizzare i due dispositivi, di richiedere dati, di

specificare se si vogliono effettuare letture o scritture, ecc...

Le istruzioni si classificano in tre specie fondamentali:

• Istruzioni di operazioni in memoria: il processore prima di poter eseguire qualunque operazione

deve caricare al suo interno (in cellette chiamate registri) gli operandi presenti in memoria. Ecco

quindi che servono determinate istruzioni per specificare quali dati caricare prima di ogni

operazione matematica. Queste istruzioni servono anche per movimentare dati da un posizione

all'altra, oppure per caricarli o inviarli alle periferiche (dischi fissi, scanner, stampanti, schede direte, modem, ecc...). A questo proposito va infatti detto che tali dispositivi esterni dispongono diun proprio indirizzo di memoria.

• Istruzioni matematiche: prevedono operazioni logiche e aritmetiche sui dati precaricati nei

registri del processore; se l'operazione viene compiuta su numeri interni si utilizza l'unitàdenominata ALU (Arithmetic Logic Unit) se su numeri in virgola mobile (numeri reali) entra ingioco l'unità FPU (Floating Point Unit).

• Istruzioni di salto condizionato: come detto prima in teoria l'istruzione successiva a quella inesecuzione si trova in memoria all'indirizzo immediatamente seguente all'istruzione corrente: c'è

Memoria Virtuale Pag. 3

Page 4: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

pertanto un «contatore di programma», il Program Counter, che viene incrementato al termine

di ogni istruzione e il suo contenuto di fatto rappresenta l'indirizzo dell'istruzione da caricare;questo sistema tuttavia permette strutture di programmazione estremamente elementari. È stataquindi introdotta questa classe di istruzioni che consente di caricare un nuovo valore all'internodel program counter, di fatto effettuando un «salto». Tale salto può essere incondizionato(avviene sempre) oppure condizionato (avviene se si verificano certe situazioni, ad esempio se ilcontenuto di un certo registro è minore di 0). Si possono così implementare strutture diprogrammazione molto più complesse quali i cicli e le chiamate a funzione.

La distinzione in queste 3 classi è netta solo in una architettura nota come «RISC» (ReducedInstruction Set Computer) che prevede istruzioni semplici e tutte della stessa lunghezza (ogniistruzione è lunga 16, 32 o 64 bit a seconda del parallelismo della macchina).I processori della famiglia Intel x86 (quelli su cui funziona Os/2) usano invece delle istruzioni piùcomplesse (da questo il nome di CISC, Complex Instruction Set Computer) la cui lunghezza èvariabile (da 1 a 17 byte) e la cui esecuzione prevede di «confondere» le prime due classi (ossia cisono istruzioni matematiche che specificano gli operando direttamente in memoria).Quando si parla di programmi a 16 o a 32 bit si intende quella che è la dimensione della word

standard che si adotta per quel programma: la word (detta anche parallelismo) è il numero di bit sucui il processore può lavorare in parallelo. Nella modalità a 16 bit numeri, dati e istruzioni (suiRISC) saranno in genere lunghi 2 bytes (16 bit); di conseguenza il program counter conterà a passidi 2 bytes alla volta. Il vantaggio di avere un computer a 32 bit piuttosto che uno a 16 è quello dipoter lavorare con operandi più larghi su un tempo minore. Al giorno d'oggi quasi tutti i computersono a 32 bit; i server di rete e i supercomputer sono generalmente a 64 bit.

Memoria Virtuale Pag. 4

Page 5: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Capitolo 1

Tecniche per la gestione della memoria

1.1: La memoria reale

Come visto la memoria è un contenitore di bytes: ciascuna cella ha un indirizzo univoco identificatoda una variabile a lunghezza finita. Questo vuol dire che ogni processore riesce ad indirizzare solouna quantità finita di memoria.La tecnica più antica ed intuitiva di gestione della memoria, è nota come «memoria reale». Inpratica è una non gestione della memoria, ossia gli indirizzi specificati nel programmacorrispondono sempre ad indirizzi fisici di memoria. I sistemi operativi e gli hardware chepermettono ai programmi di lavorare direttamente sulla memoria fisica sono molto antichi e moltosemplici e quindi hanno a disposizione una quantità molto limitata di memoria fisica, tanto che lastragrande maggioranza dei programmi che riescono ad eseguire richiedono più spazio di quanto siaeffettivamente presente all'interno del computer.Per fortuna accade che questa memoria ha una dimensione nota a priori e in genere sempredisponibile in toto (solo nei sistema più evoluti è possibile installare solo parte della memoriaallocabile dal processore) per cui non è complicato escogitare una soluzione: il codice essenziale delprogramma viene caricato in una parte di memoria, i dati essenziali in un'altra area; è fondamentaleche queste due sezioni riescano ad entrare completamente nella memoria disponibile (che in genereè la memoria totale installata, sottratta dello spazio usato dal sistema operativo). La parte del codicenon essenziale viene invece caricata solo quando strettamente necessaria (ossia quando ilprogramma deve eseguire quelle istruzioni); una volta terminata l'esecuzione di quel pezzo dicodice e il medesimo non è più utile, i dati essenziali vengono salvati (o aggiornati) nella zona deidati globali, quindi quel codice viene cancellato per lasciare il posto ad un'altra sezione a sua voltada caricare dal disco. L'area di memoria in cui avvengono questi processi di scambio è chiamataOverlay.

La struttura della memoria reale con overlay

Questa tecnica ha più svantaggi che vantaggi: anzitutto il caricamento da memoria di secondolivello (il disco fisso) è decisamente lento, ma questo è uno svantaggio che non si può colmare inalcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo dicaricamento viene assorbito per intero all'inizio dell'esecuzione del programma che poi procede«fluido»). In secondo luogo il compito della gestione dell'overlay è interamente sotto il controllo del

Memoria Virtuale Pag. 5

Overlay

Indir

izzi

cre

scen

ti

Area di

overlay

Dati programma

Overlay

Overlay

Sistema

operativo

Codice

programma

Memoria Disco fisso

Page 6: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

programma stesso, che deve monitorare quindi le risorse ed agire di conseguenza. In terzo luogo

questo modello non si adatta bene alla multiprogrammazione, ossia a quella pratica che prevede il

caricamento e l'esecuzione contemporanea di diversi programmi. Questi programmi ovviamentenon verranno eseguiti contemporaneamente (essendo in genere la CPU una sola): il sistemaoperativo farà lavorare a turno per pochi millisecondi ciascuno di esso, dando l'impressione che iprogrammi avanzino parallelamente. Resta però il fatto che tutti i programmi sono effettivamenteresidenti in memoria; ancora peggio, ogni programma deve essere indipendente l'uno dall'altro.Quando si lavora in memoria reale i programmi al loro interno specificano direttamente gli indirizzifisici per ogni locazione di memoria. Questo implica che più programmi possano richiedere l'usodella stessa locazione di memoria (ad esempio tutti iniziano in posizione 0000, hanno deglioperandi in 0E01 e via dicendo).Una possibile soluzione è quella di salvare in un puntatore (ossia una variabile di memoria che

contiene un indirizzo) l'indirizzo a cui inizia il programma e specificare al suo interno soltantoindirizzi relativi a questo: l'indirizzo della memoria fisica si ottiene perciò sommando al puntatorela posizione del codice da caricare relativa all'inizio del programma; questo indirizzo relativoprende il nome di offset. In realtà questa tecnica è piuttosto scomoda da implementare per ilprogrammatore (che deve programmare tenendo conto di questo fatto), è decisamente più lenta(ogni indirizzamento necessita di una somma), non permette ai programmi di espandersi (infattidopo la fine del proprio spazio può benissimo iniziare un nuovo programma) e specialmente non èsicura, infatti un indirizzo sbagliato può comportare la lettura (o peggio la scrittura) di una cella dimemoria che appartiene ad un altro programma. In altre parole è inaccettabile.

1.2: La segmentazione

Per compensare queste carenze del modello a memoria reale (che trova comunque spazio in vecchi

sistemi monoprogrammati come il DOS) è nata la cosiddetta segmentazione.Gli indirizzi di un programma non si riferiscono più ad una locazione fisica nella memoria, ma aduna «locazione virtuale». In sostanza i programmi lavorano con una memoria «teorica» (chiamatamemoria virtuale); la traduzione e la mappatura di questa memoria virtuale nella RAM delcomputer è un compito che spetta al sistema operativo ed al processore, liberando cosìdefinitivamente il programmatore dal gestire questa problematica (come invece non succedeva perl'overlay).Gli indirizzi vengono specificati come una coppia di due numeri: un selettore e un offset. Il primo

identifica il «segmento» su cui si sta lavorando, il secondo indica la posizione all'interno delsegmento stesso.

Memoria Virtuale Pag. 6

Page 7: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Un esempio di segmentazione

L'implementazione di questa tecnica necessita di un hardware apposito che agevoli la traduzione diquesti indirizzi virtuali in indirizzi fisici. In sostanza la CPU deve avere un'unità (chiamata MMU,Memory Management Unit) che all'interno deve contenere il puntatore ad un tabella dei segmenti:

all'interno di questa sono presenti una serie di voci (entry) che descrivono tutti i segmenti presenti

nel sistema. La traduzione procede automaticamente seguendo questa trafila:

• La MMU carica il selettore del segmento dall'indirizzo virtuale fornito dal programma• La MMU conosce già l'indirizzo base della Segment Table (che identifica l'inizio della

medesima) e gli somma il selettore trovando così la posizione (l'entry) nella tabella dei segmentidove è descritto il segmento in questione

• Le informazioni del descrittore del segmento contengono l'indirizzo base del segmento cui vienesommato l'offset ottenendo finalmente l'effettivo indirizzo fisico.

Tale procedimento è riassunto nella figura sottostante.

La traduzione secondo il sistema di segmentazione

Memoria Virtuale Pag. 7

Memoria

Indir

izzi

cre

scen

ti

Segmento 1

Segmento 2

Segmento 3

Libera

Libera

Selettore Offset

Indirizzo base

segment table

Indirizzo fisico

Segment table

Descrittore

Indirizzo Virtuale

+

+

B+

S

S

B

B

S'

O

S'+O

Page 8: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Un programmatore può a questo punto scrivere il codice di un programma su diversi segmenti; ilbello è che quando un programma richiede al sistema operativo di creargli un segmento di una certadimensione, il SO controlla se c'è tale spazio libero in memoria; in caso contrario luiautomaticamente copia sul disco fisso uno o più segmenti, liberando spazio in memoria fisica; tuttociò viene fatto all'insaputa del programma e del programmatore che quindi può dimenticarsi lafastidiosa gestione degli overlay e la «condivisione della memoria tra programmi» e concentrarsiesclusivamente sulla programmazione.Appena qualche programma richiederà un segmento che era stato copiato sul disco il SOprovvederà a liberare lo spazio necessario in memoria (sempre copiando altri segmenti sul disco) ea ricaricare quello richiesto; questo sempre in modo totalmente trasparente all'utente.Ovviamente il lavoro di copia è piuttosto lungo e rallenta l'esecuzione, per cui la segmentazioneprevede anche che sia installata una quantità di memoria fisica adeguata alle esigenze deiprogrammi che vengono eseguiti (per evitare di trascorrere la maggior parte del tempo a copiaresegmenti e non ad eseguire i programmi).Un altro vantaggio della segmentazione è la protezione dei dati: la CPU automaticamente controllase l'offset richiesto si trova all'interno del segmento oppure se un certo programma cerca di accederea segmenti che non gli appartengono. Se queste condizioni pericolose si verificano la CPU notificaal sistema operativo l'errore; il programma viene quindi terminato prima che possa nuocere agli altriprocessi caricati in memoria.Purtroppo non sono tutte rose e fiori. Anzitutto bisogna considerare che i segmenti hannodimensioni diverse; inserirli e toglierli dalla memoria provoca molta frammentazione, per cui si

generano tanti «buchi» in memoria difficili da riutilizzare (spesso un segmento non riesce adentrarci). Una soluzione potrebbe essere una ricompattazione periodica della memoria, ma èun'operazione lunga e costosa. Inoltre il SO deve possedere algoritmi relativamente complessi persapere qual è la posizione migliore in cui caricare un certo segmento.

Questo è un esempio di frammentazione: ci sarebbe sufficiente memoria libera per caricare il

segmento 4, ma non essendo continua non è possibile caricarlo se non ricompattando il segmento 3

oppure swappandolo su disco

Memoria Virtuale Pag. 8

Memoria

Indir

izzi

cre

scen

ti

Segmento 1

Segmento 2

Segmento 3

Libera

Libera

?Segmento 4

Disco fisso

Page 9: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Un altro svantaggio è che il copiare su disco segmenti molto lunghi richiede molto tempo; a questoproposito c'è da dire che ai programmatori non piace molto lavorare con questi segmenti, per cuicercano di far stare tutto il programma su un singolo segmento molto grande (e quindi scomodo dacopiare sul disco!); infatti quello che succede all'interno di ogni segmento è che l'offset rappresentaun indirizzo lineare: c'è a disposizione l'indirizzo 0000, il 0001 e così via per cui sono leciteoperazioni matematiche sui puntatori stessi, pratica che può sembrare poco ortodossa se fatta in unlinguaggio ad alto livello, ma è indubbiamente comoda da utilizzare (e utilizzata moltissimo nellarealtà).Un ulteriore svantaggio della segmentazione risiede nella dimensione massima del segmento:questa è necessariamente limitata dalla dimensione della memoria fisica; se uno ha 2 Mb dimemoria fisica non può caricare (neanche copiando sul disco tutti gli altri segmenti) un segmento di3Mb!In sostanza, la segmentazione porta molti vantaggi ma non risolve tutti i problemi.

1.3: La paginazione

Una soluzione a parte dei problemi si trova nella tecnica chiamata paginazione. Si tratta di dividere

lo spazio di indirizzamento lineare (è così chiamato l'insieme di tutti gli indirizzi di memoriavirtuale, lineare perché gli indirizzi sono contigui) in tante pagine di memoria; ognuna di queste èpiuttosto piccola e la dimensione è prefissata ed immodificabile. Ogni pagina rappresenta la minimaquantità allocabile dal sistema operativo. Questo sistema permette di ridurre la frammentazioneperché non ci sono «buchi troppo stretti» nei quali non si possa caricare un'altra pagina. Per caricareuna pagina in una memoria piena basta scaricarne esattamente una sola!Inoltre in questo modo è possibile che un programma sia più grande dell'effettiva dimensione fisicadella memoria, questo perché eventuali eccedenze dello stesso programma vengono compensatesemplicemente copiando su files parte di questo.

Il sistema di paginazione evita il problema della frammentazione: ogni pagina swappata entra

esattamente in ogni pagina libero in memoria

Memoria Virtuale Pag. 9

Memoria

Indir

izzi

cre

scen

ti

Disco fisso

Page 10: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

La paginazione è totalmente trasparente all'utente: non è più necessario specificare il numero disegmento (di pagina in questo caso) perché questo è insito nell'indirizzo stesso, indirizzo che vieneappunto chiamato indirizzo lineare. Siccome la dimensione della pagine è fissa ed è pari ad unapotenza esatta di 2, l'offset è costituito esattamente dagli ultimi bit dell'indirizzo lineare e il numerodi pagina è costituito dai primi bit: ad esempio in un indirizzo a 32 bit i primi 20 possonorappresentare il numero pagina e gli ultimi 12 l'offset.Il meccanismo di traduzione da indirizzo lineare a indirizzo fisico assomiglia molto a quello della

segmentazione:

• La MMU carica il numero di pagina dall'indirizzo lineare fornito dal programma• La MMU conosce già l'indirizzo base della Page Table (che identifica l'inizio della medesima) e

gli somma il numero di pagina trovando così la posizione (l'entry) nella tabella delle pagine doveè descritta la pagina in questione

• Le informazioni del descrittore della pagina contengono l'indirizzo base in memoria fisica cuiviene sommato l'offset ottenendo finalmente l'effettivo indirizzo fisico.

La traduzione secondo lo schema della paginazione

Questo meccanismo ha però anche dei punti deboli: anzitutto con dimensioni di memoria piuttostograndi è facile che si generi una page table molto grande e quindi difficile da gestire; la soluzioneper questo è quella di adottare la cosiddetta paginazione a due livelli: si tratta di dividere il numero

della pagina in due parti (ad esempio ciascuna di 10 bit): la prima parte identifica la posizione della

page table nella directory delle pagine, la seconda parte identifica il numero di pagina dentro la

page table selezionata.

Memoria Virtuale Pag. 10

Numero di pagina Offset

Indirizzo base

page table

Page table

Page table entry

Indirizzo Lineare

+

B+

P

P

B

B

P'

O

Indirizzo fisico

Page 11: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

La traduzione secondo lo schema della doppia paginazione

Un ulteriore problema è dovuto al fatto che il programmatore non avendo alcun controllo sullepagine non può imporre che parte del codice stia in certe pagine piuttosto che in altre. Succedeallora che il concetto di protezione diventa totalmente inapplicabile (pur essendoci la possibilità diassegnare una protezione ad una certa pagina).Un altro svantaggio è che la paginazione (a differenza della segmentazione) prevede un unicospazio di indirizzamento lineare creando così non pochi problemi in ambienti multiprogrammati.Anche qui esiste una soluzione che è quella di assegnare ad ogni programma una sua page table (ouna page directory); all'atto del context switching (ossia quell'insieme di operazione che il sistemaoperativo deve compiere per cambiare il processo attivo) viene caricato l'indirizzo nella MMU dellapage table corretta; in questo modo si può realizzare anche una certa protezione della memoria..

1.4: La segmentazione con paginazione

Quello che però effettivamente si usa nella maggior parte degli ambienti operativi commerciali è lacombinazione delle due tecniche per sfruttare i vantaggi dati da ognuna delle due; si utilizza infattiun sistema di segmentazione che permette ai programmi di avere quanti spazi di indirizzamentolineari desiderano; poi questi vengono paginati in modo da poter essere comodamente gestitidall'hardware. Certo che la MMU deve essere decisamente più potente e all'interno deve prevedereun'unità di paginazione e un'unità di segmentazione.

La traduzione degli indirizzi virtuali in indirizzi fisici avviene con due stadi successivi: prima si

adotta la traduzione secondo il sistema di segmentazione per passare da indirizzo virtuale a

indirizzo lineare. Poi si adotta la paginazione su questo indirizzo lineare e si arriva all'indirizzofisico.

Memoria Virtuale Pag. 11

Indice 1 Offset

Indirizzo base

page directory

Page Directory

Page dir. entry

Indirizzo Lineare

+

F+

P

P

F

F

B'

O

Indirizzo fisico

Indice 2

+ Page Table

Page table entry

B'+

P'

B'

P'

Page 12: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

La traduzione secondo lo schema della segmentazione con paginazione

La tabella sottostante riassume schematicamente le caratteristiche delle tecniche analizzate.

Overlay Paginazione Segmentazione Paginazione +

Segmentazione

Il programmatore

ne è consapevole?SI NO SI Solo della

segmentazione

Spazi linearidisponibili

Uno solo Uno solo Molti Molti

Si può superare illimite dellamemoria fisica?

SI SI NO SI

Prevede forme diprotezione?

NO NO SI SI

Perché vieneimplementata?

Per superare illimite della

memoria fisica

Per superare illimite della

memoria fisica

Creare più spazi diindirizzamento

lineari

Combinare tutti ivantaggi

Memoria Virtuale Pag. 12

Selettore Offset

Indirizzo base

segment table

Segment table

Descrittore

Indirizzo Virtuale

+

B+

SS

B

B

B'O'

Indirizzo fisico

+

Page Table

Page table entry

B''+

P

B''

O

Numero di pagina Offset'

Indirizzo lineare

Indirizzo base

page table

+

B''

P

P'

Page 13: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Capitolo 2

La gestione della memoria sulle architetture x86

2.1: La memoria nell'8086

Il primo processore della fortunata famiglia x86 di Intel è stato l'8086; si trattava di un processoreche in parte riciclava i vecchi lavori di Intel e le sue vecchie istruzioni; la base è infatti facilmentericonducibile al vetusto 4004, primo microprocessore a 4 bit della ben nota ditta californiana (eanche primo microcomputer in assoluto). Questo si è poi evoluto nell'8008 (a 8 bit) esuccessivamente nell'8080 trovando grande diffusione dentro i primi sistemi IBM. Quando IBMdecise di entrare nel mercato dei Personal Computer per fare concorrenza alla Apple, l'Intel preparòun'evoluzione a 16 bit del precedente processore, l'8086 appunto.Il fatto che il processore fosse a 16 bit implicava che la dimensione interna dei registri e del databus avessero proprio questo parallelismo. La maggior parte delle istruzioni (che erano ereditate dalvecchio sistema CISC a 8 bit) erano lunghe 16 bit, ma gli operando potevano aumentare il numerodi letture in memoria. L'address bus e il program counter erano a 20 bit e questo significava che lamassima memoria indirizzabile da questo processore era 1 Mb (un bel passo avanti rispetto ai 64KB dei vecchi 8080).Gli indirizzi venivano scritti su due parole distinte: della prima (i primi 16 bit) soltanto i 4 bit menosignificativi venivano utilizzati, i rimanenti ignorati; questi identificavano l'area di memoria su cuioperare (Intel parla di segmento di memoria, ma questa tecnica aveva ben poco a che vedere con lasegmentazione in quanto mancava ogni forma di protezione e mancava la segment table, per cui inquesto documento parleremo di aree di memoria); la seconda word rappresentava l'offset; eranoquindi possibili 16 aree di memoria da 64 Kb, per un totale di appunto 1 Mb.

Inutilizzati Area Offset

12 bit 4 bit 16 bit

Si mostra qui come venivano sfruttate le 2 parole di memoria degli indirizzi.

In realtà non tutte queste aree erano accessibili ai programmi, parte era riservata ai sistemi dicontrollo hardware ed al BIOS. In particolare le prime 10 aree (640 Kb) erano allocabili daiprogrammi e dal sistema operativo (allora il vetusto MsDOS 1) e formavano quella che fu chiamatamemoria convenzionale. Le ultime 6 aree (384 Kb) formavano la cosiddetta memoria superiore

(o anche UMB, Upper Memory Block).

Memoria Virtuale Pag. 13

Page 14: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

La figura mostra come venivano distribuite questi aree: in particolare si noti che le prime due aree

di memoria superiore erano riservate alla memoria video, le successive 3 servivano per copiare il

codice dei BIOS di sistema e della scheda video sulla RAM per accelerare la loro esecuzione (per

attivare questa copia c'è tuttora una opzione nel BIOS) e per contenere il codice di controllo deidischi fissi. L'ultima invece conteneva il sistema di controllo hardware.Questo Megabyte di memoria era necessariamente sempre presente in tutti i computer e ilprocessore non poteva funzionare in sua assenza.Col passare del tempo 1 Mb cominciava a diventare una dimensione un po' limitata, per cuioccorreva trovare un rimedio; una soluzione fu quella di inserire dei connettori sulla scheda madreper poter leggere un nuovo tipo di memoria (fisicamente diverso dal precedente) chiamato memoriaEMS (expanded memory specification, ossia memoria espansa). Così si poteva aggiungerememoria oltre il primo Mb, ma per poterla sfruttare un programma doveva utilizzare un complicatomeccanismo di allocazione che era del tutto simile alla paginazione. Non entriamo ulteriormente neidettagli, ma in questo modo era possibile espandere la memoria di 32 Mb rispetto alla dimensioneiniziale.L'8086 fu anche prodotto in una variante: l'8088. La differenza stava nel data bus, che era di soli 8bit. In questo modo si riuscì a montare l'8086 anche sulle vecchie schede madri IBM basate su8080. Per questo l'architettura x86 ebbe successo e fu adottata quasi subito. In realtà l'8088 eranecessariamente più lento perché ogni lettura da memoria andava fatta con due operazioni distinteper recuperare 8 bit alla volta dei 16 della parola.All'8086/88 seguì un nuovo processore: l'80186 (prodotto anche nella versione 80188). Questo chipsegnò un'importante lezione per Intel: oltre a piccole migliorie interne praticamente trascurabilierano state integrate nella CPU una serie di chip esterni (controllori IRQ, buffer di memoria e altrichip di servizio simili) per semplificare la circuiteria sulla scheda madre. Purtroppo così facendo lacompatibilità con l'8086 non era perfetta; questo decretò l'immediato fallimento del progetto sumercato, che vedeva il problema della compatibilità come quello principale.

Memoria Virtuale Pag. 14

Memoria

Convenzionale

Video Ram Space

Video Bios Option

Hard disk controller

ROM to RAM option

System BIOS ROM

1024 Kb

960 Kb

816 Kb

800 Kb

768 Kb

640 Kb

0 Kb

Page 15: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

2.2: La memoria nell'80286

Il successore dell'8086/88 fu chiamato 80286 e venne prodotto in una singola versione (non c'eral'80288); si prese consuetudine allora di chiamarlo semplicemente 286.La grande novità di questa CPU era la presenza di una prima unità MMU in grado di sfruttarerealmente un sistema di segmentazione. L'address bus e il program counter erano stati allargati a 24bit, di conseguenza la massima memoria installabile era 16 Mb. Ma tale tipo di memoria non erafisicamente diversa dal primo MB (come nel caso dell'EMS); era situata sugli stessi banchi, i«vecchi» moduli SIMM a 30 contatti.Poiché il DOS e tutti i suoi programmi non erano compatibili con formati di indirizzi a 24 bit, masolo a 20 bit, in teoria il DOS non poteva essere eseguito sul 286; ulteriore ostacolo stava nel fattoche il 286 non era vincolato ad avere installati tutti e 16 i MB di memoria. La soluzione fu di dotareil processore di un dispositivo per poter far funzionare la macchina in due modi diversi: la modalità

reale e la modalità protetta.

2.2.1: La modalità reale

Il sistema di modalità reale è lo stato nel quale la macchina si accende di default (anche gli attualicomputer partono nella stessa modalità reale di allora). La memoria installata viene configuratacome se si stesse usando un 8086: il primo Mb viene diviso al solito in 640 Kb di memoriaconvenzionale e 384 di memoria superiore. La memoria installata in eccesso (e non utilizzabiledirettamente con indirizzi a 20 bit) viene vista dal sistema come XMS (extended memory

specification, ossia memoria estesa). Tale memoria è utilizzabile dai programmi che la prevedono,ma tramite un meccanismo piuttosto lento e macchinoso. Non per questo restava comunqueinutilizzata, infatti con il DOS 3.3 in poi venivano forniti alcuni dispositivi che ne facevano uso:• l'himem.sys: serviva per creare nei primi 64 Kb di XMS un'area di memoria nota come HMA

(High memory area, memoria alta) nella quale si poteva caricare il sistema operativo DOS

liberando memoria convenzionale

• il ramdisk.sys: serviva per creare un «disco fisso» virtuale in memoria• lo smartdrive: era una cache per disco con caratteristiche write back che utilizzava l'XMS per

accelerare le operazioni• l'xaem86.sys (solo nel DOS 4): permetteva di emulare nell'XMS una memoria EMS in modo che

potesse essere utilizzata (tutto sommato più agevolmente dell'XMS) dai programmi che laprevedevano

2.2.2: La modalità protetta

Per fortuna però la memoria aggiuntiva poteva essere sfruttata anche in modo più dignitoso, nellamodalità protetta: veniva abilitato un sistema di memoria virtuale, comandato dall'MMU delprocessore e dal sistema operativo (occorrevano sistemi operativo che fossero compatibili, comeWindows 3.0 e Os/2). Gli indirizzi virtuali erano indirizzi segmentati nel formato 16:16 (16 bit diselettore e 16 di offset).Il selettore era fatto nel seguente modo: 13 bit di identificatore del segmento, 1 bit di selezione dellasegment table, 2 bit di RPL (Requested Privilege Level); questi ultimi servivano a definire il livellodi privilegio necessario per poter accedere a quel segmento: 00 => ring 0, 01 => ring 1, 10 => ring2, 11 => ring 3, dove il ring 0 ha la priorità massima d'accesso, il ring 3 quella minima. Il bit di

Memoria Virtuale Pag. 15

Page 16: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

selezione permette di specificare se il segmento di trova nella GDT o nella LDT: ogni processo ha

infatti a disposizione una tavola dei segmenti proprietaria (Local Descriptor Table) e condivide con

tutti gli altri processi una tavola condivisa (Global Descriptor Table) nella quale sono contenuti i

segmenti che possono essere letti da qualunque programma. All'atto del context switch il sistemaoperativo doveva caricare la LDT corretta.

Numero segmento ST RPL Offset

13 bit 1 bit 2 bit 16 bit

L'indirizzo virtuale

Di conseguenza ogni programma aveva a disposizione teoricamente 8192 segmenti da 64 Kb l'uno,per un totale di 512 Mb di memoria. La divisione del programma in segmenti era necessaria vista lalimitata dimensione dei segmenti stessi.Il 286 in questa modalità era quindi in grado di allocare 512 MB di codice condiviso e 512 MB dicodice privato; per cui ogni spazio di indirizzamento (=ogni programma) constava di 1GB almassimo.All'interno della segment table (chiamata descriptor table sui sistemi Intel) ci sono tutti i descrittoridei segmenti che includono dati quali l'indirizzo base, la lunghezza, la protezione, il DPL(Descriptor Privilege level) e la presenza o meno del segmento in memoria. Qualora la memoriafisica (che poteva contenere soltanto 16 Mb al massimo) fosse piena uno o più segmenti potevanoessere swappati su disco nello swapfile per estendere così la memoria virtuale oltre il limite diquella reale.

2.3: La memoria nell'80386-486-P5

Il processore che arrivò dopo il 286 fu chiamato 80386 o semplicemente 386. Rispetto a tutti glialtri modelli il 386 era un processore a 32 bit: possedeva nuove istruzioni a 32 bit, dati interistandard di 32 bit, larghezza dei bus interni, esterni e dei registri di 32 bit. Anche l'address bus e ilprogram counter avevano 32 bit. Era quindi possibile montare sul sistema un massimo di 4 Gb(2^32) di memoria, una quantità che tuttora è ancora lontana dall'essere raggiunta anche se si stagradualmente avvicinando.Il 386 poteva funzionare in modalità reale (con istruzioni a 16 bit), in modalità protetta (conistruzioni a 16 bit) e in modalità protetta «386» (con istruzioni a 32 bit). Un'importante novità fu poil'introduzione della modalità virtual86.

In pratica il 386 poteva emulare in pieno un 286 (anche se effettivamente era più lento di questo), inpiù introduceva questo nuovo set di istruzioni che permetteva di sfruttare il maggior parallelismo, lemaggiori quantità di memoria e le nuove potenzialità della MMU che integrava sia l'unità dipaginazione che di segmentazione.I processori successivi (486, Intel Pentium, AMD K5 e AMD K6) utilizzano questo stesso modelloe non fanno altro che migliore le prestazioni con l'introduzione della pipeline normali (nel 486) esuperscalari (dal Penitum in poi), ossia la possibilità di eseguire più istruzioni contemporaneamente.Se si eccettua l'MMX (improbabile estensione «multimediale») l'unica novità nell'instruction set staesclusivamente in 4 nuove (e quasi inutili...) istruzioni nel 486.Altri processori (gli Intel Pentium PRO, Pentium 2, 3 e 4, nonché gli AMD K6 2 e 3 e i K7 Athlon)

Memoria Virtuale Pag. 16

Page 17: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

invece introducono una serie di migliorie nelle istruzioni, aggiungendo le «istruzioni per il 3D» eaggiungendo una nuova modalità di paginazione a 4 MB (con dimensioni dell'address bus di 36 bit).Queste CPU dovrebbero in teoria essere in grado di installare 64 GB di memoria, ma in pratica nonesistono sistemi operativi sul mercato che fruttino questa nuova paginazione.La modalità protetta a 32 bit funziona in 3 diverse sottomodalità: il sistema a paginazione, il sistemaa segmentazione e il sistema a segmentazione paginata.

2.3.1: La paginazione

La paginazione permette di applicare la tecnica che abbiamo già visto su uno spazio diindirizzamento lineare di 4 Gb. I programmi possiedono indirizzi a 32 bit che vengono paginati dalsistema con pagine grandi 4 Kb.Sarebbe perciò possibile che ogni programma teoricamente potesse disporre di 4 Gb lineari; unapage table proprietaria di quel programma potrebbe essere caricata dal sistema operativo (all'atto delcontext switch) nella MMU; purtroppo c'è una limitazione: le parti del «codice condiviso» nonchéla zona del sistema operativo devono essere SEMPRE visibili (per chiamate a sistema, ecc...). Diconseguenza parte dello spazio di indirizzamento viene destinato esclusivamente a questo scopo; lepage tables che mappano tale area non subiscono sostituzione. Questo ovviamente riduce anche lospazio disponibile per il singolo programma.

Ad ogni context switch vengono attivate diverse Page Tables per mappare la parte dell'indirizzo

lineare privata. La parte condivisa invece non subisce la sostituzione delle page tables

Per gestire in modo efficiente la memoria, il 386 prevede la paginazione a due livelli: i primi 10 bit

dell'indirizzo lineare identificano all'interno della page directory l'indirizzo della page table dacaricare. Ogni entry nella page directory è lunga 4 byte (indirizzo fisico della page table) per cui ladimensione totale della page directory è di 4 K. I secondi 10 bit dell'indirizzo identificano la paginarichiesta all'interno della page table selezionata; anche qui ci sono 4 byte per pagina e quindi unapage table è grande 4 Kb: in altre parole occupa esattamente una pagina di memoria, per cui è facileswappare anche le page tables qualora la situazione lo richiedesse. Come sempre gli ultimi 12 bitrappresentano l'offset dentro la pagina selezionata.Da notare che nella page table solo 20 bit servono ad identificare l'indirizzo base della pagina (chedi fatto differisce ogni volta di 4 Kb); gli altri 12 bit sono utilizzati per ulteriori informazioni sullapagina: ad esempio indicano il PPL (page privilege level, ossia i privilegi che un programma deveavere per poter accedere al contenuto di quella pagina), il permesso di solo-lettura/scrittura, lapresenza della pagina in memoria oppure nello swapfile, il tipo di pagina (di programma, di sistema

Memoria Virtuale Pag. 17

Codice condiviso

Programma 1

Programma 2

Programma 3

Spazio di indirizzamento lineare attivo

Page tables

attive

Page tables

inattive

Page tables

inattive

4 Gb O

Page tables

Page 18: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

operativo), il permesso di poter copiare sul disco quella pagina (alcune pagine non possono essere

swappate, come quelle del sistema operativo), ecc...

Prima di caricare una pagina un'opportuna unità della CPU (l'unità di protezione e test) controllaquesti dati. Se si verifica una violazione questa viene notificata attraverso un apposito interrupt alsistema operativo che può così prendere le sue precauzioni.Da notare che lo spazio di indirizzamento di ogni singolo programma è quindi di 4GB, ma in talespazio deve risiedere anche il codice condiviso. Per comodità quello che molti sistemi operativifanno è quello di utilizzare 2 page directory: entrambe mappano gli stessi 4GB di memoria, ma laprima contiene solo le pagine di codice condiviso e la secondo di codice privato. Il context switch siriduce quindi a dover sostituire questa seconda page directory.

2.3.2: La segmentazione

La funzione di segmentazione è analoga a quella vista per il 286, ma più potente: questa voltal'offset è di 32 bit, ossia con la segmentazione gli indirizzi virtuali sono composti da addirittura 48bit (16 di selettore e 32 di offset).Ogni descrittore di segmenti nelle descriptor tables è composto da 64 bit (8 bytes): 32 di questivengono utilizzati per identificare l'indirizzo base del segmento, 20 la dimensione, 1 identifica se sista utilizzando la paginazione a 4 Kb (vedi in seguito); 2 bit sono il DPL (descriptor privilege level,che specifica quale ring ha accesso all'oggetto),1 bit descrive se si tratta di un segmento di sistemaoperativo o di programma, 1 se il segmento è presente in memoria, uno definisce la dimensionedegli operandi, gli altri 3 definiscono la politica di lettura e scrittura per il segmento. Vedi anche lafigura sottostante.La protezione della segmentazione è quindi più completa di quella della paginazione. Tuttaviaquesta modalità non viene usata così com'è da alcun sistema in commercio.

Limite

(Prima parte)

Base

(prima parte)

S, Tipo,

DPL, P

Limite Flag Base

16 bit 24 bit 8 bit 4 bit 4 bit 8bit

Il descrittore del segmento per l'Intel 386

Legenda:

Limite: diviso in due parti (tra i bit 0 e 15 e tra il 48 e il 51) indica la lunghezza del segmento

Base: divisa in due parti (tra i bit 16 e 39 e il 56, 63) è l'indirizzo fisico a 32 bit di partenza del

segmento.

S: (bit 44) Tipo di segmento, 0=di sistema, 1=di applicazione

Tipo: (bit 40->43) bit 40: 0=non acceduto, 1=acceduto

A seconda del bit 44, ci sono diversi significati per i bit 41->43, oggetto dati/codice, espandibilità

in alto/basso, Read-only/read-write, solo-esecuzione/lettura-esecuzione. In caso di un segmento di

sistema: LDT, TSS, Call Gate, Interrupt Gate, ecc...

DPL: (bit 45-46) Descriptor Privilege Level Descrive quale ring ha accesso all'oggetto.

P: (bit 47) Presente, 0=segmento non presente, 1=segmento presente

Flag: (bit 52-55) bit 52: usato dagli oggetti UVirt; bit 53: dimensione degli operandi 0=16 bit,

1=32 bit; bit 54: grandezza degli indirizzi 0=16 bit, 1=32; bit 55: 0= il limite è espresso in bytes,

1= il limite è espresso in pagine da 4 Kb.

Memoria Virtuale Pag. 18

Page 19: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Usando la sola funzione di segmentazione è quindi possibile avere per ogni programma 32 TB dimemoria, più altrettanti sempre disponibili per il codice condiviso. Il context switch non fa altro chesostituire la LDT.

2.3.3: La paginazione con segmentazione

Si tratta della variante più potente del precedente schema a segmentazione e rispecchia in tutto e pertutto quanto già espresso in precedenza. Come visto nei descrittori dei segmenti si può specificareche il segmento sia paginato: questo non solo permette di avere segmenti da 4 Gb, ma permettespecialmente di attivare la paginazione all'interno del segmento.Dai 48 bit di indirizzo virtuale viene ricostruito uno spazio di indirizzamento lineare a 32 bit, chepoi viene paginato con le tecniche già viste della paginazione a 2 livelli. Questo sistema permette dicombinare il meglio delle due tecniche: la protezione avviene sia a livello di segmenti che dipagine, il programmatore ha teoricamente a disposizione più spazi di indirizzamento (se usa ancheil selettore) oppure può accontentarsi di un solo segmento evitando di specificare il selettore. Èpossibile usare segmenti con programmi a 16 bit e a 32 bit; nonché segmenti ii modalità virtuale(vedi sotto).Permangono però delle limitazioni: anzitutto l'hardware di paginazione prevede spazi diindirizzamento di soli 4 GB e non di 64 TB come prevedeva la segmentazione pura. Questo puòconsiderarsi irrisorio viste le comunque generose dimensioni di cui si parla, ma è pur sempre unalimitazione. Come se non bastasse i segmenti della GDT (ossia quelli che devono essere vistisempre e da tutti i programmi) devono essere mappati in tutti gli spazi lineari; per cui in effetti unprogramma non può struttare nemmeno tutti e 4 i GB messi a disposizione. Anzi, più codicecondiviso c'è e meno spazio resta per il codice proprietario.La figura sotto riassume gli aspetti della paginazione con segmentazione nel 386.

Memoria Virtuale Pag. 19

Page 20: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

2.3.4: La modalità V86

Uno dei limiti introdotti con la modalità protetta nel 286 era quello di non poter eseguire alcunprogramma DOS (né il DOS stesso) quando questa era attiva. Ciò creava diversi fastidi in quanto iprogrammi erano limitati a 640 Kb, l'accesso all'XMS era difficoltoso e sotto Windows non erateoricamente possibile eseguire programmi DOS se non interrompendo il multitasking.Una soluzione venne con il 386, il quale era in grado di creare all'interno di un segmento specialedella modalità protetta una macchina virtuale dos (VDM, Virtual Dos Machine); il processore pereseguire quel segmento entrava nella cosiddetta «modalità Virtual 86»: all'interno del segmentoveniva ricostruita (in realtà emulata) la struttura classica della modalità reale ed era così possibileeseguire la maggior parte dei programmi DOS.Il primo ambiente a sfruttare questa possibilità fu Windows 3.0 se fatto partire con il comando win

/386, che abilitava la cosiddetta «modalità 386 avanzata»; al suo interno era quindi possibilecaricare programmi DOS.Anche il DOS stesso con la versione 5 abilitò un particolare supporto per lavorare sui 386: il driveremm386.exe. Questo permetteva di portare la macchina in modalità protetta e di creare un segmento

Memoria Virtuale Pag. 20

Page 21: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

VDM; il vantaggio di ciò era la possibilità di avere un controllo molto maggiore della memoriastessa e di poter caricare i driver e i TSR in memoria superiore liberando spazio in memoriaconvenzionale. Un altro gestore di memoria molto comune era il qemm386, una versione ancora piùavanzata che permetteva anche di estendere la memoria HMA a 384 Kb e sfruttarla per caricarcisopra tutto quanto non ci stava nell'UMB.

Memoria Virtuale Pag. 21

Page 22: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Capitolo 3

La gestione della memoria in Os/2

3.1: Os/2 a 16 bit

La prima versione di Os/2 realizzata da IBM e Microsoft per fornire un'alternativa valida allapietosa accoppiata DOS+Windows era nata per poter essere eseguita sui processori 286. Era quindibasata su un codice a 16 bit e i programmi che poteva eseguire erano a loro volta a 16 bit. Perfornire la Crash Protection e gestire al meglio l'ambiente multiprogrammato Os/2 usava ovviamentela modalità protetta. Una parte del kernel denominata Memory Manager si occupava di colloquiarecon la MMU e di gestire le segment tables.In accordo con le specifiche del 286 il sistema di segmentazione prevedeva 2 segment table (tabelledei descrittori) per processo, la GDT e la LDT. Nella prima erano contenuti i segmenti che eranovisibili da tutti i programmi (fino ad un massimo di 8192 segmenti) e in essi venivano caricate leDLL condivise, il kernel e i dispositivi del sistema operativo, nonché gli IFS e le cache per il disco.Tale codice funzionava a ring 0 ed aveva quindi il massimo del controllo su tutto il sistema.Ogni programma aveva la sua LDT, lista che specificava tutti i segmenti allocati dalla singolaapplicazione; ogni LDT ovviamente era a sua volta un'entry della GDT ed era protetta in modo chesolo il sistema operativo potesse averne l'accesso in scrittura. Il codice applicativo girava a ring 3,per cui aveva il minimo dei privilegi di accesso e di fatto non poteva colloquiare direttamente conl'hardware (a dire il vero c'erano alcuni moduli nel sistema a ring 2 i quali potevano avere accessodiretto all'hardware).Quando la memoria fisica era piena veniva utilizzato uno swapfile e i segmenti meno utilizzativenivano scaricati su disco; quando un programma li tornava a richiedere questi venivano ricaricatiin memoria.

3.2: Os/2 a 32 bit

Con l'avvento dei processori 386, IBM (la Microsoft aveva abbandonato il progetto per dedicarsi aWindows e a Windows NT) creò la prima versione a 32 bit del suo Os/2, che di fatto fu il primosistema operativo a 32 bit sull'architettura x86. La versione 2.0 manteneva la compatibilità con ilvecchio formato di programmi a 16 bit e inoltre sfruttava la modalità virtual 86 per poter eseguireanche programmi DOS e Windows al suo interno. Per fare tutto questo il sistema sfruttava (e sfruttatuttora) la modalità protetta a 32 bit nella versione «segmentazione con paginazione».

3.2.1: I 3 formati di indirizzi

Os/2 32 bit supporta 3 diversi formati di indirizzi all'interno di un programma:• Il formato 16:16 -> 16 bit di selettore e 16 di offset, è il formato di indirizzo virtuale usato dai

programmi a 16 bit per Os/2; ci sono alcuni moduli del sistema che per necessità o limitazionesono ancora a 16 bit, anche questi adottano tale formato. Ad ognuno di questi programmi èassegnata una specifica LDT in modo da poter emulare le funzioni di segmentazione pura.

• Il formato 16:32 -> 16 bit di selettore e 32 di offset, è il nuovo formato di indirizzo virtualepossibile in Os/2 a 32 bit. Le parti interne a 32 bit del sistema operativo specificano sempre il

Memoria Virtuale Pag. 22

Page 23: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

loro indirizzo in questo formato; trattandosi di elementi strutturali del sistema (e quindi globali)

non è necessario assegnare loro una LDT.• Il formato 0:32 -> 0 bit di selettore e 32 di offset. È stato ritenuto che difficilmente si sarebbero

visti programmi di dimensione superiore a 4 Gb; inoltre ai programmatori non è mai piaciutolavorare su segmenti multipli, per cui avendo a disposizione uno spazio di indirizzamento da 4Gb avrebbero comunque scritto i loro programmi per un unico segmento. Ecco quindi cheprevedendo questa esigenza (che invero si concretizza in tutti i sistemi operativi per personalcomputer) è stato deciso che i programmi a 32 bit dovessero avere un unico segmento. La LDTcontiene quindi un descrittore di un unico segmento la cui dimensione è variabile ma il cuiindirizzo base è sempre 0. Questo indirizzo virtuale «implicito» non necessita quindi di venirtradotto in indirizzo lineare, in quanto tale traduzione darebbe come risultato l'offset stesso. Seda un lato questa scelta comporta la perdita della maggior parte dello spazio virtuale diun'applicazione (che potrebbe essere 8192 volte maggiore), rappresenta un buon compromesso intermini di velocità (si salta la prima traduzione, o meglio è implicita) e permette di risparmiarespazio in quanto si codificano gli indirizzi come soli 32 bit e non come 48 bit. Certamente peròper accedere ad un segmento del sistema operativo (di memoria condivisa) occorre specificarel'indirizzo a 48 bit completo.

È possibile passare facilmente dal formato 16:16 al formato 0:32 semplicemente shiftando alcunibit, mentre la conversione inversa necessita di una somma e di una moltiplicazione.

3.2.2: Primo livello di traduzione in indirizzo lineare

La traduzione da indirizzo virtuale in formato 16:32 e 16:16 segue fedelmente gli schemi già vistoper la segmentazione nel 386: all'interno del processore viene caricato l'indirizzo base della GDT edella LDT (questo cambia ad ogni context switching). Il selettore identifica la posizione dentroqueste due tabelle del descrittore del segmento attivato. Identificato il descrittore avvengono unaserie di operazioni di controllo: anzitutto si verifica che l'offset sia minore della massimadimensione specificata in quel segmento, quindi si controlla che l'RPL dell'indirizzo attualmenteattivo in memoria abbia privilegi sufficienti (sia ad un ring minore o uguale) a quello specificato nelcampo DPL del descrittore. Poi si verificano le flag read-only/read-write per sapere se è possibilescrivere su dato segmento oppure soltanto leggere. Se i controlli non vanno a buon fine si genera un«segment fault» (detto anche trap D) che viene notificato al sistema operativo, e Os/2 non può faraltro che terminare il programma che ha causato il problema; se invece i controlli passano l'offsetdel segmento viene sommato all'indirizzo base. In questo modo si può determinare l'indirizzolineare univoco.Le applicazioni a 32 bit non ammettono più di un segmento per applicazione, il che significa chenon possono avere più di una singola voce nella LDT. Di questa voce molti dei campi sonostandard: un'applicazione viene eseguita a ring 3, ha sempre i permessi di scrittura da parte dellostesso ring negati, ha sempre lo stesso indirizzo base (00000000) ed è sempre paginata; cambia solola lunghezza del segmento: di default ai programmi vengono assegnati segmenti di 64 MB, maquesto segmento può crescere in dimensioni su richiesta dell'applicazione stessa.

3.2.3: Le arene di sistema

Come accennato in precedenza il 386 prevede la mappatura obbligatoria nello spazio di

indirizzamento lineare del codice contenuto nella GDT perché questo sia disponibile per tutte le

Memoria Virtuale Pag. 23

Page 24: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

applicazioni. È pertanto necessario riservare alcuni indirizzi in ogni spazio di indirizzamento (ogniapplicazione ne ha uno diverso) per questi segmenti. Per un problema di compatibilità con iprogrammi a 16 bit (che come abbiamo visto non potevano indirizzare più di 512 MB di memoria) èstato imposto che il limite allocabile dalle singole applicazioni fosse appunto 512 MB. Lo spaziosopra questo limite (ossia da 512 Mb a 4 Gb) è riservato per i segmenti di sistema.Os/2 gestisce queste problematiche introducendo dei controllori d'area, chiamati arene. Os/2 lavora

con 3 arene distinte: l'arena privata, l'arena condivisa e l'arena di sistema. La prima contiene tuttoil codice proprietario del programma attivo e ad ogni context switch quella parte viene riallocata(come vedremo) attivando diverse page directories. L'arena condivisa contiene tutto il codice

accessibile dalle applicazioni che deve essere visibile da parte di tutti i programmi: in sostanza si

tratta delle DLL di sistema che vengono tutte caricate in questa zona. L'arena di sistema contiene

invece tutto il codice del sistema operativo; le applicazioni non possono utilizzare dato codice per

cui è stato scelto di mapparlo sopra il limite dei 512 MB. L'arena condivisa e di sistema sono ilrisultato della mappatura dei segmenti della GDT nella memoria lineare e quindi non sono soggetteal cambio delle page directories. Poiché i programmi devono necessariamente poter accedereall'arena condivisa (oltre che a quella privata) le due arene convivono entrambe al di sotto del limitedei 512 Mb.In particolare l'arena privata inizia all'indirizzo lineare 0000000 (anche se i programmi Os/2 nonpossono allocare dati nei primi 64 Kb di memoria) e termina di default a 64 Mb. L'arena condivisainizia all'indirizzo lineare corrispondente a 304 MB e termina a 512 MB. La zona compresa tra 64Mb e 304 Mb è una zona di espansione: l'arena privata si espande verso l'alto su richiesta deiprogrammi, l'arena condivisa si espande verso il basso quando si richiede il caricamento di ulteriorilibrerie.Da questo si deduce che prima o poi le due arene andranno in conflitto: il limite inferiore dell'arenacondivisa rappresenta la massima memoria allocabile dalla singola applicazione e oltre quel limite ilsistema operativo non autorizza l'accrescimento ulteriore del programma dichiarando di averesaurito la memoria; in realtà la memoria non è affatto esaurita (nel qual caso verrebbesemplicemente allargato il file di appoggio sul disco fisso) sono esauriti gli indirizzi lineari.Analogamente se c'è almeno un programma caricato nel sistema che alloca memoria fino al limiteconsentitogli, non è più possibile allargare l'arena condivisa (ossia caricare altre DLL), altrimentiquesta sconfinerebbe (anche se soltanto in quel contesto di programma) nell'arena privata. Di fattoquindi la massima dimensione del singolo programma sotto Os/2 è di circa 300 Mb in condizioni diutilizzo normale.L'arena di sistema invece utilizza come indirizzo base 1.5 Gb e termina praticamente a 4 Gb (c'èuna piccola area riservata attorno a tale limite). Tra 512 Mb e 1.5 Gb c'è una parte della memorianon mappata e riservata per utilizzi futuri.

Memoria Virtuale Pag. 24

Page 25: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

La figura mostra la configurazione ad arene della memoria lineare

3.2.4: La Paginazione a 2 livelli

Lo spazio di indirizzamento lineare viene mappato in memoria fisica attraverso la tecnica della

paginazione a due livelli. In Os/2 per comodità si fa uso di 2 page directory separate: la SPD(System Page Directory) che mappa l'arena di sistema, e la PPD (Process Page Directory) chemappa l'arena privata e l'arena condivisa; a dire il vero a partire dalla versione «Warp 3» l'arenacondivisa è mappata dalla SPD ad eccezione delle pagine marcate come «Read-Write».Come è facile intuire ogni processo ha la sua PPD che viene sostituita all'atto del context switch.Le page directory sono costituite dalle cosiddette PDE (Page Directory Entry) che contengono i datiidentificativi della page table a cui puntano come specificato in precedenza. Le page table hannouna struttura analoga alla page directory.Anche sulle pagine sono definiti dei privilegi di accesso e il controllo Read-Write/Read-Only chesono ereditati da quelli impostati a livello del relativo segmento. Qualora si verificasse unaviolazione di questi permessi il processore notifica il problema al sistema operativo, errore che èchiamato «Page Fault» (detto anche Trap E). Da notare che il page fault va analizzato con piùattenzione da parte del sistema operativo: è infatti possibile che l'operazione fosse corretta, ma lapagina si trovasse sul disco fisso e non in memoria; in tal caso sarà compito del sistema operativorecuperare tale pagina prima di far proseguire l'esecuzione del programma. Qualora invece l'erroresia effettivamente un errore, il programma viene di norma terminato.

Memoria Virtuale Pag. 25

Arena privata

PID 1

Arena privata

PID 2

Arena privata

PID 3

Area di

espansione

Arena condivisa

Riservata per

usi futuri

Arena di

sistema

4 Gb

1.5 Gb

512 Mb

304 Mb

64 Mb

0

Page 26: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

3.2.5: La gestione delle pagine fisiche e virtuali

Per accelerare la gestione della memoria da parte del sistema operativo, Os/2 utilizza altre tre

tabelle:

• La VPT (Virtual Page Table): ogni pagina allocata nel sistema da qualunque programma viene

registrata in questa tavola

• La PFT (Page Frame Table): contiene una voce per ogni pagina indirizzabile di memoria fisica;

se la pagina è utilizzata allora la relativa voce conterrà un puntatore alla page table entry chemappa tale pagina

• La PRT (Page Range Table): contiene una lista della pagine che possono essere indirizzate

Nel sistema esistono fondamentalmente due tipi di pagine: pagine fisiche che corrispondono a 4 Kb

di RAM in memoria centrale e pagine virtuali che rappresentano 4 Kb di memoria allocati per

qualsiasi ragione dal sistema operativo.

Ogni pagina di memoria fisica (ossia tutte quelle che hanno la propria entry nella PFT) si puòtrovare nei seguenti stati:• Free: la pagina non è attualmente in uso da alcuna applicazione• Attached: la pagina è allocata dal sistema, ossia una PTE (un elemento di una page table) punta a

tale area di memoria. Ci sono 3 sottostati possibili:• Swappable: la pagina può essere salvata sullo swapfile• Locked: la pagina è momentaneamente in uso da un Device Driver e temporaneamente deve

restare in memoria• Resident: La pagina deve rimanere in memoria per tutto il tempo, non può essere copiata sullo

swapfile• Idle: La pagina non è stata usata di recente. Ci possono essere due sottostati:

• Dirty: la pagina è stata modificata rispetto all'ultimo (eventuale) salvataggio su disco e deveessere risaltata prima di essere cancellata

• Clean: la pagina non ha subito modifiche rispetto all'ultimo salvataggio per cui può esseretranquillamente cancellata

Per quanto riguarda invece le pagine virtuali (ossia tutte quelle che hanno la propria entry nellaVPT) esistono i seguenti stati possibili:• Free: la pagina non è stata allocata• Decommitted: la pagina è stata «prenotata» ma non è ancora in uso• Committed: la pagina è in uso e sono possibili i seguenti sottostati:

• Guard: uno stato utilizzato dagli stack dei programmi

• AOD: Allocated On Demand, ossia non ci sono ancora scritti i dati all'interno (appena unapagina diventa committed entra in questo stato)

• TBL: To Be Loaded, ossia la pagina deve venire caricata da un files presente sul disco

• Present: identifica che la pagina è normalmente in uso• Idle: la pagina non ha ricevuto accessi da diverso tempo; la pagina ritorna nello stato present

dopo il suo utilizzo

• Swapped: la pagina si trova fisicamente sul disco

Memoria Virtuale Pag. 26

Page 27: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

Diagramma di Venn della memoria: l'ellisse di destra rappresenta la Memoria Virtuale, quella di

sinistrala Memoria Fisica; l'intersezione è la memoria fisica utilizzata.

3.2.6: La gestione dei moduli

Un modulo in Os/2 è qualunque entità indipendente; generalmente un modulo può essere vistocome il codice contenuto in ogni segmento allocato all'interno del sistema operativo. Alcuni moduliappartengono al sistema operativo e possono essere il kernel stesso, ogni device driver, i drivervirtuali, la cache, ecc... altri moduli appartengono chiaramente all'arena condivisa, tipicamente leDLL; i moduli utente sono generalmente chiamati processi (task in altri sistemi operativi) e sono ineffetti i programmi in esecuzione. Tutti i moduli caricati nel sistema sono registrati in un'appositatabella chiamata MT (Module Table).Ad ogni programma che si carica viene assegnata un'area di memoria chiamata PTDA (Per TaskData Area) che contiene tutte le informazioni di carattere «amministrativo» del processo stesso:ogni PTDA contiene il PID (Process ID, identificativo univoco del processo), il PPID (Parent PID,ossia il PID del processo da cui è stato generato, e teoricamente l'unico processo che può invocarnela terminazione), la lista delle risorse allocata, informazioni sui semafori, le DLL utilizzate, ilpuntatore alla MTE (Module Table Entry) per quel processo, il nome del processo stesso (cheusualmente è quello del file eseguibile eseguibile da cui è stato generato), informazioni sulconcatenamento tra i gestori delle arene, l'indirizzo base della PPD (Process Page Directory) ilriferimento alla LDT e alla GDT (la PTDA è puntata da un elemento della GDT) nonché una seriedi informazioni vitali aggiuntive per il processo stesso.

Ricapitolando: ogni «oggetto di memoria» allocato comporta:8 byte -> nelle DTE (Entry nella GDT o LDT)4 byte * numero delle pagine dell'oggetto -> nella PTE (Page Table Entry) 12 byte * numero totale delle pagine in RAM -> per un Page Frame Record (una entry della PFD)12 byte * numero delle pagine dell'oggetto -> nella VPT

3.2.7: Il file di pagina

Come abbiamo visto il Memory Manager di Os/2 lavora su un file (che si chiama swapper.dat) nel

quale il sistema operativo può salvare pagine provenienti dalla memoria per poter permettere diallocare più memoria virtuale di quanta memoria fisica sia effettivamente installata.Questo swapfile ha una dimensione iniziale che viene settata nel comando menman del config.sys di

Os/2 ma ovviamente non è limitato a tale dimensione: può accrescere qualora occorra edeventualmente restringersi; il motivo di assegnarli una dimensione iniziale è quello di ridurre iltempo perso dal sistema operativo stesso ad accrescerlo o a rimpiccilirlo, operazione che viene fatta

Memoria Virtuale Pag. 27

Dec

om

mit

ted

Free

AOD

TBL

Sw

apped

Swappable

Resident

Idle

Memoria Fisica Memoria Virtuale

Page 28: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

il meno possibile e con incrementi di 1 Mb; inoltre al boot il sistema operativo cerca di costruire

uno swapfile il più possibile contiguo per ridurre il tempo di ricerca al suo interno; quando il file siridimensiona non è detto che trovi dello spazio contiguo, il che prelude ad un decremento dellavelocità e di efficienza.La dimensione massima del file di scambio è limitata a 2 Gb, questo per una limitazione dellepartizioni HPFS che non potevano gestire files più lunghi di 2 Gb. Ora con il JFS la limitazione èscomparsa, ma non la flag nel memory manager per cui tuttora la massima memoria swappabile è 2Gb (per l'esattezza ci sono solo 31 bit per identificare la posizione sul disco nelle VPE, virtual pageentry).Quando una pagina viene copiata sullo swapfile e rimossa in memoria, la relativa page table riportal'avvenuta copiatura e non identifica più l'indirizzo base in memoria, bensì crea un puntatore alrelativo oggetto della VPT; tale oggetto (ossia una VPE) conterrà la posizione fisica in cui la paginaviene salvata nello swapfile.È interessante notare che già quando una pagina di memoria passa in stato idle, la sua PTE già nonpunta più alla pagina in memoria fisica, bensì alla relativa entry nella VPT: questa punterà ancora inRAM (e non sul disco fisso) fintanto che la pagina non verrà scaricata dalla memoria.Le pagine swappate sul disco vi rimangono fintanto che il programma a cui appartengono coninterrompe la sua esecuzione: a dire il vero anche oltre la terminazione, in quanto la rimozione dellesuddette è un'operazione che viene fatta nei «tempi morti» in modo da non appesantire inutilmenteil sistema stesso; ecco perché in situazioni di grande utilizzo dello swapfile, la chiusura di unprogramma non corrisponderà ad un immediato decremento delle dimensioni del file, anzi ad unpossibile incremento qualora ci siano altri programmi che stiano utilizzando attivamente lamemoria.Una pagina ricaricata mantiene le informazioni nella VPT sulla sua posizione nello swapfile;qualora questa debba venir rimossa nuovamente dalla memoria, va a sostituire la precedentescrittura solo se è stata modificata, altrimenti viene semplicemente cancellata per risparmiaretempo. Questo sistema però comporta notevoli dimensioni del file di scambio che (almeno a livelloteorico) potrebbe crescere fino a che tutti i programmi attivi non vengono swappati.Il gestore del file di scambio (che è a sua volta un componente del kernel di Os/2) tende a farrimanere lo swapfile entro i limiti della dimensione iniziale: una volta che questa è esaurita, vieneingrandito a blocchi di 1 Mb; periodicamente, negli idle time del sistema, avviene unadeframmentazione del file stesso, ossia le pagine salvate oltre la dimensione iniziale tendono a venirspostate in eventuali «buchi» presenti nelle posizione precedenti. Qualora lo swapfile avesse più di2 Mb liberi in fondo ad esso, la sua dimensione verrebbe ridotta di 1 Mb e questo fino a raggiungerela dimensione iniziale. È questo un ulteriore motivo per cui è opportuno scegliere con «saggezza»tale dimensione iniziale, visto che queste elaborazioni (allargamenti, deframmentazione,rimpicciolimenti, ecc...) causano notevoli rallentamenti.

3.2.8: L'High Memory Support

Come si è detto nelle sezioni precedenti ogni programma ha a disposizione all'incirca 300 Mb dimemoria. Questa quantità, malgrado fosse soltanto il 7% della memoria effettivamente allocabiledagli indirizzi lineari a 32 bit, era pur sempre una quantità considerevole e fino a qualche anno fapiù che sufficiente per tutti i programmi.Recentemente c'è stata una forte spinta verso l'occupazione «smodata» della memoria ed ecco che

Memoria Virtuale Pag. 28

Page 29: La memoria virtuale - eComStation . it · 2012-10-28 · alcun modo se non aumentando la dimensione della memoria fisica (in questo caso il tempo di caricamento viene assorbito per

300 Mb potrebbero essere considerati un limite eccessivamente piccolo. A partire dalla versione

Warp Server Advanced for SMP e nelle successive WSeB, ACP, MCP ed eComStation, il kernel di

Os/2 riesce a gestire altre due arene di memoria. Questa tecnologia è stata chiamata HMS e le duearene sono la High Shared Arena e la High Private Arena (arene condivise e private «alte»). Con unapposito comando del config.sys è possibile specificare l'indirizzo di partenza dell'arena di sistema(il comando è il virtualaddresslimit) di fatto riducendo la dimensione dell'arena di sistema; il limitemassimo di questo valore (chiamato virtual address space) è 3 Gb. Tra 0.5 Gb e 3 Gb (o il valoreimpostato) si forma così un nuovo spazio di indirizzamento che viene mappato dalle due nuovearene. Di fatto si forma un sistema speculare a quello che succede sotto i 512 Mb: c'è un indirizzo dipartenza sopra al quale (e fino al virtual address space) si estende l'arena condivisa alta. Da 512 Mbfino a dato valore si estende invece l'arena privata alta. I programmi che ne fanno richiesta possonoandare a caricare DLL e codice operativo in queste due aree, estendendo di fatto il loro spazio diindirizzamento fino a 3 Gb (in realtà contando le arene condivise lo spazio si riduce circa a 2.5 Gb,comunque una quantità estremamente grande, superiore a quelle degli altri sistemi operativi, qualiLinux e Windows).La figura sottostante riassume il comportamento della memoria con l'HMS attivo. È importantenotare che SOLTANTO i programmi che la prevedono possono utilizzare la nuova arena alta. Ilmotivo per cui evitare di ridurre eccessivamente la dimensione dell'arena di sistema è la riduzionedel numero di processi totali caricabili dal sistema operativo.

La configurazione delle arene con abilitata la funzione HMS

Memoria Virtuale Pag. 29

Arena privata

PID 1

Arena privata

PID 2

Arena privata

PID 3

Area di

espansione

Arena condivisa

Arena privata

alta

PID 1

Arena di

sistema

4 Gb

Virtual address

limit

512 Mb

304 Mb

64 Mb

0

Arena condivisa

alta

Arena privata

alta

PID 2

Arena privata

alta

PID 3

Limite variabile