Que sont la mémoire haute et la mémoire basse sous Linux?


92

Je suis intéressé par la différence entre Highmem et Lowmem:

  1. Pourquoi existe-t-il une telle différenciation?
  2. Qu'avons-nous gagné en le faisant?
  3. Quelles sont les fonctionnalités de chacun?

@hiro, vous voulez dire "HIGHMEM" est "adresse virtuelle du noyau" comme décrit par ldd3. Je suis d'accord avec toi. c'est déroutant, ldd3 a défini "LOWMEM" "HIGHMEM", ainsi que "adresse virtuelle du noyau" "adresse logique du noyau". ils sont la même chose, mais a un nom différent. c’est la "beauté" du logiciel, il dépend donc du langage de description.
steve

Réponses:


69

Sur une architecture 32 bits, la plage d'espace d'adressage pour l'adressage de la RAM est la suivante:

0x00000000 - 0xffffffff

ou 4'294'967'295(4 Go).

Le noyau Linux le sépare jusqu’à 3/1 (pourrait aussi être 2/2, ou 1/3 1 ) en espace utilisateur (mémoire vive) et espace noyau (mémoire faible), respectivement.

La plage d'espace utilisateur:

0x00000000 - 0xbfffffff

Chaque processus utilisateur nouvellement généré reçoit une adresse (plage) à l'intérieur de cette zone. Les processus utilisateur ne sont généralement pas fiables et il est donc interdit d'accéder à l'espace du noyau. En outre, 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 à cette adresse de 1 Go (ainsi, pas à la totalité de 1 Go, 128 Mo sont réservés pour un accès mémoire élevé).

Les processus générés dans l'espace noyau sont sécurisés, 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 ce faire, le noyau mappe une adresse de l'espace utilisateur (la mémoire haute) sur son espace noyau (la mémoire faible), les 128 Mo mentionnés ci-dessus sont spécialement réservés à cet effet.


1 Que l' CONFIG_VMSPLIT_...option soit divisée en 3/1, 2/2 ou 1/3 ; vous pouvez probablement vérifier sous /boot/config*pour voir quelle option a été sélectionnée pour votre noyau.


C'est vieux et je ne suis pas sûr que tu sois ici. Mais je veux poser une question: les 128 Mo réservés dans l’espace noyau (pour un accès mémoire élevé), s’agit-il de toutes les références de la zone mémoire de l’espace utilisateur? Ainsi, un processus du noyau peut accéder à n’importe quel espace utilisateur en faisant référence à cette zone, non?
Amumu

1
Pourquoi est-il toujours en 1/4? Pourquoi ne pourrait-il pas diviser 5/1 ou quelque chose comme ça?
mgalgs

Que signifie exactement "peut directement accéder" ici? Je veux dire, le noyau lui-même n'est-il pas accessible via le mécanisme de mémoire virtuelle?
telenn

1
Je pense que ce que vous dites à propos de la mémoire haute / basse est erroné: je pense que dans un système pur 32 bits, le noyau peut accéder directement à la totalité des 3 Go d'espace utilisateur (le noyau peut accéder à l'espace noyau et à l'espace utilisateur). Cependant, lorsque vous avez un noyau PAE, les choses deviennent plus complexes, vous avez maintenant plus de 3 Go de RAM, chaque processus peut durer 3 Go et vous ne pouvez pas accéder directement à la totalité de l'espace utilisateur. C’est là que la mémoire haute et que 128 Mo de mémoire dans l’espace du noyau entrent en jeu. Avec un noyau 64 bits, cela devient encore plus simple, sans aucun homme fort, car tout l’espace utilisateur est accessible à partir du noyau.
ctrl-alt-delor

2
@mgalgs ¼, 2/4 et ¾ n'était qu'un ensemble de choix par défaut exposés. Depuis 2007, on peut également sélectionner les 5 / 16ème et 15/32. Si vous savez modifier quelle ligne #define, vous pouvez choisir votre propre division presque arbitraire.
jørgensen

28

