Skip to content
Maxime Chéramy edited this page Feb 24, 2012 · 4 revisions

La pagination consiste à découper la mémoire en pages de taille fixe et les placer dans des cadres de page. Puisque nous travaillons sur une architecture 32 bits, l'espace d'adressage est limité à 4 Gio.

La première étape consiste à découper la mémoire physique en cadres de page de taille 4 Kio. Nous avons eu le choix entre une taille de 4 Kio, 2 Mio et 4 Mio mais nous avons préféré utiliser la taille la plus fine pour augmenter la granularité.

Afin de découper la mémoire physique et d'obtenir une liste de cadres utilisés et libres, nous avons simplement fait une boucle qui itérait sur l'ensemble de la RAM et qui tous les 4 Kio vérifiait si le cadre courant est réservé ou non. Typiquement, les cadres réservés sont ceux de la mémoire BIOS et du noyau.

Les cadres sont stockés dans deux listes chaînées : used_frame_pages et free_frame_pages et remplis initialement par la fonction memory_setup().

Deux fonctions permettent de réserver et de libérer un cadre de page pour y stocker une page. D'autres fonctions servent à pouvoir itérer sur les cadres de la mémoire physique mais elles sont moins importantes.

Une fois la mémoire physique découpée en cadres, nous avons pu activer la pagination. Comme la segmentation, c'est la MMU qui s'occupe de la traduction des adresses mais il faut pour cela lui donner l'adresse du répertoire de pages. La MMU du x86 travaille sur plusieurs niveaux de traduction. Il y a tout d'abord un répertoire contenant les adresses des tables de pages et c'est dans ces dernières que nous retrouvons les adresses des pages. On peut remarquer que le répertoire et les tables sont des tableaux de 1024 entrées de chacune 4 octets ce qui fait des blocs de 4 Kio, soit la taille d'une page. Ces tableaux doivent être alignés sur un cadre de page ce qui permet de les adresser en seulement 20 bits (4 Gio c'est 1024 x 1024 x 4 Kio soit 2^{20} x 4 Kio).

Pour activer la pagination, il faut faire deux choses :

  • Charger l'adresse du répertoire dans le registre CR3
  • Passer le bit "paging enable" du registre CR0 à 1.\

Une fois la pagination activée, il n'est plus possible de manipuler des adresses physiques, il convient alors de manipuler des adresses virtuelles. Cela peut avoir des conséquences inattendues, et c'est pour cette raison que nous avons mis en place un système parfois appelé "Identity mapping" et qui consiste à placer les pages dans les cadres tel qu'une adresse physique soit identique à une adresse virtuelle. Ensuite il sera bien sûr possible de casser cette égalité.

Une fois la mémoire mappée, nous donnons au répertoire des pages une adresse particulière afin d'y accéder et pouvoir modifier les tables de pages facilement. L'idée est la suivante : nous avons choisi une entrée du répertoire (arbitrairement la dernière) et nous l'avons fait pointer vers l'adresse du répertoire de page. Ainsi l'adresse virtuelle 0xFFFFF00 est l'adresse du répertoire et 0xFFC + 1024 * index_page_table est l'adresse d'une table de page.

Pour la suite, il est important de garder à l'esprit que c'est la MMU qui se charge de la traduction d'adresse. Ainsi, des zones mémoires peuvent être contigües dans la mémoire virtuelle alors que dans la mémoire physique il en est tout autrement.

Clone this wiki locally