GNU/Linux >> Tutoriels Linux >  >> Linux

Comment fonctionne copy_from_user du noyau Linux en interne ?

L'implémentation de copy_from_user() dépend fortement de l'architecture.

Sur x86 et x86-64, il effectue simplement une lecture directe à partir de l'adresse de l'espace utilisateur et écrit dans l'adresse de l'espace noyau, tout en désactivant temporairement SMAP (Supervisor Mode Access Prevention) s'il est configuré. La partie délicate est que le copy_from_user() Le code est placé dans une région spéciale afin que le gestionnaire de défauts de page puisse reconnaître lorsqu'un défaut se produit à l'intérieur de celui-ci. Un défaut de protection de la mémoire qui se produit en copy_from_user() ne tue pas le processus comme il le ferait s'il était déclenché par un autre code de contexte de processus, ou ne panique pas le noyau comme il le ferait s'il se produisait dans un contexte d'interruption - il reprend simplement l'exécution dans un chemin de code qui renvoie -EFAULT à l'appelant.


concernant "comment copier_vers_utilisateur puisque le noyau transmet l'adresse de l'espace du noyau, comment un processus de l'espace utilisateur peut-il y accéder"

Un processus de l'espace utilisateur peut tenter d'accéder à n'importe quelle adresse. Cependant, si l'adresse n'est pas mappée dans cet espace utilisateur de processus (c'est-à-dire dans les tables de pages de ce processus) ou s'il y a un problème avec l'accès comme une tentative d'écriture à un emplacement en lecture seule, alors un défaut de page est généré. Notez qu'au moins sur le x86, chaque processus a tout l'espace du noyau mappé dans le 1 gigaoctet le plus bas de l'espace d'adressage virtuel de ce processus, tandis que les 3 gigaoctets supérieurs de l'espace d'adressage total de 4 Go (j'utilise ici le classique 32 bits cas) sont utilisés pour le texte du processus (c'est-à-dire le code) et les données. Une copie vers ou depuis l'espace utilisateur est exécutée par le code du noyau qui s'exécute au nom du processus et en fait c'est le mappage de la mémoire (c'est-à-dire les tables de pages) de ce processus qui sont en cours d'utilisation pendant la copie. Cela se produit pendant que l'exécution est en mode noyau - c'est-à-dire en mode privilégié/superviseur en langage x86. En supposant que le code de l'espace utilisateur a passé un emplacement cible légitime (c'est-à-dire une adresse correctement mappée dans cet espace d'adressage de processus) pour que les données soient copiées, copy_to_user , exécuté à partir du contexte du noyau serait capable d'écrire normalement à cette adresse/région sans problèmes et après le retour du contrôle à l'utilisateur, l'espace utilisateur peut également lire à partir de cet emplacement configuré par le processus lui-même pour commencer. Des détails plus intéressants peuvent se trouvent dans les chapitres 9 et 10 de Understanding the Linux Kernel, 3rd Edition, By Daniel P. Bovet, Marco Cesati. En particulier, access_ok() est un contrôle de validité nécessaire mais pas suffisant. L'utilisateur peut toujours transmettre des adresses n'appartenant pas à l'espace d'adressage du processus. Dans ce cas, une exception Page Fault se produira pendant que le code du noyau exécute la copie. La partie la plus intéressante est la façon dont le gestionnaire de défauts de page du noyau détermine que le défaut de page dans ce cas n'est pas dû à un bogue dans le code du noyau mais plutôt à une mauvaise adresse de l'utilisateur (surtout si le code du noyau en question provient d'un module du noyau chargé).


Linux
  1. Comment rechercher sur le Web à partir d'un terminal sous Linux

  2. Comment fonctionne le Sticky Bit ?

  3. Comment calculer l'utilisation CPU d'un processus par PID sous Linux à partir de C ?

  4. Le noyau Linux 3.x utilise-t-il le planificateur de processus CFS ?

  5. Comment Linux conserve-t-il le contrôle du processeur sur une machine monocœur ?

Comment changer la priorité d'un processus sous Linux

Comment construire le noyau Linux à partir de zéro

Comment fonctionne la mémoire d'échange sous Linux ?

Comment Linux charge-t-il l'image 'initrd' ?

Comment fonctionne une interface graphique Linux au niveau le plus bas ?

Comment fonctionne l'affichage de Linux ?