La première référence à laquelle faire référence est les pilotes de périphériques Linux (disponibles à la fois en ligne et sous forme de livre), en particulier le chapitre 15 qui contient 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 aurait jamais 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 (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 l'appel système est en cours d'exécution, la mémoire physique complète et 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 mémoire élevé. La mémoire haute est la mémoire qui n'est pas mappée en permanence dans l'espace d'adressage du noyau. (La mémoire basse est l'inverse: elle est toujours mappée, vous pouvez donc y accéder dans le noyau simplement en déréférencant un pointeur.)

Lorsque vous accédez à la mémoire vive à partir du code du noyau, vous devez d' kmapabord appeler pour obtenir un pointeur à partir d'une structure de données de page ( struct page). L'appel kmapfonctionne que la page soit en mémoire haute ou basse. Il existe également des kmap_atomiccontraintes supplémentaires, mais qui sont plus efficaces sur les machines multi-processeurs, car elles utilisent un verrouillage à grain plus fin. Le pointeur obtenu via kmapest une ressource: il utilise un espace d'adressage. Une fois que vous avez 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 accessible que lorsque vous appelez à kmapnouveau.


2
Merci Gilles pour la réponse .. Mais je ne suis toujours pas en mesure de comprendre le concept dans son intégralité. Pourriez-vous être un peu plus simple sans réduire les informations qu'il contient?
Sen

17

Ceci est pertinent pour 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 d'espace utilisateur peuvent adresser. Il ne peut pas toucher la mémoire faible.

Mémoire faible est le segment de mémoire que le noyau Linux peut adresser directement. Si le noyau doit accéder à la mémoire haute, il doit d'abord le mapper dans son propre espace d'adressage.

Un correctif récemment introduit vous permet de contrôler l'emplacement du segment. Le compromis est que vous pouvez retirer de la mémoire utilisateur la mémoire adressable de sorte que le noyau puisse disposer de plus de mémoire qu'il n'a pas besoin de mapper avant de l'utiliser.

Ressources additionnelles:


4

HIGHMEM est une plage d’espace mémoire du noyau, mais ce n’est PAS 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 la suivante:

  • 0x00000000-0xbfffffff: processus utilisateur (3 Go)

  • 0xc0000000-0xffffffff: espace noyau (1 Go)

(Les vecteurs spécifiques au processeur et quels qu'ils soient sont ignorés ici).

Linux divise l’espace noyau de 1 Go en deux parties, LOWMEM et HIGHMEM. Le fractionnement varie d'une installation à l'autre.

Si une installation choisit, par exemple, 512 Mo à 512 Mo pour les mems LOW et HIGH, le serveur LOWMEM de 512 Mo (0xc0000000-0xdfffffff) est mappé de manière statique au moment du démarrage du noyau; généralement, le premier nombre d'octets de la mémoire physique est utilisé à cet effet, de sorte que les adresses virtuelles et physiques de cette plage ont un décalage constant de, par exemple, 0xc0000000.

D'autre part, le dernier 512 Mo (HIGHMEM) n'a pas de mappage statique (bien que vous puissiez laisser des pages mappées de façon semi-permanente, mais vous devez le faire explicitement dans votre code de pilote). À la place, les pages sont mappées et démappées temporairement ici, de sorte que les adresses virtuelles et physiques de cette plage n'ont pas de mappage cohérent. Les utilisations typiques de HIGHMEM incluent des tampons de données uniques.


3

Autant que je me souvienne, "High Memory" est utilisé pour l'espace d'application et "Low Memory" pour le noyau.

L'avantage est que les applications (utilisateur) ne peuvent pas accéder à la mémoire de l'espace noyau.


0

Beaucoup de gens ont dit que la faible mémoire était pour le système d'exploitation. Ceci est généralement vrai mais ne doit pas nécessairement l'être. Une mémoire élevée et une mémoire faible ne représentent que deux parties de l'espace mémoire, mais sous Linux, la mémoire réduite ne concerne que le noyau et la mémoire vive sert aux processus utilisateur.

Selon le "Livre des dinosaures (concepts du système d’exploitation)", nous pouvons placer le système d’exploitation dans une mémoire faible ou élevée. Le principal facteur ayant influé sur cette décision est l'emplacement du vecteur d'interruption. Étant donné que le vecteur d'interruption est souvent dans une mémoire insuffisante, les programmeurs placent également le système d'exploitation dans cette mémoire également.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.