Page suivante - Page précédente - Table des matières

8. Informations Techniques

Pour ceux d'entre vous qui souhaitent comprendre comment marche la carte, ou jouer avec les pilotes actuels, ou même essayer de faire leur propre pilote pour une carte qui n'est actuellement pas supportée, ces informations peuvent se révéler utiles. Si vous n'entrez pas dans cette catégorie de personne, vous devriez peut-être sauter cette section.

8.1 Entrées/Sorties programmées contre mémoire partagée contre DMA

Si vous savez déjà envoyer et recevoir des paquets les uns derrière les autres, vous ne pouvez tout simplement pas mettre plus de bits sur le fil. Toutes les cartes Ethernet modernes peuvent recevoir des paquets les uns à la suite des autres. Les pilotes Linux DP8390 (wd80x3, SMC-ULTRA, 3c503, ne2000, etc) s'approchent très près de l'envoi de paquets les uns derrière les autres (cela dépendra du temps de latence d'interruption courant), et la 3c509 ou l'AT1500 n'ont absolument aucun problème pour émettre des paquets les uns derrière les autres.

Le bus ISA peut faire du 5,3 Mo/s (42 Mbit/s), ce qui semble plus que nécessaire pour l'ethernet a 10 Mbps. En cas d'utilisations de cartes 100 Mbps, il est clair que vous aurez à utiliser un bus plus rapide pour utiliser toute la bande passante.

Entrées/Sorties (E/S) programmées (NE2000, 3c509, etc.)

Pour : N'utilise aucune ressource système contrainte, juste quelques registres d'E/S, et n'a pas de limite à 16 M.

Contre : Généralement le taux de transfert le plus faible, le processeur attend tout le temps, et un accès entrelacé (interleaved en anglais) aux paquets est habituellement difficile voire impossible.

Mémoire partagée (WD80x3, SMC-Ultra, 3c503, etc.)

Pour : Simple, plus rapide que les E/S programmées, permet l'accès aléatoire aux paquets. Les pilotes Linux calculent la somme de contrôle (checksum en anglais) des paquets IP entrants lorsqu'ils sont copiés depuis la carte, ce qui entraîne une réduction supplémentaire de la charge du processeur par rapport à une carte équivalente en E/S programmées.

Contre : Utilise beaucoup d'espace mémoire (c'est important pour les utilisateur sous DOS, cela n'a pratiquement pas d'importance sous Linux), et charge encore le processeur.

Accès Direct à la Mémoire (DMA) Esclave (normal) (p.ex. : aucune pourLinux !)

Pour : Libère le processeur pendant le transfert réel des données.

Contre : La vérification des conditions aux limites de blocs, l'allocation de tampons (buffers en anglais) contigus, et la programmation des registres DMA en font la plus lente de toutes les techniques. Elle utilise en plus un canal DMA (une ressource rare !) et nécessite des tampons alignés en mémoire basse.

DMA en Bus Master (p.ex. : LANCE, DEC 21040)

Pour : Libère le processeur pendant le transfert des données, peut lier des tampons entre eux, peut nécessiter peu voire pas de perte de temps processeur sur le bus ISA. La majorité des pilotes bus-mastering pour linux utilisent un schéma 'copybreak' où les gros paquets sont directements placés dans les tampons réseau du noyau par la carte, les petits paquets étant copiés par le CPU qui est plus rapide pour ce type de traitements.

Contre : (seulement pour les cartes ISA) Nécessite des tampons en mémoire basse et un canal DMA pour les cartes. Tout Maître de Bus aura des problèmes avec les autres Maîtres de Bus qui sont des goinfres, comme certaines cartes SCSI primitives. Quelques jeux de puces pour cartes-mères mal pensés ont des problèmes avec les maîtres de bus. Et une raison pour n'avoir aucun type de périphérique DMA est d'utiliser un processeur 486 conçu pour être inséré (ou monté) en lieu et place d'un 386: ces processeurs doivent vider leur cache à chaque cycle DMA. (Ceci inclus les Cx486DLC, Ti486DLC, Cx486SLC, Ti486SLC, etc.)

8.2 Écriture d'un pilote de carte

