1 Mémoire virtuelle paginée
Une MMU, unité de gestion mémoire, est un circuit d'interface sur le
bus d'adresse entre le microprocesseur et la mémoire centrale. Dans la
pratique, ce circuit est directement intégré sur le silicium du
microprocesseur. La MMU transforme une adresse entrante, fournie par
le microprocesseur, en une adresse sortante, exploitée par la mémoire.
Le fonctionnement de la MMU que nous considérons est basé sur
l'exploitation d'une TLB, Translation Lookaside Buffer ou table
des pages suivant le principe suivant :
-
Elle décode une adresse placée par le microprocesseur sur le bus
d'adresse.
- En ne considérant que les 20 bits de poids fort sur les 32
bits d'adresse, elle cherche une équivalence dans la TLB.
- Si l'équivalence est trouvée, elle forme l'adresse sortante en
remplacant les 20 bits de poids fort par les 20 bits
d'équivalence trouvés dans la TLB, les 12 bits de poids faible
conservés d'une adresse à l'autre constituant le déplacement dans
la page courante.
- Dans le cas contraire, elle repositionne le PC du
microprocesseur sur le début de l'instruction en cours et génère
une interruption.
En cas d'interruption, le système d'exploitation peut consulter
l'adresse ayant générée celle-ci dans la variable (ou registre)
unsigned TLB_UNKNOWN_ADDRESS;
et insérer une nouvelle entrée dans la TLB en utilisant la
variable/registre
tlb_entry_t TLB_NEW_ENTRY;
de 44 bits.
Le type tlb_entry_t est défini comme suit :
typedef struct _tlb_entry_s tlb_entry_t;
struct _tlb_entry_s {
int vrt : 20; /* poids fort de l'adresse virtuelle */
int trs : 20; /* poids fort de l'adresse physique */
int ac_r : 1; /* 0: accès en lecture interdit */
int ac_w : 1; /* 0: accès en écriture interdit */
int ac_x : 1; /* 0: accès en exécution interdit */
int lock : 1; /* 0: peut être vidé de la TLB */
};
Exercice 1
Quelle est la taille en octets d'une page de mémoire de travail
selon le fonctionnement de la MMU que nous
considérons ?
1.1 Segmentation de la mémoire
Dans un premier cas d'utilisation, il est décidé que la MMU sera
simplement utilisée pour découper la mémoire virtuelle selon 3
segments distincts :
-
de 0x00800000 à 0x0081A000 : code exécutable
(et seulement exécutable) ;
- De 0x00900000 à 0x00902000 : données
manipulées en lecture/écriture ;
- de 0x00A00000 à 0x00A01000 : données
manipulées en lecture seule.
La mémoire physique quant à elle commence en 0x00000000 et
finit en 0x0001D000.
Exercice 2
Proposez une fonction
_itdecl void tlb_irq(void);
qui convertit les adresses virtuelles en adresses physiques selon
le schéma précédent. Cette interruption est appelée lorsqu'aucune
correspondance n'a été trouvée dans la TLB.
1.2 Pagination de la mémoire
De manière moins statique, un système d'exploitation gère en règle
générale un ensemble de pages libres qu'il associe aux espaces
d'adressages virtuels qu'il crée pour chaque processus. Ainsi les
pages physiques sont allouées à la demande.
Exercice 3
Proposez une stratégie pour implémenter les procédures
void* alloc_page();
void free_page(void* ptr);
Vous pouvez vous inspirer du travail fait sur les systèmes de
fichiers.
Pour chaque processus, le système d'exploitation gère un arbre de
translation qui lui permet de faire la translation entre adresse
virtuelle et adresse physique. L'idée est la suivante : une page de
mémoire physique associée au processus contient une table de 1024
entrées. Ces 1024 entrées correspondent à 1024 adresses physiques
sur des pages qui sont autant de tables d'indirection de second
niveau. Chacune de ces tables contient donc 1024 entrées : 1024
adresses virtuelles. Lorsqu'une adresse virtuelle doit être convertie
en adresse physique, le système d'exploitation décompose l'adresse en
3 champs :
-
indirection1 : les 10 bits de poids fort
- indirection2 : les 10 bits suivants
- deplacement : les 12 bits de poids faible
En considérant l'entrée indirection1 de la première page, le
système d'exploitation trouve la table de second niveau. En
considérant l'entrée indirection2 de cette table, il trouve
l'adresse physique qui a été associée à cette adresse virtuelle. Il
est évident que toutes les adresses virtuelles (4 Go) ne sont pas
associées à des adresses physiques dans chaque processus. Aussi, bon
nombre d'entrées des tables de premier ou second niveau sont nulles.
Exercice 4
Donnez la déclaration des structures de données qui permettent de
mettre en oeuvre cette translation d'adresses.
Lorsque le système d'exploitation crée un nouveau processus, il doit
créer un nouvel arbre de translation.
Figure 1 : Le modèle de mémoire virtuelle utilisé par Linux.
Exercice 5
Proposez une fonction
int alloc_translators(int code_size,
int data_size,
int bss_size,
int stack_size);
de création d'un arbre de translation qui respecte le modèle
d'organisation de la mémoire virtuelle utilisé par Linux, illustré
par la figure 1.
Exercice 6
Proposez une nouvelle implémentation de la procédure
_itdecl void tlb_irq(void);
qui convertit les adresses virtuelles en adresses physiques selon
le nouveau schéma.
1.3 Mémoire partagée
Exercice 7
Proposez une stratégie pour mettre en oeuvre un mécanisme
simplifié de mémoire partagée selon les procédures suivantes :
/* mappe et alloue si nécessaire en mémoire virtuelle */
void* openshm(int key, int size);
/* détache et libère si nécessaire une zone de mémoire partagée */
void closeshm(int key, int size);
[fin provisoire du sujet]