diff options
Diffstat (limited to 'fr_FR.ISO8859-1/articles/ddwg/article.sgml')
-rw-r--r-- | fr_FR.ISO8859-1/articles/ddwg/article.sgml | 1861 |
1 files changed, 0 insertions, 1861 deletions
diff --git a/fr_FR.ISO8859-1/articles/ddwg/article.sgml b/fr_FR.ISO8859-1/articles/ddwg/article.sgml deleted file mode 100644 index 012e35654a..0000000000 --- a/fr_FR.ISO8859-1/articles/ddwg/article.sgml +++ /dev/null @@ -1,1861 +0,0 @@ -<!-- - The FreeBSD Documentation Project - The FreeBSD French Documentation Project - - $Id: article.sgml,v 1.1 2000-06-01 19:14:23 gioria Exp $ - Original revision: n.nn ---> - -<!DOCTYPE ARTICLE PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [ -<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"> %man; -<!ENTITY % urls PUBLIC "-//FreeBSD//ENTITIES Common Document URL Entities//FR"> %urls; -<!ENTITY % abstract PUBLIC "-//FreeBSD//ENTITIES DocBook Abstract Entities//FR"> %abstract; -<!ENTITY % artheader PUBLIC "-//FreeBSD//ENTITIES DocBook ArtHeader Entities//FR"> %artheader; -<!ENTITY % translators PUBLIC "-//FreeBSD//ENTITIES DocBook Translator Entities//FR"> %translators; - -<!ENTITY % authors SYSTEM "../../../en_US.ISO_8859-1/books/handbook/authors.ent"> %authors; -<!ENTITY % mailing-lists SYSTEM "../../books/handbook/mailing-lists.ent"> %mailing-lists; - <!ENTITY rel.current CDATA "3.2"> -]> - - -<article lang="fr"> - <artheader> - <title>Le guide de l'auteur de pilotes de périphériques pour FreeBSD</title> - <authorgroup> - <author> - <firstname>Eric L.</firstname> - <surname>Hernes</surname> - </author> - </authorgroup> - &artheader.copyright; - <abstract> - <para><email>erich@rrnet.com</email></para> - <para>29 Mai 1996</para> - <para>Ce document décrit comment ajouter un module de gestion de -périphérique à FreeBSD. Il <emphasis>n'est pas</emphasis> destiné pour être un -cours d'instruction sur des modules de gestion de périphérique -d'Unix en général. Il est destiné pour les auteurs de module de -gestion de périphérique, au courant du modèle de module de gestion -de périphérique d'Unix, pour travailler sur FreeBSD. - </para> - &abstract.license; - &abstract.disclaimer; - &trans.a.dntt; - </abstract> - </artheader> - - -<sect1> -<title>Spécificité de FreeBSD2.x</title> - -<para>Dû aux changements de FreeBSD avec le temps, ce guide est -seulement précis en ce qui concerne FreeBSD 2.x. Un guide de -rechange pour FreeBSD 3.x et au-delà est en train d'être écrit. -Contactez Jeroen Ruigrok <email>asmodai@wxs.nl</email> si -vous voulez l'aider à ce sujet. -</para> -</sect1> - - -<sect1> -<title>Généralité</title> - -<para> <emphasis>Le noyau de FreeBSD est très bien -documenté, malheureusement il est entièrement écrit en `C'.</emphasis> -</para> -</sect1> - -<sect1> -<title>Types de pilotes de module de périphériques.</title> - -<sect2> -<title>Caractère</title> - -<sect3> -<title>Structures de données</title> - -<para>Structure <citerefentry><refentrytitle>cdevsw</refentrytitle></citerefentry></para> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>d_open()</function></title> -<para> -<function>d_open()</function> prend plusieurs arguments, la liste formelle ressemble à -quelque chose comme : -</para> - -<programlisting> -int -d_open(dev_t dev, int flag, int mode, struct proc *p) -</programlisting> - -<para><function>d_open()</function> est appelé à <emphasis>chaque</emphasis> ouverture du périphérique.</para> - -<para>L'argument <citerefentry><refentrytitle>dev</refentrytitle></citerefentry> contient le nombre majeur et mineur du -périphérique ouvert. Ils sont disponibles par les macros -<citerefentry><refentrytitle><function>major()</function></refentrytitle></citerefentry> et <citerefentry><refentrytitle><function>minor()</function></refentrytitle></citerefentry> -</para> - -<para>Les arguments <citerefentry><refentrytitle>flag</refentrytitle></citerefentry> et <citerefentry><refentrytitle>mode</refentrytitle></citerefentry> sont comme décrits sur -la page de manuel de -<ulink url="http://www.freebsd.org/cgi/man.cgi?open(2)">open</ulink>. -Il est recommandé que vous examiniez -ces derniers pour vous assurer des droits d'accès dans <sys/fcntl.h> -et faire ce qui est exigé. Par exemple si <citerefentry><refentrytitle>flag </refentrytitle></citerefentry> est -(O_NONBLOCK | O_EXLOCK) l'ouverture échouerait si il bloquait ou -si l'accès exclusif ne pouvait pas être accordé. -</para> - -<para> -L'argument <citerefentry><refentrytitle>p</refentrytitle></citerefentry> contient toutes les informations à propos du -processus actuel. -</para> -</sect4> - -<sect4> -<title><function>d_close()</function></title> -<para> <function>d_close()</function> prend la même liste d'argument que <function>d_open()</function>: -</para> - -<programlisting> -int -d_close(dev_t dev , int flag , int mode , struct proc *p) -</programlisting> - -<para><function>d_close()</function> est seulement appelé à la dernière fermeture de votre -périphérique (par périphérique mineur). Par exemple dans le fragment -suivant de code, <function>d_open()</function> est appelé 3 fois, mais <function>d_close()</function> -seulement une fois. -</para> - -<programlisting> - ... - fd1=open("/dev/mydev", O_RDONLY); - fd2=open("/dev/mydev", O_RDONLY); - fd3=open("/dev/mydev", O_RDONLY); - ... - <useful stuff with fd1, fd2, fd3 here> - ... - close(fd1); - close(fd2); - close(fd3); - ... -</programlisting> - -<para>Les arguments sont semblables à ceux décrits ci-dessus pour -<function>d_open()</function>. -</para> -</sect4> - -<sect4> -<title><function>d_read()</function> et <function>d_write()</function></title> - -<para><function>d_read()</function> et d_write prennent les listes suivantes d'argument: -</para> - -<programlisting> -int -d_read(dev_t dev, struct uio *uio, int flat) -int -d_write(dev_t dev, struct uio *uio, int flat) -</programlisting> - -<para> -Les points d'entrée de <function>d_read()</function> et de <function>d_write()</function> sont appelés quand -<ulink url="http://www.freebsd.org/cgi/man.cgi?read(2)">read</ulink> et -<ulink url="http://www.freebsd.org/cgi/man.cgi?write(2)">write</ulink> -sont appelés sur votre périphérique depuis l'espace utilisateur. Le transfert -des données peut être manipulé par la routine du noyau <function>uiomove()</function>. -</para> -</sect4> - -<sect4> -<title><function>d_ioctl()</function></title> - -<para> Sa liste d'argument est comme suit: -</para> -<programlisting> -int -d_ioctl(dev_t dev, int cmd, caddr_t arg, int flag, struct proc *p) -</programlisting> - -<para> -<function>d_ioctl()</function> est un fourre-tout pour les exécutions qui ne semblent -pas raisonnable dans un paradigme lecture/écriture. Le plus -célèbre de tout les ioctl est probablement celui sur des périphériques -tty, par le -<ulink url="http://www.freebsd.org/cgi/man.cgi?stty(1)">stty</ulink>. - -Le point d'entrée d'ioctl est appelé depuis l'<function>ioctl()</function> de -<filename>sys/kern/sys_generic.c</filename></para> - -<para> -Il y a quatre types différents d'ioctl qui peuvent être implémentés. - -<sys/ioccom.h> contient des macros pratiques de -pour définir ces ioctls. -</para> - -<itemizedlist> -<listitem> -<para><citerefentry><refentrytitle>_IO(g, n) </refentrytitle></citerefentry> pour les opérations de type contrôle. -</para> -</listitem> - -<listitem> -<para> -<citerefentry><refentrytitle>_IOR(g, n, t) </refentrytitle></citerefentry> pour des opérations lisant des données d'un -périphérique. -</para> -</listitem> - -<listitem> -<para> -<citerefentry><refentrytitle>_IOW(g, n, t) </refentrytitle></citerefentry> pour les opérations écrivant des données -sur un périphérique. -</para> -</listitem> - -<listitem> -<para> -<citerefentry><refentrytitle>_IOWR(g,n,t)</refentrytitle></citerefentry> pour les opérations écrivant sur un périphérique -puis lisent les données. -</para> -</listitem> -</itemizedlist> - - -<para> -Ici <citerefentry><refentrytitle>g </refentrytitle></citerefentry> se rapporte à un <emphasis>groupe </emphasis>/. C'est une valeur -de 8 bits, en général indicative du périphérique ; par exemple, 't' -est utilisé dans des ioctls de tty. <citerefentry><refentrytitle>n</refentrytitle></citerefentry> se -rapporte au nombre de l'ioctl dans le groupe. Sur SCO, ce seul nombre -dénote l'ioctl. <citerefentry><refentrytitle>t</refentrytitle></citerefentry> est le type de données qui sera -passé au pilote de périphérique; ceci est alors remis à un opérateur -<function>sizeof()</function> du noyau. L'appel système <function>ioctl()</function> fera soit un <function>copyin()</function> -soit un <function>copyout()</function> ou les deux à votre pilote, puis vous -renverra un pointeur à la structure de données dans l'argument -<citerefentry><refentrytitle>arg</refentrytitle></citerefentry> de l'appel d'd_ioctl. Actuellement la taille de -données est limitée à une page (4k sur l'i386). -</para> -</sect4> - -<sect4> -<title><function>d_stop()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>d_reset()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>d_devtotty()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>d_poll()</function> (3.0 et plus) ou <function>d_select()</function> (2.2)</title> - -<para>la liste d'argument de <function>d_poll()</function> est comme suit : -</para> - -<programlisting> -void -d_poll(dev_t dev, int events, struct proc *p) -</programlisting> - -<para> <function>d_poll()</function> est employé pour découvrir si un périphérique -est prêt pour les E/S. Par exemple, attendre que des données du réseau -soient dispnibles, ou que l'utilisateur presse une touche. -Cela correspond à un appel de <function>poll()</function> dans l'espace utilisateur. -</para> - -<para>L'appel à <function>d_poll()</function> devrait vérifier les événements -indiqués dans le masque d'évènement. Si aucun des événements demandés n'est -en activité, mais qu'elles pourraient devenir actif plus tard, il -devrait enregistrer ceci pour les actions futures du noyau. -<function>d_poll()</function> fait ceci en appelant <function>selrecord()</function> avec une structure -selinfo pour ce périphérique. La somme de toutes ces activités -ressemblent à quelque chose comme ceci: -</para> - -<programlisting> -static struct my_softc { - struct queue rx_queue; /* As example only - not required */ - struct queue tx_queue; /* As example only - not required */ - struct selinfo selp; /* Required */ -} my_softc[NMYDEV]; - -... - -static int -mydevpoll(dev_t dev, int events, struct proc *p) -{ - int revents = 0; /* Events we found */ - int s; - struct my_softc *sc = &my_softc[dev]; - - /* We can only check for IN and OUT */ - if ((events & (POLLIN|POLLOUT)) == 0) - return(POLLNVAL); - - s = <function>splhigh()</function>; - /* Writes are if the transmit queue can take them */ - if ((events & POLLOUT) && - !IF_QFULL(sc->tx_queue)) - revents |= POLLOUT; - /* ... while reads are OK if we have any data */ - if ((events & POLLIN) && - !IF_QEMPTY(sc->rx_queue)) - revents |= POLLIN; - if (revents == 0) - selrecord(p, &sc->selp); - splx(s); - return revents; -} -</programlisting> - -<para> <function>d_select()</function> est utilisé dans la version 2.2 et -précédentes de FreeBSD. Au lieu de 'events', il prend un simple -entier 'rw', qui peut être FREAD pour la lecture (comme dans -POLLIN ci-dessus), FWRITE pour l'écriture (comme dans POLLOUT ci-dessus), -et 0 pour 'exception' - lorsque quelque chose d'exceptionnel se produit, -comme une carte étant insérée ou retirée pour le pilote de -pccard. -</para> -<para>Pour 'select', le fragment correspondant à la description -ci-dessus ressembleraient à ceci: -</para> -<programlisting> -static int -mydevselect(dev_t dev, int rw, struct proc *p) -{ - int ret = 0; - int s; - struct my_softc *sc = &my_softc[dev]; - - s = <function>splhigh()</function>; - switch (rw) { - case FWRITE: - /* Writes are if the transmit queue can take them */ - if (!IF_QFULL(sc->tx_queue)) - ret = 1; - break; - case FREAD: - /* ... while reads are OK if we have any data */ - if (!IF_QEMPTY(sc->rx_queue)) - ret = 1; - break; - case 0: - /* This driver never get any exceptions */ - break; - } - if(ret == 0) - selrecord(p, &sc->selp); - splx(s); - return(revents); -} -</programlisting> -</sect4> - -<sect4> -<title><function>d_mmap()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>d_strategy()</function></title> - -<para> -La liste d'argument de <function>d_strategy()</function> est comme suit : -</para> - -<programlisting> -void -d_strategy(struct buf *bp) -</programlisting> - -<para><function>d_strategy()</function> est utilisé pour les périphériques utilisant -des E/S de type disperser-regrouper (<foreignphrase>scatter-gather</foreignphrase>). -C'est ce qu'il y a de plus courant dans un périphérique de bloc. -C'est sensiblement différent du modèle de système V, où seulement -le pilote de bloc fait une E/S de type disperser-regrouper. -Sous BSD, les périphériques de caractère sont parfois sommé d'exécuter -une E/S de type disperser-regrouper par l'intermédiaire des appels -systèmes <function>readv()</function> et <function>writev()</function>. -</para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>Bloc</title> - -<sect3> -<title>Structures de données</title> -<para> Structure <citerefentry><refentrytitle>struct bdevsw</refentrytitle></citerefentry> -</para> - -<para> Structure <citerefentry><refentrytitle>struct buf</refentrytitle></citerefentry> -</para> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>d_open()</function></title> -<para> Décrit dans la section périphérique de caractère. -</para> -</sect4> - -<sect4> -<title><function>d_close()</function></title> -<para>Décrit dans la section périphérique de caractère. -</para> -</sect4> - -<sect4> -<title><function>d_strategy()</function></title> -<para>Décrit dans la section périphérique de caractère. -</para> -</sect4> - -<sect4> -<title><function>d_ioctl()</function></title> -<para>Décrit dans la section périphérique de caractère. -</para> -</sect4> - -<sect4> -<title><function>d_dump()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>d_psize()</function></title> -<para></para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>Réseau</title> -<para>Structure <citerefentry><refentrytitle>struct ifnet</refentrytitle></citerefentry> -</para> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>if_init()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>if_output()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>if_start()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>if_done()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>if_ioctl()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>if_watchdog()</function></title> -<para></para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>Protocole de communication</title> - -<sect3> -<title>Structures de données</title> -<para>Structure <citerefentry><refentrytitle>struct linesw</refentrytitle></citerefentry> -</para> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>l_open()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_close()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_read()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_write()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_ioctl()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_rint()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_start()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>l_modem()</function></title> -<para></para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> -</sect1> - -<sect1> -<title>Bus Supportés</title> - -<sect2> -<title>ISA -- Architecture Standard d'Industrie (<foreignphrase>Industry Standard -Architecture</foreignphrase></title> - -<sect3> -<title>Structures de données</title> - -<sect4> -<title>Structure <citerefentry><refentrytitle>struct isa_device</refentrytitle></citerefentry></title> - -<para>Cette structure est obligatoire, mais généralement elle est créée par -<ulink url="http://www.freebsd.org/cgi/man.cgi?config(8)">config</ulink> à partir du fichier de configuration de noyau. -Elle est requise pour chaque périphérique, c'est à dire que si vous avez -un pilote de périphérique contrôlant deux "serial boards", vous -aurez deux structures isa_device. Si vous construisez un périphérique -comme un LKM, vous devrez créer votre propre structure isa_device afin -de refléter votre configuration (lignes 85 - 131 de pcaudio_lkm.c). -Il y a un équivalence directe ebtre le fichier de configuration et la -structureisa_device. La définition de -<filename>/usr/src/sys/i386/isa/isa_device.h</filename> -est : -</para> - -<programlisting> -struct isa_device { - int id_id; /* device id */ - struct isa_driver *id_driver; - int id_iobase; /* base i/o address */ - u_short id_irq; /* interrupt request */ - short id_drq; /* DMA request */ - caddr_t id_maddr; /* physical i/o memory address on bus (if any)*/ - int id_msize; /* size of i/o memory */ - inthand2_t *id_intr; /* interrupt interface routine */ - int id_unit; /* unit number */ - int id_flags; /* flags */ - int id_scsiid; /* scsi id if needed */ - int id_alive; /* device is present */ -#define RI_FAST 1 /* fast interrupt handler */ - u_int id_ri_flags; /* flags for <function>register_intr()</function> */ - int id_reconfig; /* hot eject device support (such as PCMCIA) */ - int id_enabled; /* is device enabled */ - int id_conflicts; /* we're allowed to conflict with things */ - struct isa_device *id_next; /* used in isa_devlist in <function>userconfig()</function> */ -}; -</programlisting> -</sect4> - -<sect4> -<title>Structure <citerefentry><refentrytitle>struct isa_driver</refentrytitle></citerefentry></title> - -<para>Cette structure est définie dans -<filename>/usr/src/sys/i386/isa/isa_device.h</filename>, -est est requise pour chaque pilote de périphérique. La définition -est : -</para> - -<programlisting> -struct isa_driver { - int (*probe) __P((struct isa_device *idp)); - /* test whether device is present */ - int (*attach) __P((struct isa_device *idp)); - /* setup driver for a device */ - char *name; /* device name */ - int sensitive_hw; /* true if other probes confuse us */ -}; -</programlisting> - -<para> -C'est la structure employée par le code sondage/attachement -(<foreignphrase>probe/attach</foreignphrase>) pour -détecter et initialiser votre périphérique. Le membre <citerefentry><refentrytitle>probe</refentrytitle></citerefentry> -est un pointeur à votre fonction permettant de sonder les périphériques. -Le membre <citerefentry><refentrytitle>attach</refentrytitle></citerefentry> est un pointeur vers votre fonction d'attache. -Le membre <citerefentry><refentrytitle>name</refentrytitle></citerefentry> est un pointeur de caractère sur le nom de deux -ou trois lettres de votre pilote. -C'est le nom enregistré pendant le processus de -sondage/attachement (et probablement aussi dans -<ulink url="http://www.freebsd.org/cgi/man.cgi?lsdev(8)">lsdev</ulink>). -Le membre <citerefentry><refentrytitle>sensitive_hw </refentrytitle></citerefentry> est un -indicateur qui aide le code de sondage à déterminer l'ordre du sondage. -</para> - -<para> -Un instantiation typique est: -</para> - -<programlisting> -struct isa_driver mcddriver = { mcd_probe, mcd_attach, "mcd" }; -</programlisting> -</sect4> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>probe()</function></title> -<para><function>probe()</function> prend un pointeur sur une structure isa_device -comme argument et renvoie un int. La valeur de retour est ``zéro'' ou -``non-zéro '' quant à l'absence ou à la présence de votre périphérique. -Ce point d'entrée peut être déclaré comme -<citerefentry><refentrytitle>static</refentrytitle></citerefentry> parce qu'il -est accessible par l'intermédiaire du membre -<citerefentry><refentrytitle>probe</refentrytitle></citerefentry> de la structre -isa_driver. Cette fonction est destinée à -détecter la présence de votre périphérique seulement et ne devrait -faire aucune configuration du périphérique elle-même. -</para> -</sect4> - -<sect4> -<title><function>attach()</function></title> -<para> -<function>attach()</function> prend également un pointeur sur une structure -isa_device comme argument et -renvoie un int. La valeur de retour est également ``zéro'' ou -``non-zéro'' indiquant si l'attache a réussie. Cette fonction -est destinée pour faire n'importe quelle initialisation spéciale du -périphérique aussi bien que pour confirmer que le périphérique est utilisable. -Il devrait aussi être déclaré <citerefentry><refentrytitle>static</refentrytitle></citerefentry> parce qu'il est accesible -par le membre <citerefentry><refentrytitle>attach</refentrytitle></citerefentry> de la structure <citerefentry><refentrytitle>isa_driver </refentrytitle></citerefentry>. -</para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>EISA -- Architecture Étendue de Standard industriel (<foreignphrase>Extended Industry Standard Architecture</foreignphrase>)</title> -<para></para> - -<sect3> -<title>Structures de données</title> - -<para>Structure <citerefentry><refentrytitle>struct eisa_dev </refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct isa_driver</refentrytitle></citerefentry> </para> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>probe()</function></title> -<para>Décrit dans la section de périphérique ISA.</para> -</sect4> - -<sect4> -<title><function>attach()</function></title> -<para>Décrit dans la section de périphérique ISA.</para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>PCI -- Bus d'interconnexion Périphérique (<foreignphrase>Peripheral Computer -Interconnect</foreignphrase>)</title> - -<sect3> -<title>Structures de données</title> - -<para> Structure <citerefentry><refentrytitle>struct pci_device</refentrytitle></citerefentry> -</para> - -<itemizedlist> -<listitem> -<para>nom : Le nom abrégé du périphérique. -</para> -</listitem> - -<listitem> -<para> sonde: Contrôle si le pilote peut supporter un périphérique avec -ce type. L'étiquette peut être employée pour obtenir plus -d'information avec <function>pci_read_conf()</function>. Voir ci-dessous. Elle renvoie -une chaîne de caractères avec le nom du périphérique, ou un pointeur -NULL si le pilote ne peut pas supporter ce périphérique. -</para> -</listitem> - -<listitem> -<para> attache: Assigne une structure de contrôle et la prépare. Cette -fonction peut utiliser les fonctions de mapping PCI. Voir -ci-dessous. (identification de configuration) ou type. -</para> -</listitem> - -<listitem> -<para> compte: Un pointeur sur un compteur d'unité. Il est -employé par le configurateur de PCI pour assigner des numéros. -</para> -</listitem> -</itemizedlist> - -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>probe()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>attach()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>shutdown()</function></title> -<para></para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>SCSI -- <foreignphrase>Small Computer Systems Interface</foreignphrase></title> - -<sect3> -<title>Structure de données</title> - -<para>Structure <citerefentry><refentrytitle>struct scsi_adapter</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct scsi_device</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct scsi_ctlr_config</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct scsi_device_config</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct scsi_link</refentrytitle></citerefentry> </para> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>attach()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>init()</function></title> -<para></para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> -<para></para> -</sect3> -</sect2> - - -<sect2> -<title>PCCARD (PCMCIA)</title> - -<sect3> -<title>Structure de données</title> - -<para>Structure <citerefentry><refentrytitle>struct slot_cont</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct pccard_drv</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct pccard_dev</refentrytitle></citerefentry> </para> -<para>Structure <citerefentry><refentrytitle>struct slot</refentrytitle></citerefentry> </para> -</sect3> - -<sect3> -<title>Points d'entrée</title> - -<sect4> -<title><function>handler()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>unload()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>suspend()</function></title> -<para></para> -</sect4> - -<sect4> -<title><function>init()</function></title> -<para></para> -</sect4> -</sect3> - -<sect3> -<title>Fichiers d'en-tête</title> - -<para><pccard/slot.h> -</para> -</sect3> -</sect2> -</sect1> - - -<sect1> -<title>Incorporation dans le noyau</title> - -<para>Dans FreeBSD, le support des bus d'ISA et EISA est spécifique à -i386. Tandis que FreeBSD lui-même est actuellement -disponible sur la plateforme i386, un certain effort a été fait pour -faire du code portable pour PCI, PCCARD, et SCSI. Le code -spécifique à ISA et EISA réside dans -<filename>/usr/src/sys/i386/isa</filename> et -<filename>/usr/src/sys/i386/eisa</filename> respectivement. Le code indépendant de la -machine de PCI, de PCCARD, et de SCSI réside dans -<filename>/usr/src/sys/{pci,pccard,scsi</filename>}. Le code spécifique i386 quand à lui -réside dans <filename>/usr/src/sys/i386/{pci, pccard, scsi}</filename>. -</para> - - -<para> Dans FreeBSD, un module de gestion de périphérique peut -être soit sous forme binaire soit sous forme de sources. -Il n'y a aucun endroit ``officiel'' pour mettre les binaires des -pilotes de périphériques. les systèmes BSD utilise quelque -chose comme sys/i386/OBJ. Puisque la plupart des pilotes sont -distribués dans les sources, la discussion suivante se rapporte à un -source pilote de périphérique. -Des binaires de pilotes de périphériques sont -parfois fournis par les constructeurs de matériel qui souhaitent -maintenir les sources de manière propriétaire. -</para> - -<para> Un pilote typique a son code source sous forme de fichier C, -comme dev.c. Le pilote peut également inclure des -fichiers; devreg.h contient typiquement des déclarations publiques -de registre de périphérique, des macros, et d'autres -déclarations spécifique au pilote de périphérique. -Quelques pilotes appellent parfois ce fichier devvar.h. -Quelques pilotes, tels que -le dgb (pour le Digiboard PC/Xe), exigent que du microcode soit chargé -sur la carte. Pour le pilote de dgb le microcode est compilé -et reporté dans un fichier d'en-tête par -<ulink url="http://www.freebsd.org/cgi/man.cgi?file2c(1)">file2c</ulink>. -</para> - -<para> Si le pilote de périphérique a des structures de données et des -ioctl qui sont spécifiques au pilote de périphérique ou -périphérique, et -doivent être accessibles de l'espace-utilisateur, elles devraient -être mises dans un fichier d'en-tête séparé qui résidera dans -<filename>/usr/include/machine/</filename> (certaines de ces derniers résident dans -<filename>/usr/include/sys/</filename>). Ceux-ci est typiquement nommé quelque chose comme -ioctl_dev.h ou devio.h. -</para> - -<para> Si un pilote écrit depuis l'espace -d'utilisateur est identique à un périphérique qui existe déjà, il faut -prendre garde à utiliser les mêmes -interfaces ioctl et structures de données. Par exemple, de l'espace -utilisateur, un lecteur de SCSI CDROM devrait être identique à un -lecteur de cdrom IDE; ou une ligne série sur une carte -intelligente multiport (Digiboard, Cyclades...) devrait être identique -à un périphérique sio. Ces périphériques ont une interface définie -relativement bonne et devraient être utilisées. -</para> - -<para> Il y a deux méthodes pour lier un pilote dans le -noyau, statiquement et le modèle LKM. La première méthode -est assez standard à travers la famille *BSD. L'autre -méthode a été initialement développée par Sun (je crois), et a -été mis en application dans BSD en utilisant le modèle de Sun. -Je ne crois pas que l'implémentation actuelle utilise encore le moindre -code de Sun. -</para> - -<sect2> -<title>Modèle Standard</title> - -<para> Les étapes exigées pour ajouter votre pilote au -noyau standard de FreeBSD sont -</para> - -<itemizedlist> -<listitem> -<para>Ajout à la liste des pilotes de périphérique -</para> -</listitem> - -<listitem> -<para>Ajout d'une entrée au [bc]devsw -</para> -</listitem> - -<listitem> -<para>Ajout d'une entrée du pilote de périphérique au fichier de -configuration du noyau -</para> -</listitem> - -<listitem> -<para><ulink -url="http://www.freebsd.org/cgi/man.cgi?config(8)">config</ulink>, -compilation et installation du noyau -</para> -</listitem> - -<listitem> -<para>créer les fichiers spéciaux requis -</para> -</listitem> - -<listitem> -<para>redémarrage -</para> -</listitem> -</itemizedlist> - -<sect3> -<title>Ajout à la liste des pilotes de périphérique</title> - -<para>Le modèle standard pour ajouter un module de gestion de périphérique -au noyau de Berkeley est d'ajouter votre pilote à la liste des -périphériques connus. Cette liste dépend de l'architecture du CPU. -Si le périphérique n'est pas spécifique i386 -(PCCARD, PCI, SCSI), le fichier est dans -<filename>/usr/src/sys/conf/files</filename>. -Si le périphérique est spécifique i386, utilisez -<filename>/usr/src/sys/i386/conf/files.i386</filename>. Une ligne typique ressemblerait -à : -</para> - -<programlisting> -i386/isa/joy.c optional joy device-driver -</programlisting> - -<para>Le premier champ relatif est le chemin du module de pilote -par rapport à <filename>/usr/src/sys</filename>. -Pour le cas d'un pilote binaire, le chemin d'accès serait quelque -chose comme <filename>i386/OBJ/joy.o</filename>. -</para> - -<para>Le deuxième champ indique à -<ulink url="http://www.freebsd.org/cgi/man.cgi?config(8)">config(8)</ulink> -que c'est un pilote facultatif. Quelques -périphériques sont obligatoires pour que le noyau puisse être construit. -</para> - -<para> -Le troisième champ est le nom du périphérique. -</para> - -<para>Le quatrième champ indique à config que c'est un -pilote de périphérique (par opposition à juste facultatif). Ceci -dit à config de créer des entrées pour le périphérique dans dans -des structures de <filename>/usr/src/sys/compile/KERNEL/ioconf.c</filename>. -</para> - -<para>Il est également possible de créer un fichier -<filename>/usr/src/sys/i386/conf/files.KERNEL</filename> dont le contenu ignorera le -fichier par défaut files.i386, mais seulement pour le noyau ``KERNEL''. -</para> -</sect3> - -<sect3> -<title>Faire de la place dans conf.c</title> - -<para>Maintenant vous devez éditer <filename>/usr/src/sys/i386/i386/conf.c</filename> -pour faire une entrée pour votre pilote. Quelque part au début, -vous devez déclarer vos points d'entrée. L'entrée pour -le pilote du joystick est: </para> - -<programlisting> -#include "joy.h" -#if NJOY > 0 -d_open_t joyopen; -d_close_t joyclose; -d_rdwr_t joyread; -d_ioctl_t joyioctl; -#else -#define joyopen nxopen -#define joyclose nxclose -#define joyread nxread -#define joyioctl nxioctl -#endif -</programlisting> - -<para> -Cela définit vos points d'entrée, ou points d'entrée nuls qui -renverront ENXIO quand appelé (clause #else). -</para> - -<para> -Le fichier d'en-tête ``joy.h'' est automatiquement produit par -<ulink url="http://www.freebsd.org/cgi/man.cgi?config(8)">config</ulink> -quand l'arborescence de construction du noyau est -créé. Cela se réduit habituellement à une seule ligne comme : -</para> - -<programlisting> -#define NJOY 1 -</programlisting> - -<para> -ou -</para> -<programlisting> -#define NJOY 0 -</programlisting> - -<para> ce qui définit le nombre de vos périphériques dans votre noyau. -</para> - -<para> -Vous devez additionnellement ajouter un slot au cdevsw[&rsqb, ou -au bdevsw[&rsqb, selon que ce soit un périphérique caractère, -périphérique bloc, ou les deux si c'est un périphérique bloc -avec une interface brute. L'entrée pour le pilote du joystick -est: -</para> - -<programlisting> -/* open, close, read, write, ioctl, stop, reset, ttys, select, mmap, strat */ -struct cdevsw cdevsw[] = -{ - ... - { joyopen, joyclose, joyread, nowrite, /*51*/ - joyioctl, nostop, nullreset, nodevtotty,/*joystick */ - seltrue, nommap, NULL}, - ... -} -</programlisting> - -<para> - L'ordre est ce qui détermine le nombre majeur de votre -périphérique. C'est pourquoi il y aura toujours une entrée -pour votre pilote, que ce soit des points d'entrée nuls, -ou des points d'entrée actuels. Il est probablement intéressant de -noter que c'est -sensiblement différent de SCO et d'autres dérivés du système V, où -n'importe quel périphérique (dans la théorie) peut avoir n'importe -quel nombre majeur. C'est en grande partie un avantage sur FreeBSD, -sur la manière dont les fichiers spéciaux de périphérique sont créés. -Nous reviendrons en détail sur ceci plus tard. -</para> -</sect3> - -<sect3> -<title>Ajout de votre périphérique dans le fichier de configuration.</title> - -<para> Ceci ajoute simplement une ligne décrivant votre périphérique. La -ligne de description du joystick est : -<programlisting> -device joy0 at isa? port "IO_GAME" -</programlisting> -Ceci indique que nous avons un -périphérique appelé ``joy0'' sur le bus ISA en utilisant -le port E/S ``IO_GAME'' (IO_GAME est une macro définie dans -<filename>/usr/src/sys/i386/isa/isa.h</filename>). -</para> - -<para> -Une entrée légèrement plus compliquée est pour le pilote ``ix'' : - -<programlisting> -device ix0 at isa? port 0x300 net irq 10 iomem 0xd0000 iosiz 32768 -vector ixintr -</programlisting> - -Ceci indique que nous avons un périphérique appelé -`ix0 ' sur le bus ISA. Il utilise le port E/S 0x300. Son -interruption sera masqué par d'autres périphériques dans la classe -réseau. Il utilise l'interruption 10. Il utilise 32k de mémoire -partagée à l'adresse physique 0xd0000. Il le définit également -son pilote d'interruption comme étant ``<function>ixintr()</function>'' -</para> -</sect3> - -<sect3> -<title><ulink url="http://www.freebsd.org/cgi/man.cgi?config(8)">config</ulink> -du noyau.</title> - -<para> Maintenant avec notre fichier de configuration en main, -nous pouvons créer un répertoire de compilation du noyau. Cela peut être -fait en tapant : -<programlisting> -# config KERNEL -</programlisting> - -où KERNEL est le nom de votre fichier de configuration. -La configuration crée un arbre de compilation -pour votre noyau dans <filename>/usr/src/sys/compile/KERNEL</filename>. Elle crée le fichier -makefile, quelques fichiers C, et quelques fichiers H avec des -macros définissant le nombre de chaque périphérique à inclure dans votre -votre noyau. -</para> - -<para> -Maintenant vous pouvez aller dans le répertoire de compilation et -construire votre noyau. À chaque fois que vous lancerez config, votre -arbre de construction précédent sera retiré, à moins que vous ne lancez -config avec un -n. Si vous avez configuré et compilé un noyau GENERIC, -vous pouvez faire un ``make links'' afin d'éviter de compiler certains -fichiers à chaque itération. Typiquement, je lance : -<programlisting> -# make depend links all -</programlisting> -suivi d'un ``make install'' quand le noyau me convient. -</para> -</sect3> - -<sect3> -<title>Créer les fichiers spéciaux de périphériques</title> - -<para> Sur FreeBSD, vous avez la responsabilité de faire vos propres fichiers -spéciaux -de périphérique. Le -nombre majeur de votre périphérique est déterminé par le nombre de -slots dans le commutateur de périphérique. Le nombre mineur est -dépendant du pilote, naturellement. Vous pouvez -soit exécuter mknod depuis la ligne de commande, soit liasser faire le -travail à <filename>/dev/MAKEDEV.local</filename>, ou même -<filename>/dev/MAKEDEV</filename>. -Je crée parfois un script MAKEDEV.dev qui peut être soit lancé -de manière autonome soit collé dans <filename>/dev/MAKEDEV.local</filename>. -</para> -</sect3> - -<sect3> -<title>Redémarrage</title> -<para> C'est la partie facile. Il y a un -certain nombre de méthodes pour faire ceci, reboot, fastboot, -shutdown - r, couper le courant, etc. Au démarrage, vous -devriez voir votre XX<function>probe()</function> appelé, et si tout marche, -votre <function>attach()</function> aussi. -</para> -</sect3> -</sect2> - -<sect2> -<title>Module du noyau à chargement dynamique (LKM)</title> - -<para>Il n'y a vraiment aucune procédure définie pour écrire un pilote de -LKM. Ce qui suit est ma propre conception après expérimentation -avec l'interface de périphérique LKM et en regardant le modèle standard -de module de gestion de périphérique, c'est une manière d'ajouter une -interface LKM à un pilote existant sans toucher aux sources (ou binaire) -initiaux de pilote . On recommande cependant, -que si vous projetez de distribuer les sources de votre pilote, -que les parties spécifiques LKM devraient faire partie du pilote -lui-même, compilé de manière conditionnelle par la macro LKM -(c.-à-d. #ifdef LKM). -</para> - -<para> -Cette section se concentrera sur la manière d'écrire la partie spécifique -LKM du pilote. Nous supposerons que nous avons écrit un -pilote qui atterrira dans le modèle standard de -gestion de périphérique, que nous voudrions maintenant mettre en -application comme étant LKM. Nous utiliserons le pilote de pcaudio -comme pilote d'exemple, et développerons une entrée LKM. La -source et le fichier makefile pour le LKM pcaudio , ``pcaudio_lkm.c'' -et ``Makefile'', devraient être dans placé <filename>/usr/src/lkm/pcaudio</filename>. -Ce qui suit est le code commenté de pcaudio_lkm.c. -</para> - -<para> -Lignes 17 - 26 -</para> - -<para> -Ceci inclut le fichier ``pca.h'' et fait une compilation conditionnelle -du reste de LKM suivant que vous avez défini ou non le pilote de -périphérique pcaudio. -Cela imite le comportement de config. Dans un pilote de -périphérique standard, -<ulink url="http://www.freebsd.org/cgi/man.cgi?config(8)">config</ulink> -produit le fichier pca.h depuis le nombre de périphériques pca -le fichier de config. </para> - -<programlisting> - 17 /* - 18 * figure out how many devices we have.. - 19 */ - 20 - 21 #include "pca.h" - 22 - 23 /* - 24 * if we have at least one ... - 25 */ - 26 #if NPCA > 0 -</programlisting> - -<para> -Lignes 27 - 37 -</para> - -<para> -Les fichiers d'en-tête requis depuis divers répertoire d'inclusion. -</para> - -<programlisting> - 27 #include <sys/param.h> - 28 #include <sys/systm.h> - 29 #include <sys/exec.h> - 30 #include <sys/conf.h> - 31 #include <sys/sysent.h> - 32 #include <sys/lkm.h> - 33 #include <sys/errno.h> - 34 #include <i386/isa/isa_device.h> - 35 #include <i386/isa/isa.h> - 36 - 37 -</programlisting> - -<para> -Lignes 38 - 51 -</para> - -<para>déclarent vos points d'entrée comme externs . -</para> - -<programlisting> - 38 /* - 39 * declare your entry points as externs - 40 */ - 41 - 42 extern int pcaprobe(struct isa_device *); - 43 extern int pcaattach(struct isa_device *); - 44 extern int pcaopen(dev_t, int, int, struct proc *); - 45 extern int pcaclose(dev_t, int, int, struct proc *); - 46 extern int pcawrite(dev_t, struct uio *, int); - 47 extern int pcaioctl(dev_t, int, caddr_t); - 48 extern int pcaselect(dev_t, int, struct proc *); - 49 extern void pcaintr(struct clockframe *); - 50 extern struct isa_driver pcadriver; - 51 -</programlisting> - -<para> -Lignes 52 - 70 -</para> - -<para> -Cela crée la table d'entrée de commutateur de périphérique pour -votre pilote. Cette table est en gros entièrement mise dans le -système de commutation de périphériques à l'emplacement indiqué par -votre nombre majeur. Dans le modèle standard, c'est dans -<filename>/usr/src/sys/i386/i386/conf.c</filename>. -NOTE: vous ne pouvez pas sélectionner -un nombre majeur de périphérique plus grand que ce qui existe dans -conf.c, par exemple -il y a 67 slots pour des périphériques caractère, vous ne popuvez pas -utiliser un périphérique (caractère) de numéro majeur 67 ou -plus, sans avoir d'abord réservé de l'espace dans conf.c. -</para> - -<programlisting> - 52 /* - 53 * build your device switch entry table - 54 */ - 55 - 56 static struct cdevsw pcacdevsw = { - 57 (d_open_t *) pcaopen, /* open */ - 58 (d_close_t *) pcaclose, /* close */ - 59 (d_rdwr_t *) enodev, /* read */ - 60 (d_rdwr_t *) pcawrite, /* write */ - 61 (d_ioctl_t *) pcaioctl, /* ioctl */ - 62 (d_stop_t *) enodev, /* stop?? */ - 63 (d_reset_t *) enodev, /* reset */ - 64 (d_ttycv_t *) enodev, /* ttys */ - 65 (d_select_t *) pcaselect, /* select */ - 66 (d_mmap_t *) enodev, /* mmap */ - 67 (d_strategy_t *) enodev /* strategy */ - 68 }; - 69 - 70 -</programlisting> - -<para> -Lignes 71 - 131 -</para> -<para> -cette section est analogue à la déclaration de fichier de configuration -de votre périphérique. Les membres de la structure isa_device sont -remplis grace à ce qu'il connait de votre périphérique, -port E/S, segment partagé de mémoire, etc... -Nous n'aurons probablement jamais un besoin de deux périphériques -pcaudio dans le noyau, mais cet exemple montre comment -périphériques multiples peuvent être supportés. -</para> - -<programlisting> - 71 /* - 72 * this lkm arbitrarily supports two - 73 * instantiations of the pc-audio device. - 74 * - 75 * this is for illustration purposes - 76 * only, it doesn't make much sense - 77 * to have two of these beasts... - 78 */ - 79 - 80 - 81 /* - 82 * these have a direct correlation to the - 83 * config file entries... - 84 */ - 85 struct isa_device pcadev[NPCA] = { - 86 { - 87 11, /* device id */ - 88 &pcadriver, /* driver pointer */ - 89 IO_TIMER1, /* base io address */ - 90 -1, /* interrupt */ - 91 -1, /* dma channel */ - 92 (caddr_t)-1, /* physical io memory */ - 93 0, /* size of io memory */ - 94 pcaintr , /* interrupt interface */ - 95 0, /* unit number */ - 96 0, /* flags */ - 97 0, /* scsi id */ - 98 0, /* is alive */ - 99 0, /* flags for register_intr */ - 100 0, /* hot eject device support */ - 101 1 /* is device enabled */ - 102 }, - 103 #if NPCA >1 - 104 { - 105 - 106 /* - 107 * these are all zeros, because it doesn't make - 108 * much sense to be here - 109 * but it may make sense for your device - 110 */ - 111 - 112 0, /* device id */ - 113 &pcadriver, /* driver pointer */ - 114 0, /* base io address */ - 115 -1, /* interrupt */ - 116 -1, /* dma channel */ - 117 -1, /* physical io memory */ - 118 0, /* size of io memory */ - 119 NULL, /* interrupt interface */ - 120 1, /* unit number */ - 121 0, /* flags */ - 122 0, /* scsi id */ - 123 0, /* is alive */ - 124 0, /* flags for register_intr */ - 125 0, /* hot eject device support */ - 126 1 /* is device enabled */ - 127 }, - 128 #endif - 129 - 130 }; - 131 -</programlisting> - -<para> -Lignes 132 - 139 -</para> - -<para> -Ceci appelle la macro MOD_DEV du préprocesseur C, qui -installe un module de gestion de périphérique de LKM, par -opposition à un système de fichiers LKM, ou un appel système de LKM. -</para> - -<programlisting> - 132 /* - 133 * this macro maps to a function which - 134 * sets the LKM up for a driver - 135 * as opposed to a filesystem, system call, or misc - 136 * LKM. - 137 */ - 138 MOD_DEV("pcaudio_mod", LM_DT_CHAR, 24, &pcacdevsw); - 139 -</programlisting> - -<para> -Lignes 140 - 168 -</para> - -<para> -c'est la fonction qui sera appelée lorsque le pilote sera -chargé. Cette fonction essaye de fonctionner comme -<filename>/sys/i386/isa/isa.c</filename> qui fait les appels de probe/attach pour un -pilote au moment du redémarrage. La plus grande astuce ici est qu'il -met en correspondance l'adresse physique du segment partagé de mémoire, qui est -indiqué dans la structure isa_device à une adresse virtuelle du noyau. -Normalement, l'adresse physique est mise dans le fichier de configuration -qui construit la structure isa_device dans -<filename>/usr/src/sys/compile/KERNEL/ioconf.c</filename>. La séquence probe/attach de -<filename>/usr/src/sys/isa/isa.c</filename> traduit l'adresse physique en une virtuelle de -sorte que dans les sous-programmes de probe/attach vous puissiez -faire des choses comme -</para> -<programlisting> -(int *)id->id_maddr = something; -</programlisting> -<para> et se réfère juste au segment partagé de mémoire -par l'intermédiaire de pointeurs. -</para> - -<programlisting> - 140 /* - 141 * this function is called when the module is - 142 * loaded; it tries to mimic the behavior - 143 * of the standard probe/attach stuff from - 144 * isa.c - 145 */ - 146 int - 147 <function>pcaload()</function>{ - 148 int i; - 149 uprintf("PC Audio Driver Loaded\n"); - 150 for (i=0; i<NPCA; i++){ - 151 /* - 152 * this maps the shared memory address - 153 * from physical to virtual, to be - 154 * consistent with the way - 155 * /usr/src/sys/i386/isa.c handles it. - 156 */ - 157 pcadev[i].id_maddr -=0xa0000; - 158 pcadev[i].id_maddr += atdevbase; - 159 if ((*pcadriver.probe)(pcadev+i)) { - 160 (*(pcadriver.attach))(pcadev+i); - 161 } else { - 162 uprintf("PC Audio Probe Failed\n"); - 163 return(1); - 164 } - 165 } - 166 return 0; - 167 } - 168 -</programlisting> - -<para>Lignes 169 - 179 -</para> - -<para>c'est la fonction appelée quand votre pilote n'est pas -chargé; il affiche juste un message à cet effet. -</para> - -<programlisting> - 169 /* - 170 * this function is called - 171 * when the module is unloaded - 172 */ - 173 - 174 int - 175 <function>pcaunload()</function>{ - 176 uprintf("PC Audio Driver Unloaded\n"); - 177 return 0; - 178 } - 179 -</programlisting> - -<para>Lignes 180 - 190 -</para> - -<para>c'est le point d'entrée qui est indiqué sur la ligne de commande -de modload. Par convention il est nommé <dev>_mod. C'est -ainsi qu'il est défini dans bsd.lkm.mk, le makefile qui -construit le LKM. Si vous nommez votre module suivant cette -convention, vous pouvez faire ``make load'' et ``make unload'' -de /usr/src/lkm/pcaudio.</para> - -<para>Note : Il y a eu <emphasis>tellement</emphasis> de révisions entre la version 2.0 et -2.1. Il peut ou ne peut ne pas être possible d'écrire -un module qui est portable pour chacune des trois versions. -</para> - - -<programlisting> - 180 /* - 181 * this is the entry point specified - 182 * on the modload command line - 183 */ - 184 - 185 int - 186 pcaudio_mod(struct lkm_table *lkmtp, int cmd, int ver) - 187 { - 188 DISPATCH(lkmtp, cmd, ver, pcaload, pcaunload, nosys); - 189 } - 190 - 191 #endif /* NICP > 0 */ -</programlisting> -</sect2> - -<sect2> -<title>Idiosyncrasies du type périphérique</title> - -<sect3> -<title>Caractère</title> -<para></para> -</sect3> - -<sect3> -<title>Bloc</title> -<para></para> -</sect3> - -<sect3> -<title>Réseau</title> -<para></para> -</sect3> - -<sect3> -<title>Line discipline</title> -<para></para> -</sect3> -</sect2> - -<sect2> -<title>Idiosyncrasies du type bus</title> - -<sect3> -<title>ISA</title> -<para></para> -</sect3> - -<sect3> -<title>EISA</title> -<para></para> -</sect3> - -<sect3> -<title>PCI</title> -<para></para> -</sect3> - -<sect3> -<title>SCSI</title> -<para></para> -</sect3> - -<sect3> -<title>PCCARD</title> -<para></para> -</sect3> -</sect2> -</sect1> - - -<sect1> -<title>Support du noyau</title> - -<sect2> -<title>Structures de données</title> - -<sect3> -<title>Structure <citerefentry><refentrytitle>struct kern_devconf</refentrytitle></citerefentry></title> - -<para>Cette structure contient quelques informations sur l'état du -périphérique et de son pilote. Elle est définie dans -<filename>/usr/src/sys/sys/devconf.h</filename> comme ci-dessous : -</para> - -<programlisting> -struct devconf { - char dc_name[MAXDEVNAME]; /* name */ - char dc_descr[MAXDEVDESCR]; /* description */ - int dc_unit; /* unit number */ - int dc_number; /* unique id */ - char dc_pname[MAXDEVNAME]; /* name of the parent device */ - int dc_punit; /* unit number of the parent */ - int dc_pnumber; /* unique id of the parent */ - struct machdep_devconf dc_md; /* machine-dependent stuff */ - enum dc_state dc_state; /* state of the device (see above) */ - enum dc_class dc_class; /* type of device (see above) */ - size_t dc_datalen; /* length of data */ - char dc_data[1]; /* variable-length data */ -}; -</programlisting> -</sect3> - -<sect3> -<title>Structure <citerefentry><refentrytitle>struct proc</refentrytitle></citerefentry></title> - -<para> Cette structure contient toutes les informations sur un processus. -Elle est dans définie <filename>/usr/src/sys/sys/proc.h</filename>: -</para> - -<programlisting> -/* - * Description of a process. - * - * This structure contains the information needed to manage a thread of - * control, known in UN*X as a process; it has references to -substructures - * containing descriptions of things that the process uses, but may -share - * with related processes. The process structure and the substructures - * are always addressable except for those marked "(PROC ONLY)" below, - * which might be addressable only on a processor on which the process - * is running. - */ -struct proc { - struct proc *p_forw; /* Doubly-linked run/sleep queue. */ - struct proc *p_back; - struct proc *p_next; /* Linked list of active procs */ - struct proc **p_prev; /* and zombies. */ - - /* substructures: */ - struct pcred *p_cred; /* Process owner's identity. */ - struct filedesc *p_fd; /* Ptr to open files structure. */ - struct pstats *p_stats; /* Accounting/statistics (PROC ONLY). */ - struct plimit *p_limit; /* Process limits. */ - struct vmspace *p_vmspace; /* Address space. */ - struct sigacts *p_sigacts; /* Signal actions, state (PROC ONLY). */ - -#define p_ucred p_cred->pc_ucred -#define p_rlimit p_limit->pl_rlimit - - int p_flag; /* P_* flags. */ - char p_stat; /* S* process status. */ - char p_pad1[3]; - - pid_t p_pid; /* Process identifier. */ - struct proc *p_hash; /* Hashed based on p_pid for kill+exit+... */ - struct proc *p_pgrpnxt; /* Pointer to next process in process group. */ - struct proc *p_pptr; /* Pointer to process structure of parent. */ - struct proc *p_osptr; /* Pointer to older sibling processes. */ - -/* The following fields are all zeroed upon creation in fork. */ -#define p_startzero p_ysptr - struct proc *p_ysptr; /* Pointer to younger siblings. */ - struct proc *p_cptr; /* Pointer to youngest living child. */ - pid_t p_oppid; /* Save parent pid during ptrace. XXX */ - int p_dupfd; /* Sideways return value from fdopen. XXX */ - - /* scheduling */ - u_int p_estcpu; /* Time averaged value of p_cpticks. */ - int p_cpticks; /* Ticks of cpu time. */ - fixpt_t p_pctcpu; /* %cpu for this process during p_swtime */ - void *p_wchan; /* Sleep address. */ - char *p_wmesg; /* Reason for sleep. */ - u_int p_swtime; /* Time swapped in or out. */ - u_int p_slptime; /* Time since last blocked. */ - - struct itimerval p_realtimer; /* Alarm timer. */ - struct timeval p_rtime; /* Real time. */ - u_quad_t p_uticks; /* Statclock hits in user mode. */ - u_quad_t p_sticks; /* Statclock hits in system mode. */ - u_quad_t p_iticks; /* Statclock hits processing intr. */ - - int p_traceflag; /* Kernel trace points. */ - struct vnode *p_tracep; /* Trace to vnode. */ - - int p_siglist; /* Signals arrived but not delivered. */ - - struct vnode *p_textvp; /* Vnode of executable. */ - - char p_lock; /* Process lock (prevent swap) count. */ - char p_pad2[3]; /* alignment */ - -/* End area that is zeroed on creation. */ -#define p_endzero p_startcopy - -/* The following fields are all copied upon creation in fork. */ -#define p_startcopy p_sigmask - - sigset_t p_sigmask; /* Current signal mask. */ - sigset_t p_sigignore; /* Signals being ignored. */ - sigset_t p_sigcatch; /* Signals being caught by user. */ - - u_char p_priority; /* Process priority. */ - u_char p_usrpri; /* User-priority based on p_cpu and p_nice. */ - char p_nice; /* Process "nice" value. */ - char p_comm[MAXCOMLEN+1]; - - struct pgrp *p_pgrp; /* Pointer to process group. */ - - struct sysentvec *p_sysent; /* System call dispatch information. */ - - struct rtprio p_rtprio; /* Realtime priority. */ -/* End area that is copied on creation. */ -#define p_endcopy p_addr - struct user *p_addr; /* Kernel virtual addr of u-area (PROC ONLY). */ - struct mdproc p_md; /* Any machine-dependent fields. */ - - u_short p_xstat; /* Exit status for wait; also stop signal. */ - u_short p_acflag; /* Accounting flags. */ - struct rusage *p_ru; /* Exit information. XXX */ -}; -</programlisting> -</sect3> - -<sect3> -<title>Structure <citerefentry><refentrytitle>struct buf</refentrytitle></citerefentry></title> -<para>La structure <citerefentry><refentrytitle>struct buf</refentrytitle></citerefentry> est employée pour s'interfacer -avec le cache de la mémoire tampon. Elle est dans -définie <filename>/usr/src/sys/sys/buf.h</filename> : -</para> - -<programlisting> -/* - * The buffer header describes an I/O operation in the kernel. - */ -struct buf { - LIST_ENTRY(buf) b_hash; /* Hash chain. */ - LIST_ENTRY(buf) b_vnbufs; /* Buffer's associated vnode. */ - TAILQ_ENTRY(buf) b_freelist; /* Free list position if not active. */ - struct buf *b_actf, **b_actb; /* Device driver queue when active. */ - struct proc *b_proc; /* Associated proc; NULL if kernel. */ - volatile long b_flags; /* B_* flags. */ - int b_qindex; /* buffer queue index */ - int b_error; /* Errno value. */ - long b_bufsize; /* Allocated buffer size. */ - long b_bcount; /* Valid bytes in buffer. */ - long b_resid; /* Remaining I/O. */ - dev_t b_dev; /* Device associated with buffer. */ - struct { - caddr_t b_addr; /* Memory, superblocks, indirect etc. */ - } b_un; - void *b_saveaddr; /* Original b_addr for physio. */ - daddr_t b_lblkno; /* Logical block number. */ - daddr_t b_blkno; /* Underlying physical block number. */ - /* Function to call upon completion. */ - void (*b_iodone) __P((struct buf *)); - /* For nested b_iodone's. */ - struct iodone_chain *b_iodone_chain; - struct vnode *b_vp; /* Device vnode. */ - int b_pfcent; /* Center page when swapping cluster. */ - int b_dirtyoff; /* Offset in buffer of dirty region. */ - int b_dirtyend; /* Offset of end of dirty region. */ - struct ucred *b_rcred; /* Read credentials reference. */ - struct ucred *b_wcred; /* Write credentials reference. */ - int b_validoff; /* Offset in buffer of valid region. */ - int b_validend; /* Offset of end of valid region. */ - daddr_t b_pblkno; /* physical block number */ - caddr_t b_savekva; /* saved kva for transfer while bouncing */ - void *b_driver1; /* for private use by the driver */ - void *b_driver2; /* for private use by the driver */ - void *b_spc; - struct vm_page *b_pages[(MAXPHYS + PAGE_SIZE - 1)/PAGE_SIZE]; - int b_npages; -}; -</programlisting> -</sect3> - - -<sect3> -<title>Structure <citerefentry><refentrytitle>struct uio</refentrytitle></citerefentry></title> - -<para>Cette structure est utilisée pour déplacer des données entre le noyau et -les espaces utilisateur par les appels système de <function>read()</function> et de <function>write()</function>. -Il est dans défini <filename>/usr/src/sys/sys/uio.h</filename> : -</para> - -<programlisting> -struct uio { - struct iovec *uio_iov; - int uio_iovcnt; - off_t uio_offset; - int uio_resid; - enum uio_seg uio_segflg; - enum uio_rw uio_rw; - struct proc *uio_procp; -}; -</programlisting> -</sect3> -</sect2> - - -<sect2> -<title>Fonctions</title> -<para>plein</para> -</sect2> - -<sect2> -<title>Références.</title> - -<para> FreeBSD Kernel Sources http://www.freebsd.org -</para> - -<para> NetBSD Kernel Sources http://www.netbsd.org -</para> - -<para> Writing Device Drivers: Tutorial and Reference; -Tim Burke, Mark A. Parenti, Al, Wojtas; -Digital Press, ISBN 1-55558-141-2. -</para> - -<para> Writing A Unix Device Driver; -Janet I. Egan, Thomas J. Teixeira; -John Wiley & Sons, ISBN 0-471-62859-X. -</para> - -<para> Writing Device Drivers for SCO Unix; -Peter Kettle; -</para> -</sect2> -</sect1> -</article> |