La seule chose indispensable pour utiliser une carte Ethernet sous Linux est le pilote approprié. Pour que cela soit possible, il est essentiel que le constructeur diffuse les informations techniques nécessaires à la programmation de ce pilote à destination du public sans que vous (ou quelqu'un d'autre) ne soyez obligé de leur vendre votre âme. Une bonne indication des chances d'obtenir de la documentation (ou, si vous ne programmez pas, des chances que quelqu'un d'autre puisse écrire ce pilote dont vous avez vraiment, vraiment besoin) est la disponibilité du pilote en mode paquet de Crynwr (ex Clarkson). Russ Nelson dirige cette opération, et il a été d'un grand service par son aide au cours du développement de certains pilotes pour Linux. Vous pouvez essayer cette URL pour consulter le programme de Russ :

Pilote en mode paquet de Russ Nelson

Une fois la documentation obtenue, vous pouvez écrire un pilote pour votre carte et l'utiliser sous Linux (du moins en théorie). Rappelez-vous néanmoins que certains matériels anciens qui ont été créés pour des machines XT ne fonctionneront pas bien dans un environnement multitâches comme Linux. Leur utilisation entraînera des problèmes importants si votre réseau est raisonnablement chargé.

La plupart des cartes possèdent des pilotes pour des interfaces MS-DOS comme NDIS ou ODI, mais ceux-ci sont inutiles pour Linux. De nombreuses personnes ont suggéré de les intégrer directement ou de réaliser une traduction automatique, mais c'est quasiment impossible. Les pilotes MS-DOS s'attendent à travailler en mode 16 bits et à utiliser des `interruptions logicielles', deux notions incompatibles avec le noyau Linux. Cette incompatibilité est en fait un avantage, puisque certains pilotes pour Linux sont considérablement meilleurs que leur équivalent MS-DOS. Par exemple, la série des pilotes `8390' utilise des zones tampon de transmissions en ping-pong, qui commencent seulement à apparaître dans le monde MS-DOS.

(`Des zones tampon de transmissions en ping-pong' signifie que l'on utilise au moins deux zones de la taille maximale d'un paquet pour transmettre les paquets. L'une des zones est chargée pendant que la carte est en train de transmettre l'autre. Le deuxième paquet est alors transmis dès que le premier est parti, etc. De cette manière, la plupart des cartes sont capables d'envoyer des paquets à la dos à dos sur le câble).

Bon. Vous avez donc décidé d'écrire un pilote pour la carte Ethernet Machin, puisque vous avez les informations nécessaires à sa programmation, et que personne d'autre ne l'a encore fait (... ce sont les deux conditions principales ;-) ). Vous devriez commencer avec le squelette du pilote réseau qui est fourni avec la distribution source du noyau Linux. Il se trouve dans le fichier /usr/src/linux/drivers/net/skeleton.c dans tous les noyaux récents. Jetez aussi un coup d'oeil sur le `Kernel Hackers Guide' à l'URL suivante :

KHG

8.3 Inteface du pilote avec le noyau

Voici quelques notes sur les fonctions que vous devrez écrire si vous créez un nouveau pilote. Lisez-les en gardant sous la main le squelette de pilote décrit ci-dessus : cela simplifiera les choses.

Détection de la carte (Probe)

Appelée au démarrage pour vérifier l'existence de la carte. Meilleure si elle peut vérifier en douceur en lisant la mémoire etc. Peut aussi lire les ports d'E/S. Ecrire au démarrage sur les ports d'E/S pour détecter la carte n'est pas bien parce que cela risque de tuer un autre périphérique. Certaines parties de l'initialisation du périphérique sont habituellement faites à ce niveau (allouer l'espace d'E/S, les IRQ, remplir les champs de dev->???, etc.) Vous avez besoin de savoir à quels ports d'E/S et à quelles zones mémoire la carte peut être configurée, comment autoriser l'utilisation de mémoire partagée (si besoin), comment sélectionner et mettre en oeuvre la génération d'interruptions, etc.

Gestionnaire d'interruptions (Interrupt handler)

Appelé par le noyau quand la carte déclenche une interruption. A la responsabilité de déterminer pourquoi la carte a déclenché l'interruption, et d'agir en conséquence. Les conditions habituelles d'interruption sont l'arrivée de données, la fin d'une transmission, l'indication de conditions d'erreur. Vous avez besoin de connaître les bits d'informations liés à une interruption afin de pouvoir agir en conséquence.

Fonction de transmission (Transmit function)

Est liée à dev->hard_start_xmit() et est appelée par le noyau quand ce dernier désire envoyer des données par l'intermédiaire du périphérique. Envoie les données sur la carte et déclenche la transmission. Vous avez besoin de savoir comment empaqueter les données et comment les faire parvenir sur la carte (copie en mémoire partagée, transfert sur les ports d'E/S, DMA ?) et au bon endroit sur la carte. Puis vous devez savoir comment dire à la carte d'envoyer les données sur le câble, et (éventuellement) émettre une interruption quand ce sera fini. Quand le périphérique ne peut plus accepter de paquets supplémentaires, il doit armer le drapeau dev->tbusy. Quand de la place est devenue disponible, en général au cours d'une interruption de fin de transmission, dev->tbusy doit être désarmé et les niveaux supérieurs doivent être informés en utilisant mark_bh(INET_BH).

