Altre correzioni di indicizzazioni. Introdotta mremap. Aggiornati i flag di
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 24 Jun 2005 23:41:55 +0000 (23:41 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 24 Jun 2005 23:41:55 +0000 (23:41 +0000)
rmap per il prefaulting. Iniziata la documentazione del memory mapping non
lineare. Qualche correzione alla sezione iniziale sul funzionamento della
memoria virtuale.

errors.tex
fileadv.tex
img/mmap_boundary.dia
img/mmap_exceed.dia
ipc.tex
process.tex

index adecb8ef65a92f70c95e368485962e1e71742fff..7b92a3fc18ac123e991ecba02dfe1517c63ba48a 100644 (file)
@@ -340,11 +340,16 @@ specificati nelle sezioni precedenti.
 \item \errcode{EMULTIHOP} \textit{Multihop attempted}. 
 \item \errcode{ENODATA} \textit{No data available}. 
 \item \errcode{ENOLINK} \textit{Link has been severed}. 
-\item \errcode{ENOMSG} \textit{No message of desired type}. 
+\item \errcode{ENOMSG} \textit{No message of desired type}. Indica che una
+  coda di messaggi del \textit{SysV IPC} non è presente nessun messaggio del
+  tipo desiderato.
 \item \errcode{ENOSR} \textit{Out of streams resources}. 
 \item \errcode{ENOSTR} \textit{Device not a stream}. 
-\item \errcode{EOVERFLOW} \textit{Value too large for defined data type}. 
-\item \errcode{EPROTO} \textit{Protocol error}. 
+\item \errcode{EOVERFLOW} \textit{Value too large for defined data type}. Si è
+  chiesta la lettura di un dato dal \textit{SysV IPC} con \const{IPC\_STAT} ma
+  il valore eccede la dimensione usata nel buffer di lettura.
+\item \errcode{EPROTO} \textit{Protocol error}. C'è stato un errore nel 
+  protocollo di rete usato dal socket.
 \item \errcode{ETIME} \textit{Timer expired}. 
 \end{description}
 
@@ -352,54 +357,54 @@ specificati nelle sezioni precedenti.
 
 
 
-\section{Errori del kernel}
-\label{sec:err_kernel_err}
+\section{Errori del kernel}
+\label{sec:err_kernel_err}
 
-In questa sezione sono raccolti i codici di errore interni del kernel. Non
-sono usati dalle funzioni di libreria, ma vengono riportati da alcune system
-call (TODO verificare i dettagli, eventualmente cassare).
+In questa sezione sono raccolti i codici di errore interni del kernel. Non
+sono usati dalle funzioni di libreria, ma vengono riportati da alcune system
+call (TODO verificare i dettagli, eventualmente cassare).
 
-\begin{description}
-\item \errcode{ERESTART} \textit{Interrupted system call should be restarted}. 
-\item \errcode{ECHRNG} \textit{Channel number out of range}. 
-\item \errcode{EL2NSYNC} \textit{Level 2 not synchronized}. 
-\item \errcode{EL3HLT} \textit{Level 3 halted}. 
-\item \errcode{EL3RST} \textit{Level 3 reset}. 
-\item \errcode{ELNRNG} \textit{Link number out of range}. 
-\item \errcode{EUNATCH} \textit{Protocol driver not attached}. 
-\item \errcode{ENOCSI} \textit{No CSI structure available}. 
-\item \errcode{EL2HLT} \textit{Level 2 halted}. 
-\item \errcode{EBADE} \textit{Invalid exchange}. 
-\item \errcode{EBADR} \textit{Invalid request descriptor}. 
-\item \errcode{EXFULL} \textit{Exchange full}. 
-\item \errcode{ENOANO} \textit{No anode}. 
-\item \errcode{EBADRQC} \textit{Invalid request code}. 
-\item \errcode{EBADSLT} \textit{Invalid slot}. 
-\item \errcode{EDEADLOCK} Identico a \errcode{EDEADLK}. 
-\item \errcode{EBFONT} \textit{Bad font file format}. 
-\item \errcode{ENONET} \textit{Machine is not on the network}. 
-\item \errcode{ENOPKG} \textit{Package not installed}. 
-\item \errcode{EADV} \textit{Advertise error}. 
-\item \errcode{ESRMNT} \textit{Srmount error}. 
-\item \errcode{ECOMM} \textit{Communication error on send}. 
-\item \errcode{EDOTDOT} \textit{RFS specific error}. 
-\item \errcode{ENOTUNIQ} \textit{Name not unique on network}. 
-\item \errcode{EBADFD} \textit{File descriptor in bad state}. 
-\item \errcode{EREMCHG} \textit{Remote address changed}. 
-\item \errcode{ELIBACC} \textit{Can not access a needed shared library}. 
-\item \errcode{ELIBBAD} \textit{Accessing a corrupted shared library}. 
-\item \errcode{ELIBSCN} \textit{.lib section in a.out corrupted}. 
-\item \errcode{ELIBMAX} \textit{Attempting to link in too many shared
-    libraries}.
-\item \errcode{ELIBEXEC} \textit{Cannot exec a shared library directly}. 
-\item \errcode{ESTRPIPE} \textit{Streams pipe error}. 
-\item \errcode{EUCLEAN} \textit{Structure needs cleaning}. 
-\item \errcode{ENAVAIL} \textit{No XENIX semaphores available}. 
-\item \errcode{EISNAM} \textit{Is a named type file}. 
-\item \errcode{EREMOTEIO} \textit{Remote I/O error}. 
-\item \errcode{ENOMEDIUM} \textit{No medium found}. 
-\item \errcode{EMEDIUMTYPE} \textit{Wrong medium type}. 
-\end{description}
+\begin{description}
+\item \errcode{ERESTART} \textit{Interrupted system call should be restarted}. 
+\item \errcode{ECHRNG} \textit{Channel number out of range}. 
+\item \errcode{EL2NSYNC} \textit{Level 2 not synchronized}. 
+\item \errcode{EL3HLT} \textit{Level 3 halted}. 
+\item \errcode{EL3RST} \textit{Level 3 reset}. 
+\item \errcode{ELNRNG} \textit{Link number out of range}. 
+\item \errcode{EUNATCH} \textit{Protocol driver not attached}. 
+\item \errcode{ENOCSI} \textit{No CSI structure available}. 
+\item \errcode{EL2HLT} \textit{Level 2 halted}. 
+\item \errcode{EBADE} \textit{Invalid exchange}. 
+\item \errcode{EBADR} \textit{Invalid request descriptor}. 
+\item \errcode{EXFULL} \textit{Exchange full}. 
+\item \errcode{ENOANO} \textit{No anode}. 
+\item \errcode{EBADRQC} \textit{Invalid request code}. 
+\item \errcode{EBADSLT} \textit{Invalid slot}. 
+\item \errcode{EDEADLOCK} Identico a \errcode{EDEADLK}. 
+\item \errcode{EBFONT} \textit{Bad font file format}. 
+\item \errcode{ENONET} \textit{Machine is not on the network}. 
+\item \errcode{ENOPKG} \textit{Package not installed}. 
+\item \errcode{EADV} \textit{Advertise error}. 
+\item \errcode{ESRMNT} \textit{Srmount error}. 
+\item \errcode{ECOMM} \textit{Communication error on send}. 
+\item \errcode{EDOTDOT} \textit{RFS specific error}. 
+\item \errcode{ENOTUNIQ} \textit{Name not unique on network}. 
+\item \errcode{EBADFD} \textit{File descriptor in bad state}. 
+\item \errcode{EREMCHG} \textit{Remote address changed}. 
+\item \errcode{ELIBACC} \textit{Can not access a needed shared library}. 
+\item \errcode{ELIBBAD} \textit{Accessing a corrupted shared library}. 
+\item \errcode{ELIBSCN} \textit{.lib section in a.out corrupted}. 
+\item \errcode{ELIBMAX} \textit{Attempting to link in too many shared
+    libraries}.
+\item \errcode{ELIBEXEC} \textit{Cannot exec a shared library directly}. 
+\item \errcode{ESTRPIPE} \textit{Streams pipe error}. 
+\item \errcode{EUCLEAN} \textit{Structure needs cleaning}. 
+\item \errcode{ENAVAIL} \textit{No XENIX semaphores available}. 
+\item \errcode{EISNAM} \textit{Is a named type file}. 
+\item \errcode{EREMOTEIO} \textit{Remote I/O error}. 
+\item \errcode{ENOMEDIUM} \textit{No medium found}. 
+\item \errcode{EMEDIUMTYPE} \textit{Wrong medium type}. 
+\end{description}
 
 
 
index 25e62d309ed63c23836e822dfab643c1c1901845..6a94f22492fa08ef6ca8047c9e49681ca23d269d 100644 (file)
@@ -998,7 +998,7 @@ si pu
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=14cm]{img/mmap_layout}
+  \includegraphics[width=13cm]{img/mmap_layout}
   \caption{Disposizione della memoria di un processo quando si esegue la
   mappatura in memoria di un file.}
   \label{fig:file_mmap_layout}
