Annexe

C'est en quelque sorte un réseau Plug-and-Play développé par Microsoft mais utilisable sous Linux. Vous connectez quelque chose sur un réseau et ce quelque chose n'a pas besoin d'être configuré mais ne va communiquer qu'avec des périphériques UPnP du réseau. Ici, « configurer » est utilisé dans le sens large et ne signifie pas simplement configurer les ressources bus. Un des objectifs est de permettre au gens connaissant peu de choses sur les réseaux ou sur la configuration et l'installation d'un routeur, d'une passerelle, d'une imprimante réseau, et cætera de le faire. Une utilisation majeure de UPnP serait dans les réseaux sans-fil.

UPnP utilise :

Ce guide pratique ne couvre pas UPnP. UPnP pour Linux est supporté par Intel qui a développé un logiciel spécifique. Il existe d'autres programmes qui font à peu près la même chose que UPnP. Une comparaison de ceux-ci est disponible sur http://www.cs.umbc.edu/~dchakr1/papers/mcommerce.html. Un projet UPnP pour Linux se trouve sur Sourceforge : Kit UPnP pour Linux

Il existe trois types d'adresses : adresses en mémoire principale, adresses d'entrées/sorties (ports) et adresses de configuration. Sur le bus PCI, les adresses de configuration constituent une plage d'adresses séparée un peu comme les adresses d'entrées/sorties. Sauf dans le cas compliqué des adresses de configuration ISA, qu'une adresse sur le bus soit ou non une adresse en mémoire principale, une adresse d'entrées/sorties ou une adresse de configuration dépend seulement du voltage sur certains fils du bus. Pour plus de détails sur les adresses de configuration du bus ISA, voir la section intitulée « Adresses de configuration du bus ISA (Port de lecture et cætera) ».

Ceci est différent des espaces d'adresses mémoire et d'entrées/sorties parce que l'espace d'adresses de configuration est « géographique ». Chaque emplacement d'une carte a un numéro d'emplacement faisant parti de l'adresse. De cette façon, Linux (ou le BIOS) peut adresser un certain emplacement et trouver le type de carte fiché dans cet emplacement. Chaque périphérique a des registres standards de 64 bits et quelques uns d'entre eux contiennent des numéros qui peuvent identifier de façon non ambiguë le périphérique. Comme le nombre d'emplacements est limité comme le sont le nombre de périphériques PCI construit dans la carte mère, Linux (ou le BIOS) a besoin de vérifier un nombre limité d'adresses pour trouver tous les périphériques PCI. S'il ne lit que des uns (0xFF en hexadécimal) à partir du premier registre d'un périphérique, alors cela signifie qu'aucun périphérique n'est présent. Comme il n'y a aucune carte ou périphérique fournissant tous les numéros un (0xFF), le « host bridge » PCI sur la carte mère fournit ce numéro pour tous les périphériques inexistants.

Le numéro d'emplacement PCI est appelé (dans le jargon PCI le numéro de périphérique et comme une carte peut avoir au plus huit périphériques sur elle, un numéro de fonction (allant de 0 à 7) identifie le périphérique qui se trouve sur une carte PCI. Ces numéros font partie de l'adresse géographique. Les développeurs Linux l'appellent pci-slot-name. Du coup, ce que Linux appelle un périphérique est en fait une fonction dans le jargon PCI. Le numéro du bus PCI (souvent 00) devient aussi une partie de l'adresse géographique. Par exemple, 0000:00:0d.2 correspond au bus PCI 0, emplacement 0, fonction 2. Pour l'adresse géographique complète, vous devez inclure le numéro sur deux mots des registres de configuration du périphérique auquel on veut l'accès. Les 0000 en tête (en 1999) étaient réservés pour une utilisation future.