Fonction de réception (Receive function)

Appelée par le gestionnaire d'interruptions du noyau quand la carte indique que des données sont disponibles. Récupère les données de la carte, les empaquette dans un sk_buff et informe le noyau de la présence des données en effectuant un netif_rx(sk_buff). Vouz devez savoir comment mettre en oeuvre le déclenchement d'interruptions à la réception de données, comment vérifier les bits d'informations correspondant à la réception, et comment récupérer les données depuis la carte (là encore, par mémoire partagée, ports d'E/S, DMA, etc.)

Fonction d'ouverture (Open function)

Est liée à dev->open. Est appelée par les couches réseau quand quelqu'un fait ifconfig eth0 up - cela doit mettre le périphérique en route et l'autoriser à recevoir et transmettre des données. Toute incantation spéciale liée à l'initialisation et qui n'aurait pas été réalisée dans la séquence de détection (autoriser la génération d'IRQ, etc.) trouvera sa place ici.

Fonction de fermeture (facultative) (Close function)

Met la carte dans un état propre quand quelqu'un effectue ifconfig eth0 down. Doit libérer les IRQ et les canaux DMA si le matériel le permet, et éteindre tout ce qui pourrait économiser de l'énergie (comme le transmetteur).

Autres fonctions

Des éléments comme une fonction de réinitialisation, afin que, si les choses se dégradent, le pilote puisse essayer de réinitialiser la carte en dernier recours. Généralement fait quand une transmission dépasse son temps maximal ou quelque chose du genre. Ou encore une fonction pour lire les registres qui contiennent les statistiques sur la carte, si elle en comporte.

8.4 Informations techniques de 3Com

Si vous êtes intéressé(e) par l'écriture de pilotes pour les cartes 3Com, vous pouvez obtenir de la documentation technique de 3Com. Cameron a été suffisamment gentil pour nous dire comment y parvenir :

Les adaptateurs Ethernet de 3Com sont documentés pour les auteurs de pilotes dans nos `Références Techniques' (Technical References, TRs). Ces manuels décrivent les interfaces du programmeur avec la carte, mais elles ne parlent pas des diagnostics, des programmes d'installation, etc., que l'utilisateur final peut voir.

Le département marketing de la Division Adaptateurs Réseaux (Network Adapter Division) est responsable de la diffusion des TRs. Pour que ce programme reste efficace, nous le centralisons dans une entité appelée `CardFacts'. C'est est un système téléphonique automatisé. Vous l'appelez avec un téléphone à fréquences vocales et il vous envoie des choses par télécopie. Pour obtenir un TR, appelez CardFacts au 408-727-7021.

(NDT : Cela ne fonctionne qu'aux Etats-Unis.) Demandez le formulaire de commande du développeur (Developer's Order Form), le document numéro 9070. Ayez votre numéro de fax sous la main lorsque vous appelez. Complétez le formulaire de commande et envoyez-le par télécopie au 408-764-5004. Les manuels sont expédiés par le service J+2 de Federal Express.

Il y a des gens ici qui pensent que nous sommes trop libéraux avec les manuels, et qui cherchent des preuves que le système est trop onéreux, ou prend trop de temps et d'effort. Jusqu'à présent, les clients de 3Com ont été très bien sur ce point, et il n'y a pas de problème avec le niveau de demandes que nous avons obtenu. Nous avons besoin que votre coopération et votre retenue se maintiennent pour continuer ainsi.

8.5 Notes sur les cartes basées sur la puce PCnet / LANCE d'AMD

La puce LANCE (Local Area Network Controller for Ethernet, Contrôleur de Réseau Local pour Ethernet) d'AMD constituait l'offre initiale, et a depuis été remplacée par la puce `PCnet-ISA', aussi connue en tant que 79C960. Notez que le nom `LANCE' est resté, et certaines personnes se réfèrent à la nouvelle puce en utilisant l'ancien nom. Dave Roberts de la Division des Produits Réseaux (Network Products Division) d'AMD a eu l'amabilité de nous fournir les informations suivantes concernant cette puce :

`Fonctionnellement, elle est équivalente à une NE1500. Le jeu de registres est identique à celui de la vieille LANCE avec les additions de l'architecture 1500/2100. Les vieux pilotes 1500/2500 fonctionneront avec la PCnet-ISA. L'architecture NE1500 et NE2100 est la même à la base. Initialement Novell l'a appelé la 2100, mais ensuite a essayé de distinguer entre cartes coax et 10Base-T. Tout ce qui était purement 10Base-T devait être numéroté dans la série 1500. C'est la seule différence.

De nombreuses sociétés offrent des produits basés sur la PCnet-ISA, y compris HP, Racal-Datacom, Allied Telesis, Boca Research, Kingston Technology, etc. Les cartes sont à la base les mêmes, excepté que certains constructeurs ont ajouté des fonctionnalités `sans-cavaliers' (`jumperless') qui permettent à la carte d'être configurée par logiciel. La plupart n'en ont pas. AMD offre un paquetage de conception standard pour une carte qui utilise la PCnet-ISA et de nombreux fabricants utilisent notre conception sans changement. Cela signifie que n'importe qui souhaitant écrire des pilotes pour la plupart des cartes basées sur la puce PCnet-ISA peut se contenter d'obtenir la documentation technique auprès d'AMD. Appelez notre centre de distribution documentaire au (800)222-9323 et demandez la documentation de l'Am79C960, PCnet-ISA. Elle est gratuite.