@@ -1094,11 +1094,11 @@ multiplo della dimensione di una pagina di memoria.
 Il valore dell'argomento \param{prot} indica la protezione\footnote{in Linux
   la memoria reale è divisa in pagine: ogni processo vede la sua memoria
   attraverso uno o più segmenti lineari di memoria virtuale.  Per ciascuno di
-  questi segmenti il kernel mantiene nella \textit{page table} la mappatura
-  sulle pagine di memoria reale, ed le modalità di accesso (lettura,
-  esecuzione, scrittura); una loro violazione causa quella che si chiama una
-  \textit{segment violation}, e la relativa emissione del segnale
-  \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
+  questi segmenti il kernel mantiene nella \itindex{page~table}\textit{page
+    table} la mappatura sulle pagine di memoria reale, ed le modalità di
+  accesso (lettura, esecuzione, scrittura); una loro violazione causa quella
+  che si chiama una \textit{segment violation}, e la relativa emissione del
+  segnale \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
 specificato come maschera binaria ottenuta dall'OR di uno o più dei valori
 riportati in tab.~\ref{tab:file_mmap_flag}; il valore specificato deve essere
 compatibile con la modalità di accesso con cui si è aperto il file.
@@ -1155,7 +1155,7 @@ tab.~\ref{tab:file_mmap_flag}.
                              memoria disponibile, si ha l'emissione di
                              un \const{SIGSEGV}. \\
     \const{MAP\_LOCKED}    & Se impostato impedisce lo swapping delle pagine