Comment le processeur désigne-t-il qu'une lecture ou une écriture doit se faire dans l'espace de configuration PCI ? Il ne le fait pas, en tout cas pas directement. À la place lorsque l'accès à l'espace de configuration est désiré, il fait une écriture sur 32 bits (un mot double) pour écrire 0cf8-0cfb en espace d'entrées/sorties et écrit l'adresse géographique complète ici. Le host bridge PCI écoute à cette adresse et nous assure que la prochaine écriture de données sera 0cfc-0cff. C'est enregistré dans des registres de configuration du périphérique spécifié. Le pont fait les deux en envoyant un signal spécial à la carte PCI spécifiée (ou ce qui y ressemble) sur un fil dédié qui va seulement à l'emplacement où la carte est connectée. Il place aussi des bits sur le bus de contrôle indiquant que ce qui est sur le bus d'adresse maintenant est une adresse géographique de l'espace de configuration.

Pourquoi ne pas faire simple et demander simplement au processeur de placer les bits sur le bus de contrôle pour indiquer que l'adresse sur le bus principal est une adresse géographique pour la configuration du PCI ? Et bien, la plupart des processeurs ne sont pas capables de le faire donc le « host bridge » PCI le fait à la place.

Ces adresses sont aussi connues comme les « ports d'auto-configuration ». Pour le bus ISA, il n'existe pas techniquement de plage d'adresses de configuration, mais le CPU utilise une façon spéciale d'accéder aux registres de configuration PnP sur les cartes PnP. Dans ce but, trois adresses d'entrées/sorties sont allouées et chacune adresse un seul octet (il n'y a pas à proprement parler d'espace ou de plage). Il ne s'agit pas de trois adresses pour chaque carte mais de trois adresses partagées par toutes les cartes ISA-PnP.

Ces trois adresses sont nommées port de lecture (read-port), port d'écriture (write-port) et port d'adresse (address-port). Chaque port a une taille d'un octet. Chaque carte PnP dispose d'un grand nombre de registres de configuration, donc même les trois adresses ne sont pas suffisantes pour les registres de configuration d'une seule carte. Pour résoudre ce problème, chaque carte se voit affecter un numéro de carte en utilisant une technique appelée « isolation ». Voir la section intitulée « Isolation ISA » pour des détails plus complexes.

Ensuite, pour configurer une certaine carte, son numéro de carte est envoyé via l'adresse du port d'écriture pour indiquer à cette carte qu'elle doit écouter sur son port d'adresse. Toutes les autres cartes notent que ce n'est pas leur numéro de carte et donc n'écoutent pas. Ensuite, l'adresse d'un registre de configuration est envoyé sur le port d'adresse (à toutes les cartes, mais une seule écoute). Enfin, le transfert de données prend place avec ce registre de configuration sur cette carte soit en faisant une lecture sur le port de lecture soit en faisant une écriture sur le port d'écriture.

Le port d'écriture est toujours A79 et le port d'adresse est toujours 279 (en hexadécimal). Le port de lecture n'est pas fixe mais dépend du logiciel de configuration (tout en restant dans la plage 203-3FF) qui avec un peu de chance n'entrera pas en conflit avec les autres cartes ISA. Si un conflit se déclare, il changera l'adresse. Toutes les cartes PnP sont « programmées » avec cette adresse. Donc, si vous utilisez isapnp pour enregistrer ou connaître la configuration, celui-ci doit d'abord déterminer l'adresse du port de lecture.

Les interruptions amènent beaucoup d'informations mais seulement indirectement. Le signal de demande d'interruption (un voltage sur un fil) envoyé par un matériel indique seulement au composant, appelé le contrôleur d'interruption, qu'un certain périphérique demande l'attention. Le contrôleur d'interruption envoie le signal au CPU. Le CPU s'interrompt dans ce qu'il faisait, trouve le pilote de ce périphérique et exécute une partie de celui-ci nommée « routine d'interruption » (ou « gestionnaire d'interruption »). Cette « routine » essaie de trouver ce qui est arrivé et gère ensuite le problème. Par exemple, le périphérique peut avoir besoin d'envoyer/recevoir des octets. Ce programme (cette routine) peut facilement comprendre ce qui s'est passé car le périphérique dispose de registres disponibles sur des adresses connues par le pilote (à condition que le numéro d'IRQ et que les adresses d'entrées/sorties soient correctement configurés). Ces registres contiennent l'état du périphérique. Le logiciel lit le contenu de ces registres et en inspectant le contenu, trouve ce qui est arrivé et réalise l'action appropriée.