Un moyen rapide pour savoir si la carte est une carte `générique' est simplement de la regarder. Si elle l'est, elle doit juste comporter une grosse puce, un quartz, une petite PROM d'adresse IEEE, éventuellement un support pour une ROM de démarrage, et un connecteur (1, 2 ou 3, selon les options de média offertes). Notez que s'il s'agit d'une carte coax, elle comportera aussi quelques composants pour le transceiver, mais ils devraient être près du connecteur et éloignés de la PCnet-ISA.'

Une note pour les bidouilleurs potentiels de cartes est que différentes implémentations de la LANCE effectuent le `redémarrage' de différentes façons. Certaines reprennent où elles s'étaient arrêtées dans l'anneau, et d'autres démarrent directement au début de l'anneau, comme si elles venaient d'être initialisées.

8.6 Multicast et Mode `Promiscuous'

Une des autres choses sur lesquels Donald a travaillé est l'implémentation des points d'entrée pour le multicast et le mode `promiscuous'. Tous les pilotes ISA publiés (c'est-à-dire pas les pilotes au stade `alpha') supportent aujourd'hui le mode promiscuous.

Donald écrit : Je commencerai par parler du mode `promiscuous', qui est conceptuellement facile à implémenter. Pour la plupart des matériels, vous n'avez qu'à positionner un bit de registre, et à partir de ce moment-là vous obtenez tous les paquets qui passent sur le fil. Bon, ce n'est pas vraiment aussi simple que cela ; pour certains matériels, vous devez arrêter la carte (en perdant potentiellement quelques paquets), la reconfigurer, puis la réactiver. Ok, ça c'est facile, donc je passe à quelque chose qui n'est pas aussi évident : le multicast. On peut le réaliser de deux façons :

  1. Utiliser le mode promiscuous, et un filtre de paquets comme celui de Berkeley (Berkeley packet filter, BPF). Le BPF est un langage à pile de comparaison de modèles (pattern matching stack), avec lequel vous écrivez un programme qui extrait les adresses qui vous intéressent. Son avantage est qu'il est très général et programmable. Son inconvénient est qu'il n'existe pas de moyen général pour le noyau d'éviter d'avoir à mettre en route le mode promiscuous et de passer chaque paquet qui circule sur le fil à travers tous les filtres de paquets qui se sont enregistrés. Consultez  Le Berkeley Packet Filter pour plus d'informations.
  2. Utiliser le filtre multicast que la plupart des puces Ethernet possèdent.

