Memoria centrale

annuncio pubblicitario
Sistemi Operativi
Docente: Ugo Erra
Docente:
Ugo Erra
[email protected]
8° LEZIONE
M E M O R I A C E N T R A L E – 1 ° PA R T E
C O R S O D I L A U R E A T R I E N N A L E I N I N F O R M AT I C A
U N I V E R S I TA
TA’ D E G L I S T U D I D E L L A B A S I L I C ATA
Sistemi Operativi 2007/08
Sommario della lezione
y Introduzione
I t d i
y Associazione degli indirizzi
y Indirizzi logici e indirizzi fisici
y Uso delle librerie
y Avvicendamento delle librerie
y Allocazione della memoria
Allocazione della memoria
Sistemi Operativi 2007/08
Introduzione
y Nei moderni Sistemi Operativi la gestione della memoria N i
d i Si t i O
ti i l
ti
d ll
i
è un aspetto fondamentale per la realizzazione della multiprogrammazione poiché più processi attivi devono
multiprogrammazione poiché più processi attivi devono essere presenti in memoria
y Lo scopo del Sistema Operativo è di allocare la memoria L
d l Si t
O
ti è di ll
l
i
per i processi da mandare in esecuzione in modo che siano pronti quando la CPU gli viene assegnata
siano pronti quando la CPU gli viene assegnata
y L’allocazione della memoria ai processi è quindi uno degli scopi di un Sistema Operativo
i di
Si
O
i
Sistemi Operativi 2007/08
La CPU ed i processi
p
y Un programma per essere eseguito deve trovarsi nella U
it d
t
i ll
memoria primaria
{
LLa CPU può accedere ai registri ed alla memoria ma non alle CPU ò
d
i
i t i d ll
i
ll
istruzioni o agli indirizzi presenti sul disco
y La CPU è progettata per eseguire le istruzioni o per La CPU è progettata per eseguire le istruzioni o per
caricare i dati in memoria nell’arco di uno o più cicli di clock
{
{
I dati in memoria solitamente possono impiegare più tempo a causa del passaggio sul bus di sistema
p
gg
L’uso della cache può migliorare il recupero dei dati dalla memoria
Sistemi Operativi 2007/08
Avvio di un’applicazione
pp
y Nel momento in cui l
Nel momento in cui l’utente
utente manda in esecuzione un manda in esecuzione un
programma, il Sistema Operativo deve recuperare il codice dalla memoria secondaria e copiarlo in una zona della memoria primaria
memoria primaria
y Il Sistema Operativo deve quindi decidere l’indirizzo di RAM dal quale avviare il processo
q
p
y Poiché nella RAM potrebbero esserci altri processi l’operazione non ne immediata ne semplice
RAM
0000
P
7FFF
FFFF
Sistemi Operativi 2007/08
P
Registro base e Registro limite
g
g
y Ogni processo deve avere uno spazio di Ogni processo deve avere uno spazio di
memoria proprio e separato dal resto dei processi in modo che nessun altro possa accedervi
y Una soluzione consiste nell’utilizzare due registri
{
{
Registro base : contiene il più piccolo indirizzo R
it b
ti
il iù i l i di i
fisico ammesso
Registro limite : contiene la dimensione dell’intervallo
dell
intervallo ammesso
ammesso
y Solo il Sistema Operativo può accedere a questi registri ed impedisce ai programmi utenti di modificarli
utenti di modificarli
{
Il S.O. può anche effettuare in questo modo un dump (copia) della memoria
Sistemi Operativi 2007/08
0
Sistema
Operativo
256000
processo
300040
300040
processo
120900
420940
processo
880000
1024000
base
memoria centrale
limite
Protezione della memoria
y Per assicurare che non ci siano accessi illegali in memoria P
i
h
i i
i ill li i
i
la CPU confronta ogni indirizzo generato dal processo con i valori contenuti nel registro base e nel registro limite
i valori contenuti nel registro base e nel registro limite
base
CPU
base + limite
base + limite
sii
≥
no
sii
≤
no
Eccezione che restituisce il controllo al sistema operativo –
p
errore di indirizzamento
Sistemi Operativi 2007/08
memoria
Il problema dell’associazione degli indirizzi
p
g
y Supponiamo che tre processi P
Supponiamo che tre processi P1,P
P2 e P
e P3 siano presenti in siano presenti in
memoria
y In questo scenario sono possibili due eventi in un certo In questo scenario sono possibili due eventi in un certo
istante:
1.
2.
y
Un nuovo processo P
Un
nuovo processo P4 deve essere mandato in esecuzione (dove?)
deve essere mandato in esecuzione (dove?)
Il processo P1 in attesa di I/O viene momentaneamente spostato sull’hard disk per liberare memoria ad un processo da mandare in esecuzione Successivamente P1 sarà nuovamente mandato in esecuzione. Successivamente P
sarà nuovamente mandato in
esecuzione (dove?)
In entrambi i casi il Sistema Operativo deve essere in e t a b cas S ste a Ope at o de e esse e
grado di mandare sempre in esecuzione il processo indipendentemente dall’indirizzo di partenza
Sistemi Operativi 2007/08
Fasi di elaborazioni di un programma utente
p g
Programma
sorgente
Compilatore
o assemblatore
fase di compilazione
Modulo
oggetto
Altri
Moduli
oggetto
editor dei
collegamenti
modulo
rilocabile
fase di
caricamento
Libreria di
sistema
caricatore
Libreria di
caricata
dinamicame
nte
t
Sistemi Operativi 2007/08
Modulo eseguibile
Residente in
memoria
fase di
fase
di
esecuzione
Generazione del codice ‐ 2
y Supponiamo di avere una istruzione in C del genere
Supponiamo di avere una istruzione in C del genere
counter = counter + 1;
in assembly avremo qualcosa del genere:
in assembly
avremo qualcosa del genere:
20500 0x00003
…
20600 load(R1, 20500)
20604 add(R1,
( , #
#1);
);
20608 store(R1, 20500)
y La cella di memoria con indirizzo 20500 contiene il valore L
ll di
i
i di i
20500
i
il l
della variabile counter da incrementare
Sistemi Operativi 2007/08
Generazione del codice ‐ 2
y Supponiamo di avere una istruzione in C del genere
Supponiamo di avere una istruzione in C del genere
if(counter!=100) counter=0
in assembly avremo qualcosa del genere:
20500
…
300FC
30100
30104
30108
3010C
30110
0x00003
... ...
load(R1, 20500)
bne(R1, #100, 30110);
zero(R1)
( )
store(R1, 20500)
... ...
y La cella di memoria con indirizzo 20500 contiene il valore della variabile counter da incrementare
Sistemi Operativi 2007/08
Associazione degli indirizzi (binding)
g
(
g)
y L’associazione di istruzioni e dati a indirizzi di memoria si L’
i i
di i t i i d ti i di i i di
i i
può compiere in diverse fasi:
{
{
{
Compilazione
C
il i
Caricamento
Esecuzione
Sistemi Operativi 2007/08
Compilazione
p
y Se in fase di compilazione è noto a priori dove risiederà il S i f
di
il i
è t
i id
i i d à il
processo in memoria è possibile generare codice assoluto
{
Ad esempio se il processo deve iniziare dalla locazione r
Ad
i
il
d
i ii
d ll l
i
allora il ll
il
compilatore genera codice a partire dalla locazione r
y Il Sistema Operativo MS‐DOS utilizzava questo Il Sistema Operativo MS DOS utilizzava questo
meccanismo di associazione
y Quale è lo svantaggio principale di questo meccanismo?
Quale è lo svantaggio principale di questo meccanismo?
{
Se la locazione di memoria iniziale cambia oppure non è disponibile non è possibile mandare in esecuzione il processo anche se è
non è possibile mandare in esecuzione il processo anche se è disponibile memoria libera da qualche altra parte
Sistemi Operativi 2007/08
Caricamento
y Se a priori non è possibile stabilire dove allocare il S
i i
è
ibil t bili d
ll
il
processo allora è necessario generare codice rilocabile
y Finché il processo non è caricato in memoria non è hé l
è
è
posibile associare al programma gli indirizzi di memoria
y L’associazione non può essere cambiata nel caso in cui programma viene momentaneamente spostato del disco
y Nel caso in cui il programma deve essere spostato in memoria è necessario caricarlo di nuovo dal disco
Sistemi Operativi 2007/08
Esecuzione
y Se il programma durante la sua esecuzione può essere Se il programma durante la sua esecuzione può essere
spostato da una parte all’altra della memoria allora ll’associazione
associazione deve essere fatta a tempo di esecuzione
deve essere fatta a tempo di esecuzione
y Per poter utilizzare questo tipo di associazione è pp
necessario un supporto dell’hardware
y I vantaggi principali sono:
{
{
Assoluta indipendenza da una locazione di memoria
p
Possibilità di cambiare il blocco di memoria occupato immediatamente
y I Sistemi Operativi moderni supportano questa modalità I Si
iO
i i
d i
d li à
di associazione
Sistemi Operativi 2007/08
Spazi di indirizzi logici e fisici
p
g
y Gli indirizzi utilizzati da una applicazione sono diversi Gli indirizzi utilizzati da una applicazione sono diversi
dagli indirizzi realmente utilizzati dall’applicazione in memoria
{
{
Indirizzo logico (o indirizzi virtuali): è generato dalla CPU nel momento della compilazione
Indirizzo fisico : è l’indirizzo effettivamente utilizzato dall’applicazione in memoria e caricato nel registro di indirizzamento della memoria (memory
(
y address register, MAR)
g
,
)
y L’associazione degli indirizzi basati sulla compilazione e sul caricamento producono indirizzi logici e fisici identici
y L’associazione degli indirizzi basati sull’esecuzione genera indirizzi logici e fisici diversi
Sistemi Operativi 2007/08
Unità di gestione della memoria
g
y LL’associazione
associazione in fase di esecuzione tra lo spazio degli in fase di esecuzione tra lo spazio degli
indirizzi logici e lo spazio di indirizzi virtuali è svolta da unità di gestione della memoria (memory‐management
unità di gestione della memoria (memory
management
unit, MMU)
y La MMU possiede un registro di rilocazione che permette p
g
p
immediatamente di convertire un indirizzo logico in indirizzo fisico
y Il programma utente tratta sempre indirizzi logici mentre l’architettura di sistema tratta indirizzi fisici
{
Esempio: se l’applicazione utilizza un range di indirizzi logici da 0 a max ed il registro di locazione contiene il valore r allora il range di indirizzi fisici sarà da 0+r a r+max
Sistemi Operativi 2007/08
Es. di rilocazione dinamica con registro di rilocazione
g
y Supponiamo che il registro di rilocazione contenga il valore Supponiamo che il registro di rilocazione contenga il valore
14000
y Qualunque tentativo da parte dell’applicazione di accedere alle locazioni di memoria 0, 346 o 1200 si traduce in
{
{
0 + 14000 = 14000
346 + 14000 = 14346
Registro di rilocazione
14000
CPU
Indirizzo
logico
346
+
MMU
Sistemi Operativi 2007/08
Indirizzo
fisico
14346
memoria
Caricamento dinamico
y Un applicazione durante il suo ciclo di esecuzione utilizza delle Un applicazione durante il suo ciclo di esecuzione utilizza delle
y
y
y
y
procedure esterne (matematiche, database, disegno, etc…)
Il caricamento dinamico permette di caricare una procedura
Il caricamento dinamico permette di caricare una procedura in memoria solo quando viene richiamata
La memoria viene utilizzata meglio poiché la procedura è caricata solo se effettivamente utilizzata
Anche se l’applicazione è enorme la memoria occupata è effettivamente solo quella necessaria
ff tti
t
l
ll
i
Il programmatore deve prestare attenzione progettando ll’applicazione
applicazione in modo da trarre vantaggio dal caricamento in modo da trarre vantaggio dal caricamento
dinamico
Sistemi Operativi 2007/08
Librerie di procedure
p
y Le librerie di procedure possono essere L lib i di
d
fondamentalmente di due tipi:
{
{
Librerie statiche
Lib
i t ti h
Librerie dinamiche
y Il programmatore solitamente può accedervi utilizzando Il
t
lit
t
ò
d i tili
d
un file .h in C/C++
Sistemi Operativi 2007/08
Librerie statiche
y Le librerie statiche contengono procedure che vengono Le librerie statiche contengono procedure che vengono
collegate al codice del programma principale dal compilatore o dal loader e diventano parte dell
compilatore o dal loader
e diventano parte dell’eseguibile
eseguibile
y Lo svantaggio principale è che se n programmi utilizzano q
p
g
la stessa libreria statica questa sarà incorporata da ogni eseguibile e quindi lo stesso codice sarà caricato più volte in memoria {
Anche l’occupazione su disco aumenta inutilmente
y Oltretutto se l’applicazione una volta mandata in esecuzione non utilizzerà nessuna procedura della libreria i
ili
à
d
d ll lib i
occuperà inutilmente spazio in memoria
Sistemi Operativi 2007/08
Librerie dinamiche
y Una libreria dinamica viene caricata in memoria solo quando Una libreria dinamica viene caricata in memoria solo quando
l’applicazione chiama una delle sue procedure. La librerie è q
quindi caricata in memoria a run‐time utilizzando un caricamento dinamico
y L’applicazione che utilizza una libreria dinamica conterrà all’interno del suo codice il nome della procedura che vuole ll’i
d l
di il
d ll
d
h
l
chiamare
y Il vantaggio principale è che il codice di una libreria dinamica Il vantaggio principale è che il codice di una libreria dinamica
può essere condivisa tra più processi evitando inutili duplicazioni in memoria di codice identico
{
{
Sotto linux le librerie dinamiche hanno estensione .so
Sotto Windows le librerie dinamiche hanno la “ben nota” estensione .dll
Sistemi Operativi 2007/08
Avvicendamento dei processi
p
y LL’idea
idea dell
dell’avvicendamento
avvicendamento dei processi
dei processi (o swapping) è (o swapping) è
salvare nella memoria secondaria un processo non in esecuzione (swap out) e ricaricarlo (swap in) appena prima di p
p
pp
p
dargli la CPU
Sistema
Operativo
1 ‐ scaricamento
spazio
utente
memoria centrale
Sistemi Operativi 2007/08
2 ‐ caricamento
Processo P1
Processo P2
memoria ausiliare
Swapping
pp g
y Lo swapping permette di avere più processi attivi di L
i
tt di
iù
i tti i di
quanti effettivamente possa contenere la RAM
y I processi attivi sono mantenuti temporaneamente su un’area del disco fisso ad uso esclusivo del Sistema O
Operativo chiamata area di swap
ti
hi
t
di
y Poiché un processo può essere ricaricato in una diversa aria di memoria principale è necessario utilizzare codice dinamicamente rilocabile in fase di esecuzione
Sistemi Operativi 2007/08
Il cambio di contesto nello swapping
pp g
y La fase di contex switch utilizzando lo swapping può aumentare La fase di contex switch utilizzando lo swapping può aumentare
y
y
y
y
y
significativamente
Ad esempio supponiamo di avere in memoria un processo di 10MB e supponiamo che il disco fisso abbia una velocità di trasferimento di
supponiamo che il disco fisso abbia una velocità di trasferimento di 40MB/sec
Il tempo di trasferimento è pari a:
10 000KB / 40 000KB/sec = ¼ sec = 250 millisecondi
10.000KB / 40.000KB/sec = ¼ sec = 250 millisecondi
A questo tempo va aggiunto il tempo per posizionare le testine (circa 8 millisecondi) quindi passiamo a:
258 millisecondi
258 millisecondi
Infine va considerato che l’avvicendamento include una fase di scrittura (swap out) ed una di lettura (swap in) quindi in totale avremo:
516 illi
516 millisecondi
di
Quindi un quanto di tempo dovrebbe essere maggiore di 0,516 secondi
Sistemi Operativi 2007/08
Swapping
pp g
y I calcoli precedenti valgono nel caso di un processo di 10MB I calcoli precedenti valgono nel caso di un processo di 10MB
ma le conclusioni sono differenti se il processo occupa più memoria
y Normalmente i processi soggetti a swapping sono quelli in attesa di I/O ma…
{
{
Un processo P
p
/
p
p
1 con I/O asincrono potrebbero avere dei problemi
Se il processo P1 viene scaricato dalla memoria un altro processo P2 potrebbe utilizzare la memoria di P1 dedicata alle operazioni di I/O
y LL’avvicendamento
avvicendamento dei processi nella sua forma originale è dei processi nella sua forma originale è
utilizzato raramente nei sistemi operativi
y Il primo sistema operativo di massa ad usare swapping è stato Wi d
Windows 3.1
31
{
L’utente in maniera inconsapevole decideva quali applicazioni scaricare/caricare da disco
Sistemi Operativi 2007/08
Allocazione contigua della memoria
g
y La memoria centrale deve contenere sia La memoria centrale deve contenere sia
il Sistema Operativo che i processi degli utenti
y Normalmente il Sistema Operativo è p
caricato nella parte bassa della memoria (a partire dall’indirizzo 0)
y Per le applicazioni che devono essere pp
caricate in memoria è necessario adottare una politica di allocazione in memoria considerando la coda di i
id
d l
d di
ingresso dei processi
Sistemi Operativi 2007/08
0
Sistema
O
Operativo
i
spazio
utente
max
memoria centrale
Allocazione della memoria
y La memoria può essere allocata utilizzando diverse L
i
ò
ll t tili
d di
strategie tra le quali le più note sono:
{
{
Partizioni multiple fisse
P
ti i i
lti l fi
Partizioni multiple variabile
Sistemi Operativi 2007/08
Partizioni multiple fisse
p
y Nello schema a partizioni multiple fisse N ll
h
ti i i
lti l fi
la memoria è suddivisa in blocchi (non necessariamente tutti uguali) di
necessariamente tutti uguali) di dimensione fissa
y Ogni partizione può contenere un O i
ti i
ò
t
processo
y Il numero di partizioni decide il grado di multiprogrammazione
y Al termine di un processo, la partizione è libera per contenere un altro processo
Sistemi Operativi 2007/08
Sistema
O
Operativo
i
1MB
2MB
3MB
4MB
memoria centrale
Contex switch nelle partizioni multiple fisse
p
p
y Il meccanismo dei registri limite e di Il meccanismo dei registri limite e di
Sistema
O
Operativo
i
1MB
2MB
3MB
4MB
memoria centrale
Sistemi Operativi 2007/08
rilocazione può essere usato per proteggere le varie partizioni
proteggere le varie partizioni
y In fase di contex switch il Sistema O
Operativo carica:
ti
i
{
{
Nel registro di rilocazione l’indirizzo iniziale della partizione
della partizione Nel registro limite la dimensione del processo
Frammentazione interna
y Un processo allocato in una U
ll t i
partizione difficilmente ha esattamente la stessa dimensione di
esattamente la stessa dimensione di quella partizione
y La parte che rimane viene sprecata
L
t h i
i
t
{
Ad esempio, nella partizione da 2Mbyte, 512KB vengono sprecati
512KB vengono sprecati
y Questo problema è noto come frammentazione interna
frammentazione interna
Sistema
O
Operativo
i
1MB
2MB
1.5MB
3MB
4MB
memoria centrale
Sistemi Operativi 2007/08
Frammentazione esterna
y Un altro svantaggio sta nel numero di buchi che restano Un altro svantaggio sta nel numero di buchi che restano
liberi in ogni partizione
{
Ad esempio: allocando diversi processi
Ad
esempio: allocando diversi processi
in ogni partizione otteniamo uno spreco di
512KB+512KB+1MB+2MB = 3MB
y Questo problema è noto come
frammentazione esterna
y Un processo potrebbe essere
all’allocato nel blocco ottenuto
sommando i diversi buchi sprecati
p
Sistemi Operativi 2007/08
Sistema
O
Operativo
i
1MB
2MB
3MB
4MB
512KB
512 KB
512 KB
1.5MB
512KB
2MB
1MB
2MB
2MB
memoria centrale
Svantaggi delle partizioni multiple fisse
gg
p
p
y Frammentazione
Frammentazione interna
interna
{ In un blocco di dimensione fissa la memoria interna ad un partizione è assegnata ma non utilizzata completamente
g
p
y Frammentazione esterna
{ Lo spazio di memoria lasciato dai buchi è sufficiente per contenere un altro processo ma non è contigua
y Se un processo è grande ma non abbastanza da essere contenuto nella partizione più grande non può essere t
t
ll
ti i
iù
d
ò
caricato
{
Aumentando la dimensione delle partizioni diminuisce il grado di Aumentando
la dimensione delle partizioni diminuisce il grado di
multiprogrammazione ma tende anche ad aumentare la frammentazione interna
Sistemi Operativi 2007/08
Partizioni multiple variabili
p
y Nella schema a partizioni multiple variabili un processo riceve Nella schema a partizioni multiple variabili un processo riceve
un blocco di memoria pari alla sua dimensione
{
Non è più presente la frammentazione interna
p p
Sistema
Operativo
Area libera
10 MB
memoria centrale
Sistemi Operativi 2007/08
Sistema
Operativo
Sistema
Operativo
P1
2 MB
P1
2 MB
P2
1 MB
Area libera
10 MB
10 MB
memoria centrale
Area libera
Area
libera
10 MB
memoria centrale
Partizioni multiple variabili: creazioni di buchi
p
y Dopo che diversi processi si sono avvicendati in memoria D
h di
i
i i
i d ti i
i
vengono lasciati diversi buchi
{
I b hi
I buchi con il tempo diventano sempre più sparsi e non utilizzabili
il t
di t
iù
i
tili bili
Sistema
Operativo
Sistema
Operativo
Sistema
Operativo
Sistema
Operativo
Sistema
Operativo
P1
P1
P1
P1
P1
P4
P4
P2
P5
P5
P3
P3
P3
P3
P3
memoria centrale
memoria centrale
memoria centrale
memoria centrale
memoria centrale
Sistemi Operativi 2007/08
Metodi di allocazione
y Il Sistema Operativo tiene traccia di tutti i buchi liberi e della Il Sistema Operativo tiene traccia di tutti i buchi liberi e della
loro dimensione
y Quando un processo deve essere caricato in memoria il Sistema Operativo deve cercare un buco sufficientemente grande per contenerlo
y Le strategie per scegliere un buco libero sono:
Le strategie per scegliere un buco libero sono:
{
{
{
First‐fit : scegli la prima partizione abbastanza grande per poter caricare il processo
Best fit: scegli la più piccola partizione abbastanza grande per poter
Best‐fit: scegli la più piccola partizione abbastanza grande per poter caricare il processo
Worst‐fit: scegli la partizione più grande
y Sperimentalmente il metodo migliore di allocazione risulta S i
l
il
d
i li
di ll
i
i l
essere il First‐fit ed il Best‐fit
Sistemi Operativi 2007/08
Svantaggi delle partizioni multiple variabili
gg
p
p
yF
Frammentazione esterna
t i
t
{ Con il tempo si formano diversi buchi non contigui che non sono in grado di ospitare un processo
grado di ospitare un processo
{ La regola del 50 per cento stabilisce che per n blocchi allocati 0,5n
blocchi sono persi nella frammentazione
p
y Frammentazione interna
{ Il carico necessario per tenere traccia dei buchi lasciati liberi è più p
p
grande del buco stesso
Sistemi Operativi 2007/08
Compattazione
p
y La compattazione
L
tt i
èl
è la soluzione che si adopera per l i
h i d
recuperare i buchi di memoria inutilizzata
y L’idea è di spostare le immagini dei processi in maniera da ’d èd
l
d
d
ricavare un buco di memoria contigua sufficientemente grande da permettere di caricare altri processi
d d
tt
di i
lt i
i
y Per poter utilizzare la compattazione è necessario che i processi siano rilocabili
y Essendo una operazione onerosa che può richiedere molto tempo durante la compattazione il sistema è inutilizabile
Sistemi Operativi 2007/08
Strategie di compattazione
g
p
y LLa compattazione può essere effettuata in diversi modi:
tt i
ò
ff tt t i di
i
di
{ Spostare tutti i processi verso un estremo della memoria (molto costoso)
{ Spostare i processi in buchi già esistenti verso gli estremi della memoria (statisticamente si sposta meno memoria)
(
p
)
{ Spostare solo i processi necessari per far entrare un nuovo processo che altrimenti non avrebbe spazio sufficiente
Sistemi Operativi 2007/08
Esempi di compattazione p
p
0
0
Sistema
Operativo
600K
Sistema
Operativo
300K
300K
500K
P1
P2
500K
400K
800K
600K
1000K
1200K
0
P3
0
Sistema
Operativo
300K
P1
P2
P3
P4
1200K
500K
600K
Sistema
Operativo
300K
P1
P2
500K
600K
P1
P2
P4
1000K
1200K
P3
900K
300K
1500K
1500K
900K
P4
900K
1900K
2100K
P4
1900K
200K
allocazione allocazione
originale
Sistemi Operativi 2007/08
2100K
2100K
spostati
600K
2100K
spostati
400K
P3
spostati
200K
Scarica