Donc, chaque pilote de périphérique a besoin de savoir le numéro d'interruption (IRQ) où écouter. Sur le bus PCI (et dans certains cas spéciaux, sur le bus ISA), il est possible que deux (voire plus) périphériques partagent le même numéro d'IRQ. Notez que vous ne pouvez pas partager une interruption PCI avec une interruption ISA (y a-t'il des exceptions ?). Quand une interruption partagée est lancée, le processeur exécute toutes les routines du service d'interruption séquentiellement pour tous les périphériques utilisant cette interruption. La première action qu'entreprend la première routine lancée est de vérifier les registres du périphérique pour voir si une interruption a été générée par son périphérique. S'il se trouve que ce n'est pas le cas (fausse alarme), il s'arrêtera immédiatement et la prochaine routine commence pour le deuxième périphérique qui utilise cette même interruption, et cætera. Il vérifie le périphérique comme décrit ci-dessus. Cette séquence est répétée jusqu'à la découverte du périphérique qui a lancé cette interruption. Toutes les routines d'interruption pour une interruption constituent une chaîne. Donc, la chaîne est traversée jusqu'à ce qu'une routine de la chaîne réclame l'interruption en disant : cette interruption est pour moi. Après avoir géré l'interruption, les routines suivantes du service d'interruption ne sont pas exécutées.

Mettre un certain voltage sur une ligne IRQ revient seulement à demander que le CPU s'interrompe de façon à exécuter la routine du pilote du périphérique. Dans pratiquement tous les cas, le CPU est interrompu par la requête. Mais les interruptions du CPU peuvent être temporairement désactivées ou « faire la queue », et donc, dans de rares cas, une interruption peut ne pas être gérée (ou peut subir un certain délai). Donc, ce qui a été auparavant appelé une interruption est plus précisément une « demande d'interruption », ce qui explique l'acronyme d'IRQ (« Interrupt ReQuest », c'est-à-dire ReQuête d'Interruption).

L'indication précédente, à savoir que les pilotes de périphérique écoutent leur interruption, était une explication très simplifiée. En fait, il s'agit d'un composant (ou d'une partie d'un composant) embarqué sur la carte-mère, appelé le contrôleur d'interruptions. Il va écouter toutes les interruptions. Quand le contrôleur récupère une interruption, il envoie un signal au CPU pour lancer la routine du service d'interruption du pilote de périphérique approprié pour gérer cette interruption.

Il existe différents types de contrôleurs d'interruptions. L'un d'entre eux est l'APIC (acronyme de Advanced Programmable Interrupt Controller) qui a habituellement des broches en entrée pour un grand nombre d'interruptions, y compris les interruptions PCI. Les anciens contrôleurs ont seulement des broches pour les interruptions ISA mais ils peuvent toujours gérer les interruptions PCI car il s'agit d'un routeur programmable d'interruptions qui convertit les interruptions PCI en interruptions ISA et les envoie vers certaines broches (c'est-à-dire vers certaines IRQ).

C'est uniquement pour l'ancien bus ISA. L'isolation est une méthode complexe d'affectation d'un point temporaire (numéro d'identifiant ou CSN, Card Select Number) à chaque périphérique PnP du bus ISA. Comme il existe des moyens plus efficaces (mais plus complexes) de le faire, certains pourraient dire qu'il s'agit d'une méthode simple. Seule une adresse d'écriture est utilisée pour les écritures PnP vers tous les périphériques pour que toutes les écritures vers cette adresse aillent sur tous les périphériques PnP. Cette adresse d'écriture est utilisé pour envoyer (affecter) un numéro de carte unique à chaque périphérique PnP. Pour être assigné, ce numéro de carte nécessite qu'un seul périphérique soit en écoute lorsque le numéro de carte est envoyé (écrit) à cette adresse commune. Tous les périphériques PnP ont un numéro de série unique qu'ils utilisent lors du processus d'isolation. Faire l'isolation est comme un jeu. Cela se fait en utilisant l'équivalent d'un bus commun de fils connectant tous les périphériques PnP au programme d'isolation.

Pour le premier tour du « jeu », tous les périphériques PnP écoutent sur ce fil et envoient simultanément une séquence de bits sur le fil. Les bits autorisés sont soit un 1 (voltage positif) soit un « 0 ouvert » sans voltage (circuit ouvert ou trois-états). Pour cela, chaque périphérique PnP commence à envoyer séquentiellement son numéro de série sur ce fil, voltage (circuit ouvert ou trois-états). Pour faire cela, chaque périphérique PnP lance simplement son numéro de série sur les fils, bit à bit, en commençant par le plus haut. Si un périphérique envoie un 1, un 1 sera entendu par tous les autres périphériques. Si tous les périphériques envoient un « 0 ouvert », rien ne sera entendu sur le fil. Le but est d'éliminer (à la fin du premier tour) tous les périphériques sauf celui possédant le numéro de série le plus important. « Éliminer » signifie enlever de ce tour du jeu et donc cesser temporairement d'écouter tout ce qui passe sur le fil. (Notez que tous les numéros de série ont la même taille.) Quand il ne reste qu'un seul périphérique en écoute, un numéro de carte lui est donné.

Tout d'abord, considérez seulement le bit le plus haut du numéro de série qui est placé sur le fil par tous les périphériques qui n'ont pas encore de numéro de carte. Si un périphérique PnP envoie un 0 (0 ouvert) mais entend un 1, cela signifie qu'un ou plusieurs autres périphériques PnP a un numéro de série plus important, donc il se supprime temporairement pour ce tour. Maintenant, les périphériques restant en jeu (pour ce tour) ont tous le même bit de haut niveau (un 1), donc nous pouvons supprimer ce bit et continuer avec le « reste du numéro de série » pour la suite du tour. Ensuite, recommencez depuis le début de ce paragraphe et répétez jusqu'à ce que le numéro de série soit examiné en entier pour chaque périphérique (voir plus bas pour les cas « tous à 0 »).

Donc, il est clair que seules les cartes avec un petit numéro de série sont éliminées lors d'un tour. Mais qu'arrive-t-il si tous les périphériques du jeu envoient un 0 comme leur bit de haut niveau ? Dans ce cas, un « 0 ouvert » est envoyé sur la ligne et tous les participants restent en lice. S'ils ont tous un 0 au début, alors les 0 sont supprimés comme les 1 du paragraphe ci-dessus. Le jeu continue alors avec le bit suivant du numéro de série).

A la fin du tour (après que le dernier bit ait été envoyé), seul un périphérique PnP, celui possédant le plus haut numéro de série, reste en jeu. Il se voit attribuer un numéro de carte et quitte le jeu définitivement. Ensuite, tous les autres périphériques du tour précédent (qui n'ont donc pas de numéro de carte) reviennent dans le jeu et un nouveau tour commence, avec un participant en moins. Éventuellement, tous les périphériques PnP se voient assigner un numéro de carte. Il est facile de prouver que cet algorithme fonctionne. L'algorithme actuel est un peu plus complexe que celui présenté ci-dessus car chaque étape est répétée deux fois pour s'assurer, et ces répétitions sont faites d'une façon un peu différente (mais en utilisant la même idée de base).

Une fois tous les numéros de carte assignés, ils sont utilisés pour s'adresser à chaque périphérique PnP pour envoyer/lire des données de configuration. Notez que ces numéros de carte sont seulement utilisés pour la configuration PnP et ne sont pas utilisés pour les communications normales avec le périphérique PnP. Lorsque l'ordinateur démarre, un BIOS PnP fera l'isolation puis s'occupera de la configuration PnP. Après ça, tous les numéros de carte sont « perdus » d'une telle façon que si quelqu'un veut changer (ou inspecter) la configuration une nouvelle fois, l'isolation devra être refaite intégralement.

Si un bus dispose d'une fonctionnalité de maîtrise du bus, il est peu probable que des ressources seront nécessaires pour le DMA sur ce bus. Par exemple, le bus PCI n'a pas besoin des ressources DMA car il dispose de cette fonctionnalité. Néanmoins, la « maîtrise du bus » est souvent appelée DMA. Mais, comme il ne s'agit pas strictement de DMA, il ne nécessite aucune ressource DMA. Les bus locaux ISA et VESA n'ont pas de maîtrise du bus. Les anciens bus MCU et EISA l'avaient.