Je crois que je devrais donner une liste de ce que quelques cartes ou puces Ethernet fournissent :

 Puce/carte  Promiscuous  Filtre Multicast
 -----------------------------------------
 Seeq8001/3c501  Oui     Filtre binaire (1)
 3Com/3c509      Oui     Filtre binaire (1)
 8390            Oui     Hashage à six bits Autodin II (2) (3)
 LANCE           Oui     Hashage à six bits Autodin II (2) (3)
 i82586          Oui     Hashage à six bits Autodin II caché (2) (4)

  1. Ces cartes prétendent avoir un filtre, mais il s'agit d'un simple oui/non `accepte tous les paquets multicast', ou `n'accepte aucun paquet multicast'.
  2. AUTODIN II est le polynôme standard de contrôle Ethernet (somme de contrôle/checksum CRC). Dans ce principe, les adresses multicast sont hashées et recherchées dans une table de hashage. Si le bit correspondant est activé, ce paquet est accepté. Les paquets Ethernet sont conçus de telle façon que la partie matérielle pour réaliser ceci est triviale -- vous mémorisez juste (habituellement) six bits du circuit CRC (qui est nécessaire de toute façon pour la vérification d'erreur) après les six premiers octets (l'adresse de destination), et vous les utilisez comme index dans la table de hashage (six bits -- une table de 64-bits).
  3. Ces puces utilisent le hashage à six bits, et nécessitent que la table soit calculée et chargée par l'hôte. Cela signifie que le noyau doit comprendre le code pour le CRC.
  4. Le 82586 utilise le hashage à six bits de façon interne, mais il calcule la table de hashage lui-même à partir d'une liste d'adresses multicast à accepter.

Notez qu'aucune de ces puces ne réalise un filtrage parfait, et nous avons encore besoin d'un module de niveau intermédiaire pour réaliser le filtrage final. Notez aussi que dans chaque cas nous devons conserver une liste complète des adresses multicast acceptées pour recalculer la table de hashage quand elle change.

8.7 Le filtre de paquets de Berkeley (Berkeley Packet Filter -- BPF)

L'idée générale des développeurs est que la fonctionnalité du BPF ne doit pas être fournie par le noyau, mais doit se trouver dans une bibliothèque de compatibilité (dont on espère qu'elle servira peu).

Pour ceux qui ne seraient pas au courant : BPF (le Berkeley Packet Filter) est un mécanisme destiné à spécifier aux couches réseau du noyau quels paquets vous intéressent. Il est implémenté sous la forme d'un interpréteur d'un langage à pile spécialisé construit dans un niveau bas du code réseau. Une application passe un programme écrit dans ce langage au noyau, et le noyau exécute le programme sur chaque paquet entrant. Si le noyau possède plusieurs applications BPF, chaque programme est exécuté sur chaque paquet.

Le problème est qu'il est difficile de déduire quel type de paquet intéresse réellement l'application à partir du programme de filtrage, donc la solution est de toujours exécuter le filtre. Imaginez un programme qui enregistre un programme BPF pour extraire un flux de données de faible débit envoyé à une adresse multicast. La plupart des cartes Ethernet possèdent un filtre d'adresses multicast implémenté sous la forme d'une table de hashage à 64 entrées qui ignore la plupart des paquets multicast non souhaités, donc les capacités existent pour faire de cette opération une opération peu coûteuse en ressources. Mais avec le BPF, le noyau doit passer l'interface en mode promiscuous, recevoir tous les paquets, et les passer à travers ce filtre. D'ailleurs, c'est un travail qu'il est très difficile de comptabiliser dans le processus qui a demandé les paquets.


Page suivante - Page précédente - Table des matières