Explication détaillée de l'espace utilisateur Linux et de l'espace noyau

藏色散人
Libérer: 2020-12-08 17:01:31
avant
4294 Les gens l'ont consulté

Recommandé : "Tutoriel vidéo Linux"

1. Introduction

  • Fonctionnement du système d'exploitation Linux et du pilote Dans espace noyau, les applications s'exécutent dans l'espace utilisateur. Les deux ne peuvent pas simplement utiliser des pointeurs pour transférer des données. En raison du mécanisme de mémoire virtuelle utilisé par Linux, les données de l'espace utilisateur peuvent être échangées. Lorsque l'espace du noyau utilise des pointeurs d'espace utilisateur, les données correspondantes peuvent ne pas être en mémoire. Le mappage mémoire de l'espace utilisateur adopte le type de page de segment, tandis que l'espace noyau a ses propres règles ; cet article vise à explorer le mappage d'adresses de l'espace noyau ;
  • os alloue un espace mémoire d'adresse virtuelle indépendant et continu à chaque processus. La taille est généralement de 4 Go (système d'exploitation 32 bits, soit 2 à la puissance 32), dans lequel la valeur d'adresse élevée est. L'espace mémoire est alloué au système d'exploitation, le système d'exploitation Linux occupe 1 Go et le système d'exploitation Windows occupe 2 Go ; l'espace d'adressage mémoire restant est alloué aux processus.
  • Habituellement, l'espace d'adressage virtuel du noyau Linux 32 bits est divisé en 0~3G comme espace utilisateur et 3~4G comme espace noyau (notez que l'adresse linéaire que le noyau peut utiliser n'est que de 1G). Notez qu'il s'agit de la division de l'espace d'adressage du noyau 32 bits et que la division de l'espace d'adressage du noyau 64 bits est différente.

  • Espace d'adressage du processus 0 ~ 4G
  • Le processus est dans l'utilisateur mode Seuls 0~3G sont accessibles, et 3G~4G ne sont accessibles qu'en entrant dans l'état du noyau
  • Le processus entre dans l'état du noyau via des appels système
  • La partie 3G~4G du l'espace virtuel de chaque processus est le même
  • Le processus entrant en mode noyau à partir du mode utilisateur ne provoquera pas de modifications dans CR3 mais entraînera des modifications dans la pile

2. Mémoire haut de gamme du noyau Linux

1. Origine

Lorsque le code ou le thread du module du noyau accède à la mémoire, les adresses mémoire dans le code sont toutes des adresses logiques, et pour correspondre à la adresse mémoire physique réelle, l'adresse doit être un à un Mappage, par exemple, l'adresse physique correspondant à l'adresse logique 0xc0000003 est 0×3, l'adresse physique correspondant à 0xc0000004 est 0×4,... , la relation entre l'adresse logique et l'adresse physique est

Adresse physique = Adresse logique – 0xC0000000 : Il s'agit de la relation de traduction d'adresse de l'espace d'adressage du noyau. Notez que l'adresse virtuelle du noyau est au "haut de gamme". ", mais l'adresse mémoire physique mappée par ta se trouve à l'extrémité inférieure.

En supposant que, selon la relation de mappage d'adresse simple ci-dessus, l'accès à l'espace d'adressage logique du noyau est 0xc0000000 ~ 0xffffffff, alors la plage de mémoire physique correspondante est 0×0 ~ 0×40000000, c'est-à-dire que seule 1 Go de mémoire physique est accessible . Si 8 Go de mémoire physique sont installés sur la machine, le noyau ne peut accéder qu'au premier Go de mémoire physique, et les 7 Go de mémoire physique suivants seront inaccessibles car l'espace d'adressage du noyau a été entièrement mappé sur la plage d'adresses de la mémoire physique 0 × 0 ~ 0×40000000. Même si une mémoire physique de 8 Go est installée, comment le noyau accède-t-il à la mémoire avec l'adresse physique 0×40000001 ? Le code doit avoir une adresse logique en mémoire. L'espace d'adressage de 0xc0000000 à 0xffffffff a été utilisé, donc la mémoire après l'adresse physique 0×40000000 n'est pas accessible.

Évidemment, l'espace d'adressage du noyau 0xc0000000 ~ 0xfffffff ne peut pas être utilisé pour un simple mappage d'adresses. Par conséquent, l'architecture x86 divise l'espace d'adressage du noyau en trois parties : ZONE_DMA, ZONE_NORMAL et ZONE_HIGHMEM. ZONE_HIGHMEM est une mémoire haut de gamme, qui est à l'origine du concept de mémoire haut de gamme.