-                             mappate. \\
+                             mappate.\\
     \const{MAP\_GROWSDOWN} & Usato per gli stack. Indica 
                              che la mappatura deve essere effettuata con gli
                              indirizzi crescenti verso il basso.\\
@@ -1163,17 +1163,26 @@ tab.~\ref{tab:file_mmap_flag}.
                              argomenti \param{fd} e \param{offset} sono
                              ignorati.\footnotemark\\
     \const{MAP\_ANON}      & Sinonimo di \const{MAP\_ANONYMOUS}, deprecato.\\
-    \const{MAP\_FILE}      & Valore di compatibilità, deprecato.\\
+    \const{MAP\_FILE}      & Valore di compatibilità, ignorato.\\
+    \const{MAP\_32BIT}     & Esegue la mappatura sui primi 2GiB dello spazio
+                             degli indirizzi, viene supportato solo sulle
+                             piattaforme \texttt{x86-64} per compatibilità con
+                             le applicazioni a 32 bit. Viene ignorato se si è
+                             richiesto \const{MAP\_FIXED}.\\
+    \const{MAP\_POPULATE}  & Esegue il \itindex{prefaulting}
+                             \textit{prefaulting} delle pagine di memoria
+                             necessarie alla mappatura. \\
+    \const{MAP\_NONBLOCK}  & Esegue un \textit{prefaulting} più limitato che
+                             non causa I/O.\footnotemark \\
+%     \const{MAP\_DONTEXPAND}& Non consente una successiva espansione dell'area
+%                              mappata con \func{mremap}, proposto ma pare non
+%                              implementato.\\
     \hline
   \end{tabular}
   \caption{Valori possibili dell'argomento \param{flag} di \func{mmap}.}
   \label{tab:file_mmap_flag}
 \end{table}
 
-\footnotetext{Dato che tutti faranno riferimento alle stesse pagine di
-  memoria.}  
-\footnotetext{L'uso di questo flag con \const{MAP\_SHARED} è
-  stato implementato in Linux a partire dai kernel della serie 2.4.x.}
 
 Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
 piuttosto complessi, essi si possono comprendere solo tenendo presente che
@@ -1184,14 +1193,6 @@ sola lettura si avr
 (\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non
 consentono questo tipo di accesso.
 
-\begin{figure}[!htb]
-  \centering
-  \includegraphics[width=10cm]{img/mmap_boundary}
-  \caption{Schema della mappatura in memoria di una sezione di file di
-    dimensioni non corrispondenti al bordo di una pagina.}
-  \label{fig:file_mmap_boundary}
-\end{figure}
-
 È invece assai diversa la questione relativa agli accessi al di fuori della
 regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe
 ritenere che anch'essi debbano generare un segnale di violazione di accesso;
@@ -1199,11 +1200,30 @@ questo per
 paginazione\index{paginazione}, la mappatura in memoria non può che essere
 eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una
 pagina, ed in generale queste potranno non corrispondere alle dimensioni
-effettive del file o della sezione che si vuole mappare. Il caso più comune è
-quello illustrato in fig.~\ref{fig:file_mmap_boundary}, in cui la sezione di
-file non rientra nei confini di una pagina: in tal caso verrà il file sarà
-mappato su un segmento di memoria che si estende fino al bordo della pagina
-successiva.
+effettive del file o della sezione che si vuole mappare. 
+
+\footnotetext[20]{Dato che tutti faranno riferimento alle stesse pagine di
+  memoria.}  
+\footnotetext[21]{L'uso di questo flag con \const{MAP\_SHARED} è
+  stato implementato in Linux a partire dai kernel della serie 2.4.x.}
+
+\footnotetext{questo flag ed il precedente \const{MAP\_POPULATE} sono stati
+  introdotti nel kernel 2.5.46 insieme alla mappatura non lineare di cui
+  parleremo più avanti.}
+
+\begin{figure}[!htb] 
+  \centering
+  \includegraphics[width=10cm]{img/mmap_boundary}
+  \caption{Schema della mappatura in memoria di una sezione di file di
+    dimensioni non corrispondenti al bordo di una pagina.}
+  \label{fig:file_mmap_boundary}
+\end{figure}
+
+
+Il caso più comune è quello illustrato in fig.~\ref{fig:file_mmap_boundary},
+in cui la sezione di file non rientra nei confini di una pagina: in tal caso
+verrà il file sarà mappato su un segmento di memoria che si estende fino al
+bordo della pagina successiva.
 
 In questo caso è possibile accedere a quella zona di memoria che eccede le
 dimensioni specificate da \param{lenght}, senza ottenere un \const{SIGSEGV}
@@ -1217,14 +1237,6 @@ file mappato sono pi
 file è stato troncato, dopo che è stato mappato, ad una dimensione inferiore a
 quella della mappatura in memoria.
 
-\begin{figure}[htb]
-  \centering
-  \includegraphics[width=10cm]{img/mmap_exceed}
-  \caption{Schema della mappatura in memoria di file di dimensioni inferiori
-    alla lunghezza richiesta.}
-  \label{fig:file_mmap_exceed}
-\end{figure}
-
 In questa situazione, per la sezione di pagina parzialmente coperta dal
 contenuto del file, vale esattamente quanto visto in precedenza; invece per la
 parte che eccede, fino alle dimensioni date da \param{length}, l'accesso non
@@ -1242,6 +1254,14 @@ sez.~\ref{sec:file_vfs_work}). Si tenga presente per
 di dispositivi (un esempio è l'interfaccia al ponte PCI-VME del chip Universe)
 che sono utilizzabili solo con questa interfaccia.
 
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=10cm]{img/mmap_exceed}
+  \caption{Schema della mappatura in memoria di file di dimensioni inferiori
+    alla lunghezza richiesta.}
+  \label{fig:file_mmap_exceed}
+\end{figure}
+
 Dato che passando attraverso una \func{fork} lo spazio di indirizzi viene
 copiato integralmente, i file mappati in memoria verranno ereditati in maniera
 trasparente dal processo figlio, mantenendo gli stessi attributi avuti nel
@@ -1293,8 +1313,9 @@ memoria mappata con il file su disco; il suo prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EINVAL}] O \param{start} non è multiplo di \const{PAGESIZE},
-    o si è specificato un valore non valido per \param{flags}.
+    \item[\errcode{EINVAL}] O \param{start} non è multiplo di
+      \const{PAGE\_SIZE}, o si è specificato un valore non valido per
+      \param{flags}.
     \item[\errcode{EFAULT}] L'intervallo specificato non ricade in una zona
       precedentemente mappata.
     \end{errlist}
