Mode protégé
Le mode protégé est un mode de fonctionnement des processeurs basés sur l'architecture x86 d'Intel à partir du 80286. Il est aussi présent dans les séries x86-64 sous deux formes possibles : 32 bits et 64 bits.
Caractéristiques
[modifier | modifier le code]L'introduction du mode protégé a pour but d'ajouter, à côté du mode dit réel compatible avec l'existant, de nouvelles fonctionnalités pour favoriser le multitâche et la stabilité du système en proposant une assistance matérielle pour les points suivants :
- protection de la mémoire (niveaux de privilèges) ;
- support de la mémoire virtuelle (segmentation puis, à partir du 80386, pagination) ;
- commutation de contexte ;
- adressage sur 32 bits à partir du 80386.
La plupart des systèmes d'exploitation modernes x86, de Linux à FreeBSD en passant par Windows depuis la version 3.1, fonctionnent dans ce mode. Pour des raisons de compatibilité, un ordinateur se lance en mode réel et le basculement en mode protégé s'effectue ensuite. Il s'agit d'une des premières tâches faites par le système d'exploitation après l'amorçage.
La segmentation
[modifier | modifier le code]La segmentation ne peut pas être complètement désactivée en mode protégé. Mais à la différence du mode réel, les segments sont entièrement programmables.
C’est avec la segmentation que sont instaurés les niveaux de privilèges (anneaux, voir ci-dessous). Chaque segment possède un niveau de 0 à 3.
La segmentation sert aussi de support à la mémoire virtuelle. En effet, un segment est constitué d’une base (adresse physique — appelée linéaire si la pagination est activée — de départ dans la mémoire) et d’une limite qui définit sa longueur. À l’intérieur d’un segment, l’adresse logique 0 correspond à la base de ce segment. Un segment peut donc être déplacé avec ses données de façon transparente.
De plus le descripteur de chaque segment contient un bit P pour « présent » qui indique si les données sont en mémoire vive ou pas. Si ce bit est éteint, lors d'un accès à ce segment, une exception se déclenche qui permet au système d’exploitation d’aller chercher les données où elles se trouvent et de les copier en mémoire vive.
La segmentation n'est pratiquement pas utilisée par Linux, qui définit des segments correspondant à l'ensemble de la mémoire virtuelle.
Niveaux de privilège
[modifier | modifier le code]Il existe, en mode protégé de x86, quatre niveaux de privilège appelés anneaux de protection, numérotés de 0 à 3. Le niveau 0 est le niveau de privilège le plus élevé et le niveau 3 le plus faible. La protection mémoire repose sur les segments : le matériel n’autorise pas à un programme qui s’exécute dans un segment, d’accéder aux segments de privilège supérieur (donc situés dans un anneau de numéro inférieur).
En pratique, la plupart des systèmes d'exploitation modernes (dont Linux et Windows) n'utilisent que deux de ces niveaux. Le code de l'espace noyau (notamment le noyau de système d'exploitation) s'exécute dans l'anneau Ring 0, tandis que les applications utilisateur sont normalement exécutées dans l'anneau Ring 3, plus sécurisé et plus restrictif. On parle couramment de ces anneaux avec les termes « mode noyau » et « mode utilisateur ».
Pagination
[modifier | modifier le code]La segmentation ne pouvant être désactivée, les adresses virtuelles sont systématiquement traitées par l'unité de segmentation, qui produit une adresse linéaire. Lorsque la pagination n'est pas disponible (80286) ou désactivée, cette adresse linéaire est directement considérée comme une adresse physique. Cependant, le 80386 et ses successeurs offrent un puissant mécanisme de pagination qui permet de gérer très efficacement la mémoire virtuelle.
Dans le cas le plus fréquent, la mémoire virtuelle (celle correspondant aux adresses linéaires) est divisée en pages de 4 Kio (mais il est possible également d'avoir des pages de 2 Mio ou 4 Mio). Chaque contexte dispose d'un espace d'adressage de 4 Gio, soit 1 024×1 024 pages, dont certaines correspondent à des cadres en mémoire vive (qui ont la même taille, donc habituellement 4 Kio). L'association entre pages et cadres est assurée par l'unité de pagination.
Afin de limiter la taille de la table des pages (a priori un tableau de plus d'un million d'entrées, mais très creux), une structure à deux niveaux est mise en place :
- les 10 bits de poids plus fort de l'adresse permettent de désigner une entrée d'un répertoire de tables de pages (dont l'adresse de base est donnée par le registre CR3), qui compte donc 1 024 entrées de 32 bits chacune (soit 4 Kio, soit exactement un cadre). Cette entrée donne l'adresse d'un cadre qui contient un tableau de deuxième niveau, la table de pages ;
- les 10 bits suivants de l'adresse désignent une entrée de cette table de pages. Cette dernière compte donc également 1 024 entrées, de 32 bits chacune, soit exactement un cadre ici aussi. Cette entrée donne l'adresse (physique) du cadre associé à la page ;
- les 12 bits de poids faible donnent le déplacement, aussi bien dans la page que dans le cadre.
Une entrée de répertoire ou de table de pages fait 32 bits, or une adresse de cadre est donnée sur 20 bits (10+10). Il reste donc 12 bits supplémentaires, qui correspondent à divers indicateurs, dont le bit de présence, qui indique que la page n'est pas présente en mémoire. Lorsque cela se produit, une exception de type défaut de page est levée, et doit être traitée par le système d'exploitation. Deux cas se présentent :
- la page en question a précédemment été stockée sur une mémoire de masse pour libérer de la mémoire vive (swap). Il faut donc à nouveau libérer de la mémoire vive le cas échéant, et rapatrier la page de la mémoire de masse vers la mémoire centrale avant que le processus puisse poursuivre son exécution ;
- la page n'a pas été allouée par le processus : celui-ci vient donc de provoquer une erreur, et doit être terminé.
Rétro-compatibilité avec le mode réel
[modifier | modifier le code]Il existe une série de règles pour qu'un programme exploité en mode réel soit binairement compatible, c'est-à-dire qu'il puisse être exécuté en mode protégé.
En fait, la plupart des programmes DOS enfreignaient ces règles. Le 386 introduit le mode virtuel 8086 pour remédier à cela.
Les modes protégés de x86-64
[modifier | modifier le code]Le mode 32 bits de x86 est conservé, appelé Legacy Mode (mode hérité). x86-64 introduit un autre mode protégé en 64 bits natif appelé Long mode, avec des différences notables :
- Sous-mode de compatibilité pour exécuter des programmes compilés en 32 ou 16 bits utilisant le mode protégé
- Taille de page de 4 Kio ou 2 Mio
- Disparition quasi totale de la segmentation (mémoire virtuelle adressée par 64 bits à plat). CS, DS, ES et SS sont traités comme s'ils valaient zéro. FS et GS ont un traitement particulier.
- Désactivation du mode virtuel 8086
- Disparition du basculement de tâches automatique. La commutation de contexte incombe désormais au logiciel.
- Nouvelle manière de changer le niveau de privilège