Dans la structure x86, les trois types de zones (calculées à partir de la 3G) sont les suivants :

ZONE_DMA 16 Mo à partir de la mémoire

ZONE_NORMAL 16Mo~896Mo

ZONE_HIGHMEM 896Mo ~ Fin (1G)

2. Comprendre

Plus tôt, nous avons expliqué l'origine de la mémoire haut de gamme. Linux divise l'espace d'adressage du noyau en trois parties : ZONE_DMA, ZONE_NORMAL et ZONE_HIGHMEM. L'espace d'adressage de la mémoire haut de gamme HIGH_MEM va de 0xF8000000 à 0xFFFFFFFF (896 Mo à 1 024 Mo). Donc, si le noyau estcomment peut-il utiliser l'espace d'adressage mémoire haut de gamme de 128 Mo pour accéder à toute la mémoire physique ?

Lorsque le noyau souhaite accéder à la mémoire avec une adresse physique supérieure à 896 Mo, il trouvera un espace d'adressage logique libre de taille correspondante dans la plage d'espace d'adressage de 0xF8000000 ~ 0xFFFFFFFF et l'empruntera pendant un certain temps. Empruntez cet espace d'adressage logique et mappez-le à la mémoire physique à laquelle vous souhaitez accéder (c'est-à-dire, remplissez le tableau des pages PTE du noyau Utilisez-le temporairement pendant un certain temps et renvoyez-le après utilisation). De cette manière, d'autres peuvent également emprunter cet espace d'adressage pour accéder à d'autres mémoires physiques, obtenant ainsi l'utilisation d'un espace d'adressage limité pour accéder à toutes les mémoires physiques. Comme indiqué ci-dessous.

Par exemple, le noyau souhaite accéder à une mémoire physique de 1 Mo à partir de 2G, c'est-à-dire que la plage d'adresses physiques est de 0 × 80000000 ~ 0x800FFFFF. Avant d'accéder, recherchez d'abord un espace d'adressage libre de 1 Mo. Supposons que l'espace d'adressage libre trouvé soit 0xF8700000 ~ 0xF87FFFFF. Utilisez cet espace d'adressage logique de 1 Mo pour mapper la mémoire dans l'espace d'adressage physique 0 × 80000000 ~ 0x800FFFFF. La relation de mappage est la suivante :

Adresse logique
逻辑地址 物理内存地址
0xc0000000 0×0
0xc0000001 0×1
0xc0000002 0×2
0xc0000003 0×3
0xe0000000 0×20000000
0xffffffff 0×40000000 ??
Adresse mémoire physique
0xc0000000 0×0
0xc0000001 0×1
0xc0000002 0×2
0xc0000003 0×3
0xe0000000 0×20000000
0xffffffff 0×40000000 ??
tr>
逻辑地址 物理内存地址
0xF8700000 0×80000000
0xF8700001 0×80000001
0xF8700002 0×80000002
0xF87FFFFF 0x800FFFFF
Adresse logique
Adresse mémoire physique
0xF8700000 td> 0×80000000
0xF8700001 0×80000001
0xF8700002 0×80000002
0xF87FFFFF 0x800FFFFF

Une fois que le noyau a accédé à la mémoire physique 0×80000000 ~ 0x800FFFFF, il libère l'espace linéaire du noyau 0xF8700000 ~ 0xF87FFFFF. De cette manière, d'autres processus ou codes peuvent également utiliser l'adresse 0xF8700000 ~ 0xF87FFFFF pour accéder à une autre mémoire physique.

D'après la description ci-dessus, nous pouvons connaître l'idée la plus basique de la mémoire haut de gamme : emprunter une section d'espace d'adressage, établir un mappage d'adresses temporaire, la libérer après utilisation, et cet espace d'adressage peut être recyclé, accéder à toute la mémoire physique.

En voyant cela, certaines personnes ne peuvent s'empêcher de se demander : que se passe-t-il si un processus ou un module du noyau continue d'occuper un certain espace d'adressage logique et ne le libère pas ? Si cette situation se produit réellement, l'espace d'adressage mémoire haut de gamme du noyau deviendra de plus en plus restreint s'il est occupé et non libéré, il ne sera pas accessible même s'il n'est pas mappé sur la mémoire physique.

3. Division

Le noyau divise la mémoire haut de gamme en 3 parties : VMALLOC_START~VMALLOC_END, KMAP_BASE~FIXADDR_START et FIXADDR_START~4G.


Pour une mémoire haut de gamme, vous pouvez obtenir la page correspondante via alloc_page() ou d'autres fonctions, mais si vous souhaitez accéder à la mémoire physique réelle, vous il faut convertir la page en linéaire L'adresse fera l'affaire (pourquoi ? Pensez à la façon dont la MMU accède à la mémoire physique). C'est-à-dire que nous devons trouver un espace linéaire pour la page correspondant à la mémoire haut de gamme. appelé mappage de mémoire haut de gamme.