@@ -1365,9 +1386,82 @@ Indicare un intervallo che non contiene pagine mappate non 
 Alla conclusione del processo, ogni pagina mappata verrà automaticamente
 rilasciata, mentre la chiusura del file descriptor usato per effettuare la
 mappatura in memoria non ha alcun effetto sulla stessa.
+
+Infine Linux supporta alcune operazioni specifiche non disponibili su altri
+kernel unix-like. La prima di queste operazioni è la possibilità di modificare
+una mappatura precedente, ad esempio per espanderla o restringerla. Questo è
+realizzato dalla funzione \funcd{mremap}, il cui prototipo è:
+\begin{functions}  
+  \headdecl{unistd.h}
+  \headdecl{sys/mman.h} 
+
+  \funcdecl{void * mremap(void *old\_address, size\_t old\_size , size\_t
+    new\_size, unsigned long flags);}
+  
+  Restringe o allarga una mappatura in memoria di un file.
+
+  \bodydesc{La funzione restituisce l'indirizzo alla nuova area di memoria in
+    caso di successo od il valore \const{MAP\_FAILED} (pari a \texttt{(void *)
+      -1}) in caso di errore, nel qual caso \var{errno} assumerà uno dei
+    valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] Uno dei puntatori non è validi, in genere si è
+      usato un valore di \param{old\_address} non allineato ad una pagina di
+      memoria.
+    \item[\errcode{EFAULT}] Ci sono degli indirizzi non validi nell'intervallo
+      di memoria specificato dagli argomenti \param{old\_address} e
+      \param{old\_size}, o ci sono altre mappatura di un tipo non
+      corrispondente a quella richiesta.
+    \item[\errcode{ENOMEM}] Non c'è memoria sufficiente oppure l'area di
+      memoria non può essere espansa all'indirizzo virtuale corrente, e non si
+      è specificato \const{MREMAP\_MAYMOVE} nei flag.
+    \item[\errcode{EAGAIN}] Il segmento di memoria scelto è bloccato e non può
+      essere rimappato.
+    \end{errlist}
+  }
+\end{functions}
+
+La funzione richiede come argomenti \param{old\_address} che specifica il
+precedente indirizzo per la mappatura in memoria e \param{old\_size}, che ne
+indica la dimensione, con \param{new\_size} si specifica invece la nuova
+dimensione che si vuole ottenere. Questa funzione usa il meccanismo della
+\index{memoria~virtuale}memoria virtuale per modificare l'associazione fra gli
+indirizzi virtuali del processo e le pagine di memoria, modificando una
+precedente mappatura.
+
+Infine l'argomento \param{flags} è una maschera binaria per i flag che
+controllano il comportamento della funzione. Il solo valore utilizzato è
+\const{MREMAP\_MAYMOVE}\footnote{per poter utilizzare questa costante occorre
+  aver definito \macro{\_GNU\_SOURCE} prima di includere \file{sys/mman.h}.}
+che consente di eseguire l'espansione anche quando non è possibile utilizzare
+il predente indirizzo. Per questo motivo la funzione restituisce sempre
+l'indirizzo della nuova zona di memoria, che, se si è usato questo flag, non è
+detto coincida con \param{old\_address}.
+
+La mappatura in memoria di un file viene normalmente eseguita in maniera
+lineare, cioè parti successive di un file vengono mappate linearmente su
+indirizzi successivi in memoria (la prima pagina di un file viene mappata
+sulla prima pagina di memoria). Esistono però delle applicazioni\footnote{in
+  particolare la tecnica è usata dai database o dai programmi che realizzano
+  macchine virtuali.} in cui è utile poter mappare parti diverse di un file su
+diverse zone di memoria. 
+
+Questo è ovviamente sempre possibile eseguendo più volte \func{mmap} per
+ciascuna delle diverse aree, ma questo approccio ha delle conseguenze molto
+pesanti in termini di prestazioni. Si ricordi infatti che il \textit{memory
+  mapping} in memoria funziona facendo ricorso al meccaniso della
+\index{memoria~virtuale} memoria virtuale per trascrivere su un file le
+operazioni effettuate sugli indirizzi di memoria sui cui esso è mappato. 
+
+Per questo motivo con il kernel 2.5.46 è stato introdotto ad opera di Ingo
+Molnar un meccanismo che consente la mappatura non lineare, ed i due nuovi
+flag \const{MAP\_POPULATE} e \const{MAP\_NONBLOCK} per \func{mmap}.
+
+
 \itindend{memory~mapping}
 
 
+
 \section{Il file locking}
 \label{sec:file_locking}
 
index 29956d363ec827c0999138f5f22c4d962287f2da..8160a80adcfa67997fd5ca6c0a2b74fca2068ce2 100644 (file)
Binary files a/img/mmap_boundary.dia and b/img/mmap_boundary.dia differ
index 8630e39202f33fbcca9c69ef0357e9e12181c477..3b5319650a7563fdc071fd5cb3a726d4ce941d72 100644 (file)
Binary files a/img/mmap_exceed.dia and b/img/mmap_exceed.dia differ
diff --git a/ipc.tex b/ipc.tex
index dc314c78b158a15cb1f64d5f630837c59b154256..839f9dafa468a7eca5f9a5dce6bb805fa237d526 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -2480,7 +2480,7 @@ un segmento di memoria condivisa 
       \const{IPC\_RMID} senza i permessi necessari.
     \item[\errcode{EOVERFLOW}] Si è tentato il comando \const{IPC\_STAT} ma il
       valore del group-ID o dell'user-ID è troppo grande per essere
-      memorizzato nella struttura puntata dal \param{buf}.  
+      memorizzato nella struttura puntata da \param{buf}.
     \item[\errcode{EFAULT}] L'indirizzo specificato con \param{buf} non è
       valido.
     \end{errlist}
