Croisière au coeur d'un OS Etape 4 : La pagination
La mémoire virtuelle : la traduction d'adresses
Dans cette partie, nous détaillerons les principes généraux relatifs à la traduction des adresses de la mémoire virtuelle.
1. Mémoire virtuelle et MMU
L’objectif associé à la “mémoire virtuelle” est de
pouvoir écrire des programmes en considérant que
la mémoire disponible est “infinie” ou du moins
indépendante de la RAM disponible. A cette fin, les
autres ressources disponibles (tel que le disque dur
local ou celui d’une autre machine sur le réseau) peuvent
être utilisées pour stocker les parties de cette
mémoire virtuelle qui ne servent pas souvent. Ceci permet
de libérer de la RAM pour y stocker ce qui sert
plus fréquemment. C’est le mécanisme de swap qu’on
retrouve sur la plupart des OS génériques, tel que
Linux.
Ce mécanisme correspond au fonctionnement d’un
cache : la RAM sert de tampon pour les accès
aux données/instructions qui se situent dans un espace
beaucoup plus grand (la mémoire virtuelle).
Toute la mise en oeuvre de la mémoire virtuelle repose en fait sur un seul mécanisme fondamental et plus général : la traduction d’adresses. Cette dernière consiste à découpler i) les adresses des données et des instructions manipulées par le processeur de ii) leur emplacement physique (en RAM, sur le disque ou ailleurs). Elle est prise en charge par l’unité de gestion de la mémoire (MMU). En pratique, la MMU peut être une puce externe au processeur située entre le processeur et la RAM (figure 3) ou être intégrée directement dans la puce qui contient le processeur.
Les processeurs n'utilisent pas nécessairement une MMU mais nous nous intéressons uniquement aux processeurs de type x86 qui utilise une MMU.
2. Le fonctionnement
Avec la mémoire virtuelle, le processeur dispose d'un espace de mémoire "infini". Les adresses qu'il utilise sont purement fictives. Il faut donc que les adresses "fictives" soit traduites en adresses physiques dans la RAM. C'est la MMU et le système d'exploitation qui se chargent de cette traduction. Cette traduction se fait en deux étapes.
Première étape (systématique)
Le processeur commence par fournir chaque adresse qu’il manipule (purement fictive) à la MMU. Celle-ci s’occupe de les traduire en adresses en RAM (et en RAM seulement). Deux cas peuvent se produire. Si la MMU dispose d’une traduction pour l’adresse fictive fournie par le processeur, alors elle se charge de l’accès à la RAM. Le processeur récupère ensuite la donnée/instruction sur le bus mémoire et peut continuer son travail. Si la traduction par la MMU échoue, les données ne sont donc pas en RAM. Dans ce cas, la MMU signale une exception au processeur et c’est au système d’exploitation de la prendre en charge.
Deuxième étape (si besoin)
Le système d’exploitation définit et maintient ses propres structures de données internes pour la gestion des adresses fictives. Lorsqu’il prend le relais pour traiter l’exception levée par la MMU, il utilise ces données pour déterminer où sont les données/instructions référencées par l’adresse fictive qui a provoqué l’exception ( à quel endroit dans le swap ? dans quel fichier ?) ou pour signaler que l’adresse fictive ne référence rien de connu. Si l’OS constate que l’adresse fictive correspond à un emplacement sur le disque dur, il peut transférer les données depuis cet emplacement du disque vers la RAM si de la place est disponible. Ce mécanisme porte le nom générique de “demand paging” et se trouve au coeur du fonctionnement du file mapping (projection de fichier) ou du swap (entre autres). Si aucune place en RAM n’est disponible, il peut transférer un morceau peu utilisé de la RAM vers le disque (en veillant à mettre à jour les tables de traduction d’adresses) et il peut ainsi profiter de ce nouvel emplacement disponible. Si le système d’exploitation constate que l’adresse fictive ne correspond à rien (ni en RAM, ni sur disque, ni sur aucune autre ressource de stockage), il peut avertir l’application qui a travaillé avec l’adresse fictive erronée. Ceci correspond au fameux “segmentation fault” sous Unix. Ainsi, la traduction d’adresses permet aussi de détecter et de signaler des erreurs de programmation.
note sur l'OS
Lorsque l'on dit que “l’OS prend le relais quand la MMU n’a pas pu traduire l’adresse fictive fournie par le processeur”, cela laisse à penser que l’OS constitue une entité en dehors de tout le reste (processeur et MMU). En réalité, il n’en est rien : l’OS est fait de codes et de données qui sont aussi traités par le processeur. Ce qui vient d’être décrit s’applique donc à l’OS lui-même. Ceci induit ainsi un niveau de récursivité supplémentaire (pour traiter les défauts de traduction de la MMU, l’OS utilise la MMU). Cet aspect aurait été difficile à faire apparaître sur la figure et dans le synopsis.
page suivante >