correspond aux trois parties de la mémoire haut de gamme. Il existe trois façons de mapper la mémoire haut de gamme :
est mappé à « l'espace de mappage dynamique du noyau » (allocation de mémoire non contiguë) Cette méthode est très simple, car grâce à vmalloc(), lors de la demande de mémoire dans "l'espace de mappage dynamique du noyau", il est possible d'obtenir des pages à partir de la mémoire haut de gamme (voir l'implémentation de vmalloc), donc il Il est possible que la mémoire haut de gamme soit mappée sur « l'espace de mappage dynamique du noyau ».

Mappage permanent du noyau Si la page correspondant à la mémoire haut de gamme est obtenue via alloc_page(), comment lui trouver un espace linéaire ?
Le noyau réserve spécialement pour cela un espace linéaire, de PKMAP_BASE à FIXADDR_START, pour mapper la mémoire haut de gamme. Sur le noyau 2.6, cette plage d'adresses est comprise entre 4G-8M et 4G-4M. Cet espace est appelé « Espace de mappage permanent du noyau » ou « Espace de mappage permanent du noyau ». Cet espace utilise la même table de répertoire de pages que les autres espaces. Pour le noyau, il s'agit de swapper_pg_dir. Pour les processus ordinaires, il est pointé par le registre CR3. Normalement, cet espace a une taille de 4 Mo, donc une seule table de pages est nécessaire. Le noyau recherche cette table de pages via pkmap_page_table. Grâce à kmap(), une page peut être mappée sur cet espace. Étant donné que cet espace fait 4 Mo, jusqu'à 1 024 pages peuvent être mappées en même temps. Par conséquent, les pages inutilisées doivent être libérées de cet espace en temps opportun (c'est-à-dire que la relation de mappage est libérée via kunmap(), l'adresse linéaire correspondant à une page peut être libérée de cet espace).

Mappage temporaire du noyau Le noyau réserve un espace linéaire entre FIXADDR_START et FIXADDR_TOP pour des besoins particuliers. Cet espace est appelé « espace de mappage fixe ». Dans cet espace, une partie est utilisée pour le mappage temporaire de la mémoire haut de gamme.

Cet espace a les caractéristiques suivantes :

(1) Chaque CPU occupe un espace
(2) L'espace occupé par chaque CPU est divisé en plusieurs petits espaces La taille de chaque petit espace est. 1 page, et chaque petit espace est utilisé dans un but précis. Ces objectifs sont définis dans km_type dans kmap_types.h.

Lorsqu'un mappage temporaire doit être effectué, le but du mappage doit être spécifié. Selon le but du mappage, le petit espace correspondant peut être trouvé, puis l'adresse de cet espace est utilisée comme mappage. adresse. Cela signifie qu'un mappage temporaire entraînera l'écrasement du mappage précédent. Le mappage temporaire est réalisé via kmap_atomic().

3. Autres

1. L'espace utilisateur (processus) a-t-il un concept de mémoire haut de gamme ?

Les processus utilisateur n'ont aucune notion de mémoire haut de gamme. La mémoire élevée n'existe que dans l'espace du noyau. Les processus utilisateur ne peuvent accéder qu'à 3 Go de mémoire physique, tandis que les processus du noyau peuvent accéder à toute la mémoire physique.

2. Y a-t-il de la mémoire haut de gamme dans le noyau 64 bits ?

Dans la réalité actuelle, la mémoire haut de gamme n'existe pas dans le noyau Linux 64 bits car le noyau 64 bits peut prendre en charge plus de 512 Go de mémoire. Si la mémoire physique installée sur la machine dépasse l'espace d'adressage du noyau, il y aura une mémoire haut de gamme.

3. À quelle quantité de mémoire physique un processus utilisateur peut-il accéder ? À quelle quantité de mémoire physique le code du noyau peut-il accéder ?

Les processus utilisateur du système 32 bits peuvent accéder jusqu'à 3 Go et le code du noyau peut accéder à toute la mémoire physique.

Les processus utilisateur du système 64 bits peuvent accéder à un maximum de plus de 512 Go, et le code du noyau peut accéder à toute la mémoire physique.

4. Quelle est la relation entre la mémoire haut de gamme et l'adresse physique, l'adresse logique et l'adresse linéaire ?

La mémoire haut de gamme est uniquement liée aux adresses logiques et n'a aucune relation directe avec les adresses logiques et les adresses physiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal