Je m'intéresse à la différence entre Highmem et Lowmem:
Sur une architecture 32 bits, la plage d'espace d'adressage pour l'adressage RAM est:
0x00000000 - 0xffffffff
ou 4'294'967'295
(4 GO).
Le noyau Linux se divise en 3/1 (peut également être 2/2 ou 1/3 1) dans l'espace utilisateur (mémoire élevée) et l'espace noyau (mémoire faible) respectivement.
La gamme d'espace utilisateur:
0x00000000 - 0xbfffffff
Chaque processus utilisateur nouvellement généré obtient une adresse (plage) dans cette zone. Les processus utilisateur ne sont généralement pas approuvés et ne sont donc pas autorisés à accéder à l'espace du noyau. De plus, ils sont considérés comme non urgents, en règle générale, le noyau essaie de différer l'allocation de mémoire à ces processus.
La plage d'espace du noyau:
0xc0000000 - 0xffffffff
Un processus de noyau obtient son adresse (plage) ici. Le noyau peut accéder directement à ces 1 Go d'adresses (enfin, pas au 1 Go complet, il y a 128 Mo réservés pour un accès mémoire élevé).
Les processus générés dans l'espace du noyau sont fiables, urgents et supposés sans erreur, la demande de mémoire est traitée instantanément.
Chaque processus du noyau peut également accéder à la plage d'espace utilisateur s'il le souhaite. Et pour y parvenir, le noyau mappe une adresse de l'espace utilisateur (la mémoire haute) à son espace noyau (la mémoire basse), les 128 Mo mentionnés ci-dessus sont spécialement réservés pour cela.
1 Que le fractionnement soit 3/1, 2/2 ou 1/3 est contrôlé par le CONFIG_VMSPLIT_...
option; vous pouvez probablement vérifier sous /boot/config*
pour voir quelle option a été sélectionnée pour votre noyau.
La première référence vers laquelle se tourner est Linux Device Drivers (disponible à la fois en ligne et sous forme de livre), en particulier chapitre 15 qui a une section sur le sujet.
Dans un monde idéal, chaque composant du système serait capable de mapper toute la mémoire à laquelle il a besoin d'accéder. Et c'est le cas pour les processus sous Linux et la plupart des systèmes d'exploitation: un processus 32 bits ne peut accéder qu'à un peu moins de 2 ^ 32 octets de mémoire virtuelle (en fait environ 3 Go sur une architecture Linux 32 bits typique). Cela devient difficile pour le noyau, qui doit pouvoir mapper la mémoire complète du processus dont le système appelle l'exécution, ainsi que la mémoire physique entière, ainsi que tout autre périphérique matériel mappé en mémoire.
Ainsi, lorsqu'un noyau 32 bits doit mapper plus de 4 Go de mémoire, il doit être compilé avec un support de mémoire élevé. Une mémoire élevée est une mémoire qui n'est pas mappée en permanence dans l'espace d'adressage du noyau. (La mémoire faible est le contraire: elle est toujours mappée, vous pouvez donc y accéder dans le noyau simplement en déréférençant un pointeur.)
Lorsque vous accédez à une mémoire élevée à partir du code du noyau, vous devez d'abord appeler kmap
, pour obtenir un pointeur à partir d'une structure de données de page (struct page
). L'appel de kmap
fonctionne que la page soit en mémoire haute ou basse. Il y a aussi kmap_atomic
qui a ajouté des contraintes mais est plus efficace sur les machines multiprocesseurs car il utilise un verrouillage plus fin. Le pointeur obtenu via kmap
est une ressource: il utilise l'espace d'adressage. Une fois terminé, vous devez appeler kunmap
(ou kunmap_atomic
) pour libérer cette ressource; le pointeur n'est alors plus valide et le contenu de la page n'est plus accessible tant que vous n'avez pas appelé à nouveau kmap
.
Cela concerne le noyau Linux; Je ne sais pas comment un noyau Unix gère cela.
La mémoire haute est le segment de mémoire que les programmes de l'espace utilisateur peuvent traiter. Il ne peut pas toucher Low Memory.
La mémoire faible est le segment de mémoire que le noyau Linux peut traiter directement. Si le noyau doit accéder à High Memory, il doit d'abord le mapper dans son propre espace d'adressage.
Un correctif a été introduit récemment qui vous permet de contrôler l'emplacement du segment. Le compromis est que vous pouvez retirer la mémoire adressable de l'espace utilisateur afin que le noyau puisse avoir plus de mémoire qu'il n'a pas à mapper avant de l'utiliser.
Ressources additionnelles:
HIGHMEM est une plage d'espace mémoire du noyau, mais ce n'est PAS de la mémoire à laquelle vous accédez mais c'est un endroit où vous mettez ce que vous voulez accéder.
Une carte de mémoire virtuelle Linux 32 bits typique est comme:
0x00000000-0xbfffffff: processus utilisateur (3 Go)
0xc0000000-0xffffffff: espace noyau (1 Go)
(Les vecteurs spécifiques au CPU et quels qu'ils soient sont ignorés ici).
Linux divise l'espace du noyau de 1 Go en 2 parties, LOWMEM et HIGHMEM. La répartition varie d'une installation à l'autre.
Si une installation choisit, disons, 512 Mo à 512 Mo pour les mems LOW et HIGH, le 512MB LOWMEM (0xc0000000-0xdfffffff) est mappé statiquement au moment du démarrage du noyau; généralement, les premiers octets de la mémoire physique sont utilisés pour cela, de sorte que les adresses virtuelles et physiques dans cette plage ont un décalage constant de, disons, 0xc0000000.
En revanche, ce dernier 512 Mo (HIGHMEM) n'a pas de mappage statique (bien que vous puissiez y laisser des pages mappées de manière semi-permanente, mais vous devez le faire explicitement dans votre code de pilote). Au lieu de cela, les pages sont temporairement mappées et non mappées ici afin que les adresses virtuelles et physiques de cette plage n'aient pas de mappage cohérent. Les utilisations typiques de HIGHMEM incluent les tampons de données à usage unique.
Pour autant que je m'en souvienne, "High Memory" est utilisé pour l'espace d'application et "Low Memory" pour le noyau.
L'avantage est que les applications (espace utilisateur) ne peuvent pas accéder à la mémoire de l'espace noyau.
Beaucoup de gens ont dit que la mémoire faible est pour le système d'exploitation. C'est généralement vrai, mais ce n'est pas obligatoire. La mémoire élevée et la mémoire faible ne sont que deux parties de l'espace mémoire, mais dans le système Linux, la mémoire faible est réservée au noyau et la mémoire élevée aux processus utilisateur.
Selon le "livre sur les dinosaures (concepts de système d'exploitation)", nous pouvons placer le système d'exploitation en mémoire faible ou haute. Le principal facteur affectant cette décision est l'emplacement du vecteur d'interruption. Étant donné que le vecteur d'interruption est souvent en mémoire insuffisante, les programmeurs placent généralement le système d'exploitation en mémoire faible également.