@@ -3364,7 +3364,7 @@ di messaggi POSIX 
     di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
     valori:
     \begin{errlist}
-    \item[\errcode{EACCESS}] Il processo non ha i privilegi per accedere al
+    \item[\errcode{EACCES}] Il processo non ha i privilegi per accedere al
       alla memoria secondo quanto specificato da \param{oflag}.
     \item[\errcode{EEXIST}] Si è specificato \const{O\_CREAT} e
       \const{O\_EXCL} ma la coda già esiste.
index 37ef2d004558f099ee6c0476682c0dc937cba4d3..1166f5119bb17c853af906249cc922a7b9cc1592 100644 (file)
@@ -294,21 +294,21 @@ virtuale di tutti i processi che hanno detta funzione nel loro codice.
 
 La corrispondenza fra le pagine della \index{memoria~virtuale}memoria virtuale
 e quelle della memoria fisica della macchina viene gestita in maniera
-trasparente dall'hardware di gestione della memoria (la \textit{Memory
-  Management Unit} del processore).  Poiché in genere la memoria fisica è solo
-una piccola frazione della memoria virtuale, è necessario un meccanismo che
-permetta di trasferire le pagine che servono dal supporto su cui si trovano in
-memoria, eliminando quelle che non servono. Questo meccanismo è detto
-\textsl{paginazione}\index{paginazione} (o \textit{paging}), ed è uno dei
-compiti principali del kernel.
+trasparente dal kernel con l'ausilio dell'hardware di gestione della memoria
+(la \textit{Memory Management Unit} del processore).  Poiché in genere la
+memoria fisica è solo una piccola frazione della memoria virtuale, è
+necessario un meccanismo che permetta di trasferire le pagine che servono dal
+supporto su cui si trovano in memoria, eliminando quelle che non servono.
+Questo meccanismo è detto \textsl{paginazione}\index{paginazione} (o
+\textit{paging}), ed è uno dei compiti principali del kernel.
 
 Quando un processo cerca di accedere ad una pagina che non è nella memoria
 reale, avviene quello che viene chiamato un \textit{page
-  fault}\itindex{page~fault}; l'hardware di gestione della memoria genera
-un'interruzione e passa il controllo al kernel il quale sospende il processo e
-si incarica di mettere in RAM la pagina richiesta (effettuando tutte le
-operazioni necessarie per reperire lo spazio necessario), per poi restituire
-il controllo al processo.
+  fault}\itindex{page~fault}; la gestione della memoria genera un'interruzione
+e passa il controllo al kernel il quale sospende il processo e si incarica di
+mettere in RAM la pagina richiesta (effettuando tutte le operazioni necessarie
+per reperire lo spazio necessario), per poi restituire il controllo al
+processo.
 
 Dal punto di vista di un processo questo meccanismo è completamente
 trasparente, e tutto avviene come se tutte le pagine fossero sempre