Comment une interruption est-elle gérée sous Linux?

35

Je sais juste que Interruptc'est une hardware signal assertioncause dans une broche de processeur. Mais j'aimerais savoir comment le système d'exploitation Linux le gère.
Que se passe-t-il quand une interruption survient?

Sen
la source
tldp.org/LDP/tlk/dd/interrupts.html explique tout sur la question que vous avez posée
John

Réponses:

40

Voici une vue de haut niveau du traitement de bas niveau. Je décris une architecture typique simple, les architectures réelles peuvent être plus complexes ou différer d'une manière qui n'a pas d'importance à ce niveau de détail.

Lorsqu'une interruption survient, le processeur vérifie si les interruptions sont masquées. S'ils le sont, rien ne se passe jusqu'à ce qu'ils soient démasqués. Lorsque les interruptions deviennent non masquées, s'il y a des interruptions en attente, le processeur en choisit une.

Ensuite, le processeur exécute l'interruption en se connectant à une adresse particulière en mémoire. Le code à cette adresse s'appelle le gestionnaire d'interruption . Lorsque le processeur s'y branche, il masque les interruptions (le gestionnaire d'interruptions dispose donc d'un contrôle exclusif) et enregistre le contenu de certains registres à un endroit donné (généralement d'autres registres).

Le gestionnaire d'interruptions fait ce qu'il doit faire, généralement en communiquant avec le périphérique qui a déclenché l'interruption pour envoyer ou recevoir des données. Si l'interruption a été déclenchée par le minuteur, le gestionnaire peut déclencher le planificateur de système d'exploitation pour passer à un autre thread. Lorsque le gestionnaire a terminé son exécution, il exécute une instruction spéciale retour-d'interruption qui restaure les registres sauvegardés et annule les interruptions.

Le gestionnaire d'interruptions doit être exécuté rapidement, car il empêche toute autre interruption de s'exécuter. Dans le noyau Linux, le traitement des interruptions est divisé en deux parties:

  • La «moitié supérieure» est le gestionnaire d'interruptions. Il fait le minimum nécessaire, communique généralement avec le matériel et définit un indicateur quelque part dans la mémoire du noyau.
  • La «partie inférieure» effectue tout autre traitement nécessaire, par exemple copier des données dans la mémoire de processus, mettre à jour les structures de données du noyau, etc. Elle peut prendre du temps et même bloquer l'attente d'une autre partie du système car il fonctionne avec des interruptions activées.

Comme d'habitude à ce sujet, pour plus d'informations, lisez Pilotes de périphérique Linux ; le chapitre 10 concerne les interruptions.

Gilles, arrête de faire le mal
la source
22

Gilles a déjà décrit le cas général d’une interruption. Ce qui suit s’applique spécifiquement à Linux 2.6 sur une architecture Intel (une partie de celle-ci est également basée sur les spécifications d’Intel).

Une interruption est un événement qui modifie la séquence d'instructions exécutées par le processeur.
Il y a deux types d'interruptions:

  • Interruption synchrone (exception) produite par la CPU lors du traitement des instructions
  • Interruption asynchrone (interruption) émise par d'autres périphériques matériels

Les exceptions sont causées par des erreurs de programmation (fe Divide erreur , page défaut , débordement ) qui doit être pris en charge par le noyau. Il envoie un signal au programme et tente de remédier à l'erreur.

Les deux exceptions suivantes sont classées:

  • Exception détectée par le processeur générée par la CPU lors de la détection d'une condition anormale; divisés en trois groupes: Les défauts peuvent généralement être corrigées, les pièges font état d' une exécution, Abandonne sont des erreurs graves.
  • Exception programmée demandée par le programmeur, traitée comme un piège.

Les interruptions peuvent être émises par des périphériques d'E / S (clavier, carte réseau, ..), des minuteries et par d'autres processeurs (sur les systèmes multiprocesseurs). Lorsqu'une interruption survient, la CPU doit arrêter son instruction en cours et exécuter la nouvelle interruption. Il doit sauvegarder l'ancien état de processus interrompu pour le (probablement) le reprendre après le traitement de l'interruption.

La gestion des interruptions est une tâche délicate:

  • Des interruptions peuvent survenir à tout moment, le noyau tente de les écarter le plus rapidement possible.
  • Une interruption peut être interrompue par une autre interruption
  • Il y a des régions dans le noyau qui ne doivent pas du tout être interrompues

Deux niveaux d'interruption différents sont définis:

  • Interruptions masquables émises par des périphériques d’E / S; peut être dans deux états, masqué ou non masqué. Seules les interruptions non masquées sont traitées.
  • Interruptions non masquables ; dysfonctionnements critiques (par exemple, défaillance matérielle); toujours traité par la CPU.

Chaque périphérique matériel possède sa propre ligne de requête d'interruption (IRQ). Les IRQ sont numérotés à partir de 0. Toutes les lignes IRQ sont connectées à un contrôleur d'interruption programmable (PIC). Le PIC écoute les IRQ et les affecte à la CPU. Il est également possible de désactiver une ligne IRQ spécifique.
Les systèmes Linux modernes multitraitement incluent généralement le plus récent Advanced PIC (APIC), qui distribue les demandes IRQ de manière égale entre les processeurs.

L'étape intermédiaire entre une interruption ou une exception et son traitement est la table de descripteur d'interruption (IDT). Cette table associe chaque vecteur d'interruption ou d'exception (un nombre) à un gestionnaire spécifié (par exemple, une erreur de division est gérée par la fonction divide_error()).

Grâce à l'IDT, le noyau sait exactement comment gérer l'interruption ou l'exception survenue.


Alors, qu'est-ce que le noyau quand une interruption se produit?

  • La CPU vérifie après chaque instruction s'il y a une IRQ du PIC (A)
  • Si tel est le cas, consulte l’IDT pour mapper le vecteur reçu sur une fonction
  • Vérifie si l'interruption a été émise par une source autorisée
  • Enregistre les registres du processus interrompu
  • Appelez la fonction correspondante pour gérer l'interruption
  • Chargez les registres récemment sauvegardés du processus interrompu et essayez de le reprendre.
remuer
la source
Pouvez-vous préciser "Le processeur vérifie après chaque instruction s'il existe une IRQ provenant du PIC (A)" . Comment ça se passe exactement? Est-ce que cela se rapportait à VIP-flag dans le registre des drapeaux ou quoi que ce soit? Merci d'avance
red0ct
7

Tout d’abord, les participants impliqués dans la gestion des interruptions sont les périphériques matériels, le contrôleur d’interruptions, le CPU, le noyau du système d’exploitation et les pilotes. Les périphériques matériels sont responsables de la génération d'interruptions. Ils affirment les lignes de demande d'interruption lorsqu'ils souhaitent attirer l'attention du noyau du système d'exploitation. Ces signaux sont multiplexés par le contrôleur d'interruption, qui est responsable de la collecte des signaux d'interruption. Il est également responsable de la détermination de l'ordre dans lequel les signaux d'interruption seront transmis à la CPU. Le contrôleur d'interruption peut désactiver temporairement une ligne de requête d'interruption (IRQL) et la réactiver (masquage IRQL). Le contrôleur d'interruption transmet les demandes d'interruption collectées à la CPU de manière séquentielle. La CPU après la fin de l'exécution de chaque instruction, la CPU vérifie s'il y a des demandes d'interruption en attente émanant du contrôleur d'interruptions. Si la CPU constate qu'il y a une demande en attente ET que le drapeau Interrupt Enable est activé dans le registre de contrôle de la CPU interne, la CPU commence la gestion des interruptions. Comme vous pouvez le constater, en manipulant l'indicateur Interrupt dans la CPU et en communiquant avec le contrôleur d'interruptions, le noyau Linux est en mesure de contrôler l'acceptation des interruptions. Par exemple, Linux peut désactiver l'acceptation des interruptions provenant du périphérique particulier ou désactiver l'acceptation des interruptions. Le noyau Linux est capable de contrôler l'acceptation des interruptions. Par exemple, Linux peut désactiver l'acceptation des interruptions provenant du périphérique particulier ou désactiver l'acceptation des interruptions. Le noyau Linux est capable de contrôler l'acceptation des interruptions. Par exemple, Linux peut désactiver l'acceptation des interruptions provenant du périphérique particulier ou désactiver l'acceptation des interruptions.

Que se passe-t-il lorsque le processeur reçoit une demande d'interruption? Premièrement, le processeur désactive automatiquement les interruptions en réinitialisant l'indicateur d'interruption. Ils seront réactivés une fois que la gestion des interruptions sera terminée. Dans le même temps, la CPU effectue très peu de travail pour passer de la mode utilisateur au mode noyau de la CPU, de manière à lui permettre de reprendre l’exécution du code interrompu. La CPU consulte des structures de contrôle spéciales remplies par le noyau Linux pour trouver une adresse de code à laquelle le contrôle sera transmis. Cette adresse est l'adresse de la première instruction du gestionnaire d'interruptions, qui fait partie du noyau Linux.

Lors de la première étape de la gestion des interruptions, le noyau identifie le vecteur d’interruption reçu pour identifier le type d’événement survenu dans le système. Le vecteur d'interruption définit les actions que Linux va entreprendre pour le gérer. Dans un deuxième temps, Linux enregistre le reste des registres de la CPU (qui n’ont pas été sauvegardés automatiquement par la CPU) et qui peuvent éventuellement être utilisés par le programme interrompu. Cette action est très importante car elle permet à Linux de gérer les interruptions de manière transparente par rapport au programme interrompu. Dans une troisième étape, Linux passe en mode noyau en définissant l'environnement du noyau et en définissant l'état de la CPU requis. Et finalement, le gestionnaire d'interruptions dépendant du vecteur est appelé. (Vous pouvez consulter la macro BUILD_INTERRUPT3 dans arch \ x86 \ kernel \ entry_32. S pour saisir les détails supplémentaires pour l'exemple relatif à l'architecture x86) Dans le cas de périphériques, il s'agit d'une routine do_IRQ (). (Regardez dans l'arch \ x86 \ kernel \ irq.c)

Le gestionnaire d'interruption dépendant du vecteur est généralement encapsulé par des appels à irq_enter () et irq_exit (). La zone de code comprise dans une paire de ces fonctions est atomique par rapport à toute autre zone similaire et est également atomique par rapport à des paires de cli / sti. Irq_enter () et irq_exit () capturent également certaines statistiques relatives à la gestion des interruptions. Enfin, le noyau examine la table vector_irq pour trouver le numéro irq attribué au vecteur de l'interruption reçue et appelle handle_irq () (depuis arch \ x86 \ kernel \ irq_32.c).

À ce stade, la partie commune de la gestion des interruptions sous Linux se termine, car le noyau considère la routine de gestionnaire d'interruptions dépendante du périphérique installée par le pilote de périphérique comme faisant partie du descripteur irq et l'appelle. Si ce gestionnaire n'a pas été installé par le pilote, le noyau ne fait qu'acquitter l'interruption sur le contrôleur d'interruption et quitte le gestionnaire d'interruption général.

Après la fin de la gestion des interruptions, le noyau restaure l'état du programme qui avait été interrompu précédemment et reprend l'exécution du programme.

ZarathustrA
la source
CPU consults with special CPU control structures filled by Linux kernel to find an address of code to which control will be passed.Oui! Je me demande ce que sont ces structures de contrôle spéciales ...
automate
3

Du point de vue de la théorie, presque tout a été expliqué. Mais si vous recherchez des explications sur le framework de code de gestion des interruptions du noyau, cliquez sur le lien suivant si vous: Un code va dans la gestion des interruptions du noyau

Et si vous étudiez toujours la théorie des interruptions et des gestionnaires d'interruptions, je vous recommande de lire ceci: Comprendre les interruptions et les gestionnaires d'interruptions

Trukna
la source