Adding first french translation of developper handbook
This commit is contained in:
parent
e248c08a95
commit
d0c90506a7
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=12185
10 changed files with 4514 additions and 0 deletions
35
fr_FR.ISO8859-1/books/developers-handbook/Makefile
Normal file
35
fr_FR.ISO8859-1/books/developers-handbook/Makefile
Normal file
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# The FreeBSD Documentation Project
|
||||
# The FreeBSD French Documentation Project
|
||||
#
|
||||
# Compilation du Manuel du Developpeur de FreeBSD
|
||||
#
|
||||
#
|
||||
#
|
||||
# $FreeBSD$
|
||||
# Original revision: 1.25
|
||||
#
|
||||
#
|
||||
|
||||
MAINTAINER=gioria@FreeBSD.org
|
||||
|
||||
DOC?= book
|
||||
|
||||
FORMATS?= html-split
|
||||
|
||||
INSTALL_COMPRESSED?= gz
|
||||
INSTALL_ONLY_COMPRESSED?=
|
||||
|
||||
#
|
||||
# SRCS lists the individual SGML files that make up the document. Changes
|
||||
# to any of these files will force a rebuild
|
||||
#
|
||||
|
||||
# SGML content
|
||||
SRCS= book.sgml
|
||||
|
||||
# Entities
|
||||
|
||||
DOC_PREFIX?= ${.CURDIR}/../../..
|
||||
|
||||
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
|
547
fr_FR.ISO8859-1/books/developers-handbook/book.sgml
Normal file
547
fr_FR.ISO8859-1/books/developers-handbook/book.sgml
Normal file
|
@ -0,0 +1,547 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: book.sgml,v 1.1 2002-02-14 14:25:01 gioria Exp $
|
||||
$FreeBSD$
|
||||
Original revision: 1.15
|
||||
|
||||
-->
|
||||
<!DOCTYPE BOOK 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 % bookinfo PUBLIC "-//FreeBSD//ENTITIES DocBook BookInfo Entities//FR"> %bookinfo;
|
||||
<!ENTITY % translators PUBLIC "-//FreeBSD//ENTITIES DocBook Translator Entities//FR"> %translators;
|
||||
<!ENTITY % chapters SYSTEM "chapters.ent"> %chapters;
|
||||
<!ENTITY % authors PUBLIC "-//FreeBSD//ENTITIES DocBook Author Entities//EN"> %authors
|
||||
<!ENTITY % mailing-lists SYSTEM "../../share/sgml/mailing-lists.ent"> %mailing-lists;
|
||||
|
||||
<!-- French Build only -->
|
||||
<!-- <!ENTITY % authors SYSTEM "../../../en_US.ISO_8859-1/books/handbook/authors.ent" > %authors; -->
|
||||
|
||||
|
||||
|
||||
<!ENTITY rel.current CDATA "3.3">
|
||||
]>
|
||||
<book lang="fr">
|
||||
<bookinfo>
|
||||
<title>Livre de chevet du développeur FreeBSD</title>
|
||||
|
||||
<corpauthor>Le groupe du projet de documentation FreeBSD</corpauthor>
|
||||
|
||||
<pubdate>Août 2000</pubdate>
|
||||
|
||||
<copyright>
|
||||
<year>2000</year>
|
||||
<year>2001</year>
|
||||
<holder>Le groupe du projet de documentation FreeBSD</holder>
|
||||
</copyright>
|
||||
|
||||
&bookinfo.legalnotice;
|
||||
|
||||
<abstract>
|
||||
<para>Bienvenue dans le livre de chevet du développeur</para>
|
||||
&trans.a.praca;
|
||||
<para>N.d.T.: La version française est publiée sur le
|
||||
<ulink url="&url.base;/">serveur World Wide Web du groupe de
|
||||
traduction en langue française de la documentation de
|
||||
FreeBSD</ulink>.</para>
|
||||
|
||||
<para>N.d.T.: Contactez la &a.fr-doc si vous voulez collaborer
|
||||
à la traduction.</para>
|
||||
|
||||
<para>La traduction de ce manuel est “en cours”. Dans la
|
||||
table des matières ci-dessous:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Les chapitres marqués de deux astérisques
|
||||
sont en cours de traduction.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Les chapitres marqués de trois astérisques
|
||||
sont à traduire.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>L'astérisque simple est réservé aux
|
||||
chapitres et sections en cours de rédaction dans la
|
||||
version U.S.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</abstract>
|
||||
|
||||
</bookinfo>
|
||||
|
||||
<part id="introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<chapter id="developmentplatform">
|
||||
<title>Développer sous FreeBSD</title>
|
||||
|
||||
<para>Ce document a pour but de décrire FreeBSD comme une plateforme
|
||||
de développement, la vision de BSD, un survol de l'architecture, l'agencement
|
||||
de /usr/src, l'histoire, etc.</para>
|
||||
|
||||
<para>Merci d'adopter FreeBSD comme votre plateforme
|
||||
de développement ! Nous espérons qu'elle ne vous laissera pas tomber.</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="bsdvision">
|
||||
<title>La vision BSD</title>
|
||||
|
||||
<para></para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="archoverview">
|
||||
<title>Survol de l'architecture</title>
|
||||
|
||||
<para></para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="sourcelayout">
|
||||
<title>L'agencement de /usr/src</title>
|
||||
|
||||
<para>Le code source complet de FreeBSD est disponible depuis notre
|
||||
base CVS publique. Le code source est normalement installé sous
|
||||
<filename class=directory>/usr/src</filename> qui contient les
|
||||
sous-répertoires suivants.</para>
|
||||
|
||||
<para>
|
||||
<informaltable frame="none">
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Répertoire</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><filename class=directory>bin/</filename></entry>
|
||||
<entry>Sources des fichiers de
|
||||
<filename>/bin</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>contrib/</filename></entry>
|
||||
<entry>Sources des fichiers des logiciels fournis ("contributed").</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>crypto/</filename></entry>
|
||||
<entry>Sources du DES</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>etc/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/etc</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>games/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/usr/games</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>gnu/</filename></entry>
|
||||
<entry>Utilitaires sous licence publique GNU</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>include/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/usr/include</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename
|
||||
class=directory>kerberosIV/</filename></entry>
|
||||
<entry>Sources de Kerbereros version IV</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename
|
||||
class=directory>kerberos5/</filename></entry>
|
||||
<entry>Sources de Kerbereros version 5</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>lib/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/usr/lib</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>libexec/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/usr/libexec</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename
|
||||
class=directory>release/</filename></entry>
|
||||
<entry>Fichiers requis pour la production d'une version
|
||||
stable de FreeBSD</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>sbin/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/sbin</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>secure/</filename></entry>
|
||||
<entry>Sources de FreeSec</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>share/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/sbin</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>sys/</filename></entry>
|
||||
<entry>Fichiers source du noyau</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename class=directory>tools/</filename></entry>
|
||||
<entry>Outils utilisés pour la maintenance et les tests de
|
||||
FreeBSD</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename
|
||||
class=directory>usr.bin/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/usr/bin</filename></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><filename
|
||||
class=directory>usr.sbin/</filename></entry>
|
||||
<entry>Sources des fichiers de <filename
|
||||
class=directory>/usr/sbin</filename></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="Basics">
|
||||
<title>Les fondamentaux</title>
|
||||
|
||||
&chap.tools;
|
||||
&chap.secure;
|
||||
|
||||
</part>
|
||||
|
||||
<part id="kernel">
|
||||
<title>Le noyau</title>
|
||||
|
||||
<chapter id="kernelhistory">
|
||||
<title>Histoire du noyau Unix</title>
|
||||
|
||||
<para>Un peu d'histoire sur le noyau Unix/BSD, les appels système, comment
|
||||
fonctionnent les processus, bloquer, planifier, les threads (noyau),
|
||||
le basculement de contexte, les signaux, les interruptions, les modules, etc.</para>
|
||||
|
||||
<para></para>
|
||||
</chapter>
|
||||
|
||||
&chap.locking;
|
||||
|
||||
</part>
|
||||
|
||||
<part id="memory">
|
||||
<title>Mémoire et mémoire virtuelle</title>
|
||||
|
||||
<chapter id="virtualmemory">
|
||||
<title>La mémoire virtuelle</title>
|
||||
|
||||
<para>MV, gestion par page, gestion sur disque, allouer de la mémoire, tester les
|
||||
fuites de mémoires, mmap, vnodes, etc.</para>
|
||||
|
||||
<para></para>
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="iosystem">
|
||||
<title>Système E/S (Entrées/Sorties)</title>
|
||||
|
||||
<chapter id="ufs">
|
||||
<title>UFS</title>
|
||||
|
||||
<para>UFS, FFS, Ext2FS, JFS, inodes, mémoire tampon, mettre à jour les données d'un disque,
|
||||
verrouillage, metadata, soft-updates, LFS, portalfs, procfs,
|
||||
vnodes, partage de mémoire, objets en mémoire, TLBs, mettre en cache</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="ipc">
|
||||
<title>Communication InterProcessus (IPC)</title>
|
||||
|
||||
<chapter id="signals">
|
||||
<title>Les signaux</title>
|
||||
|
||||
<para>Signaux, tubes, sémaphores, files de message, segments de mémoire partagée,
|
||||
ports, prises, portes</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="networking">
|
||||
<title>Le réseau</title>
|
||||
|
||||
<chapter id="sockets">
|
||||
<title>Les prises</title>
|
||||
|
||||
<para>Prises, bpf, IP, TCP, UDP, ICMP, OSI, ponts,
|
||||
pare-feux, translation d'adresses (NAT), séparation de réseaux, etc</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="networkfs">
|
||||
<title>Systèmes de fichiers en réseau</title>
|
||||
|
||||
<chapter id="afs">
|
||||
<title>AFS</title>
|
||||
|
||||
<para>AFS, NFS, SANs etc]</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="terminal">
|
||||
<title>Gestion du terminal</title>
|
||||
|
||||
<chapter id="syscons">
|
||||
<title>Syscons</title>
|
||||
|
||||
<para>Syscons, tty, PCVT, console en liaison série, économiseurs d'écran,
|
||||
etc</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="sound">
|
||||
<title>Le son</title>
|
||||
|
||||
<chapter id="oss">
|
||||
<title>OSS</title>
|
||||
|
||||
<para>OSS, formes d'ondes, etc</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="devicedrivers">
|
||||
<title>Pilotes de périphérique</title>
|
||||
|
||||
&chap.driverbasics;
|
||||
&chap.pci;
|
||||
&chap.scsi;
|
||||
&chap.usb;
|
||||
|
||||
<chapter id="newbus">
|
||||
<title>NewBus</title>
|
||||
|
||||
<para>Ce chapître traitera de l'architecture NewBus de FreeBSD.</para>
|
||||
</chapter>
|
||||
|
||||
</part>
|
||||
|
||||
<part id="architectures">
|
||||
<title>Architectures</title>
|
||||
|
||||
<chapter id="ia32">
|
||||
<title>IA-32</title>
|
||||
|
||||
<para>Traite des spécificités de l'architecture x86 sous FreeBSD.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="alpha">
|
||||
<title>Alpha</title>
|
||||
|
||||
<para>Traite des spécificités de l'architecture Alpha sous FreeBSD.</para>
|
||||
|
||||
<para>Explication des erreurs d'alignements, comment les réparer,
|
||||
comment les ignorer.</para>
|
||||
|
||||
<para>Exemple de code assembleur pour FreeBSD/alpha.</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="ia64">
|
||||
<title>IA-64</title>
|
||||
|
||||
<para>Traite des spécificités de l'architecture IA-64 sous FreeBSD.</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="debuggingpart">
|
||||
<title>Déverminage</title>
|
||||
|
||||
<chapter id="truss">
|
||||
<title>Truss</title>
|
||||
|
||||
<para>diverses descriptions sur les méthodes de déverminage de certains aspects
|
||||
du système utilisant truss, ktrace, gdb, kgdb, etc</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="compatibility">
|
||||
<title>Les couches de compatibilité</title>
|
||||
|
||||
<chapter id="linux">
|
||||
<title>Linux</title>
|
||||
|
||||
<para>Linux, SVR4, etc</para>
|
||||
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="appendices">
|
||||
<title>Bibligraphie</title>
|
||||
|
||||
<bibliography>
|
||||
|
||||
<biblioentry id="COD" xreflabel="1">
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Dave</firstname>
|
||||
<othername role="MI">A</othername>
|
||||
<surname>Patterson</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>John</firstname>
|
||||
<othername role="MI">L</othername>
|
||||
<surname>Hennessy</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<copyright><year>1998</year><holder>Morgan Kaufmann Publishers,
|
||||
Inc.</holder></copyright>
|
||||
<isbn>1-55860-428-6</isbn>
|
||||
<publisher>
|
||||
<publishername>Morgan Kaufmann Publishers, Inc.</publishername>
|
||||
</publisher>
|
||||
<title>Computer Organization and Design</title>
|
||||
<subtitle>The Hardware / Software Interface</subtitle>
|
||||
<pagenums>1-2</pagenums>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry xreflabel="2">
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>W.</firstname>
|
||||
<othername role="Middle">Richard</othername>
|
||||
<surname>Stevens</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<copyright><year>1993</year><holder>Addison Wesley Longman,
|
||||
Inc.</holder></copyright>
|
||||
<isbn>0-201-56317-7</isbn>
|
||||
<publisher>
|
||||
<publishername>Addison Wesley Longman, Inc.</publishername>
|
||||
</publisher>
|
||||
<title>Advanced Programming in the Unix Environment</title>
|
||||
<pagenums>1-2</pagenums>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry xreflabel="3">
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Marshall</firstname>
|
||||
<othername role="Middle">Kirk</othername>
|
||||
<surname>McKusick</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Keith</firstname>
|
||||
<surname>Bostic</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Michael</firstname>
|
||||
<othername role="MI">J</othername>
|
||||
<surname>Karels</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>John</firstname>
|
||||
<othername role="MI">S</othername>
|
||||
<surname>Quarterman</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<copyright><year>1996</year><holder>Addison-Wesley Publishing Company,
|
||||
Inc.</holder></copyright>
|
||||
<isbn>0-201-54979-4</isbn>
|
||||
<publisher>
|
||||
<publishername>Addison-Wesley Publishing Company, Inc.</publishername>
|
||||
</publisher>
|
||||
<title>The Design and Implementation of the 4.4 BSD Operating System</title>
|
||||
<pagenums>1-2</pagenums>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="Phrack" xreflabel="4">
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Aleph</firstname>
|
||||
<surname>One</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<title>Phrack 49; "Smashing the Stack for Fun and Profit"</title>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="StackGuard" xreflabel="5">
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Chrispin</firstname>
|
||||
<surname>Cowan</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Calton</firstname>
|
||||
<surname>Pu</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Dave</firstname>
|
||||
<surname>Maier</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<title>StackGuard; Automatic Adaptive Detection and Prevention of
|
||||
Buffer-Overflow Attacks</title>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="OpenBSD" xreflabel="6">
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Todd</firstname>
|
||||
<surname>Miller</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Theo</firstname>
|
||||
<surname>de Raadt</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<title>strlcpy and strlcat -- consistent, safe string copy and
|
||||
concatenation.</title>
|
||||
</biblioentry>
|
||||
|
||||
</bibliography>
|
||||
|
||||
</part>
|
||||
|
||||
</book>
|
64
fr_FR.ISO8859-1/books/developers-handbook/chapters.ent
Normal file
64
fr_FR.ISO8859-1/books/developers-handbook/chapters.ent
Normal file
|
@ -0,0 +1,64 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: chapters.ent,v 1.1 2002-02-14 14:25:01 gioria Exp $
|
||||
Original revision: 1.4
|
||||
Creates entities for each chapter in the FreeBSD Developer's
|
||||
Handbook. Each entity is named chap.foo, where foo is the value
|
||||
of the id attribute on that chapter, and corresponds to the name of
|
||||
the directory in which that chapter's .sgml file is stored.
|
||||
|
||||
Chapters should be listed in the order in which they are referenced.
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
<!-- Part one -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part two -->
|
||||
<!ENTITY chap.tools SYSTEM "tools/chapter.sgml">
|
||||
<!ENTITY chap.secure SYSTEM "secure/chapter.sgml">
|
||||
|
||||
<!-- Part three -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
<!ENTITY chap.locking SYSTEM "locking/chapter.sgml">
|
||||
|
||||
<!-- Part four -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part five -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part six -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part seven -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part eight -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part nine -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part ten -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part eleven -->
|
||||
<!ENTITY chap.driverbasics SYSTEM "driverbasics/chapter.sgml">
|
||||
<!ENTITY chap.pci SYSTEM "pci/chapter.sgml">
|
||||
<!ENTITY chap.scsi SYSTEM "scsi/chapter.sgml">
|
||||
<!ENTITY chap.usb SYSTEM "usb/chapter.sgml">
|
||||
|
||||
<!-- Part twelve -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part thirteen -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part fourteen -->
|
||||
<!-- No significant material yet, still in book.sgml -->
|
||||
|
||||
<!-- Part fifteen (appendices) -->
|
||||
<!ENTITY chap.bibliography SYSTEM "bibliography/chapter.sgml">
|
|
@ -0,0 +1,383 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: chapter.sgml,v 1.1 2002-02-14 14:25:02 gioria Exp $
|
||||
Original revision: 1.5
|
||||
$FreeBSD$
|
||||
|
||||
-->
|
||||
|
||||
<chapter id="driverbasics">
|
||||
<title>Ecrire des pilotes de périphériques pour FreeBSD</title>
|
||||
|
||||
<para>Ce chapître a été écrit par &.murray avec des sélections
|
||||
depuis une variété de codes source inclus dans la page de manuel d'intro(4) de Joerg
|
||||
Wunsch.</para>
|
||||
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>Ce chapître fournit une brêve introduction sur l'écriture
|
||||
de pilotes de périphériques pourFreeBSD.
|
||||
Un périphérique, dans ce contexte, est un terme utilisé
|
||||
le plus souvent pour tout ce qui est lié au matériel et qui dépend
|
||||
du système, comme les disques, imprimantes, ou un écran avec son clavier.
|
||||
Un pilote de périphérique est un composant logiciel du système
|
||||
d'exploitation qui contrôle un périphérique spécifique. Il y a aussi
|
||||
ce que l'on apelle les pseudo-périphériques ("pseudo-devices") où un pilote
|
||||
de périphérique émule le comportement d'un périphérique dans un logiciel sans
|
||||
matériel particulier sous-jacent. Les pilotes de périphériques peuvent être compilés
|
||||
dans le ystème statiquement ou chargé à la demande via l'éditeur de liens dynamique du
|
||||
noyau `kld'.</para>
|
||||
|
||||
<para>La plupart des périphériques dans un système d'exploitation de type Unix
|
||||
sont accessibles au travers de fichiers spéciaux de périphérique (device-nodes), appelés parfois
|
||||
fichiers spéciaux. Ces fichiers sont habituellement stockés dans le répertoire
|
||||
<filename>/dev</filename> de la hiérarchie du système de fichiers. Jusqu'à ce que
|
||||
devfs soit totalement intégré dans FreeBSD, chaque fichier spécial de périphérique doit être
|
||||
créé statiquement et indépendamment de l'existence du pilote de périphérique associé.
|
||||
La plupart des fichiers spéciaux de périphérique du système sont créés en exécutant <command>MAKEDEV</command>.</para>
|
||||
|
||||
<para>Les pilotes de périphérique peuvent être en gros séparés en deux catégories;
|
||||
les pilotes de périphérique en mode caractère et les pilotes de périphériques réseau.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>L'éditeur de liens dynamiques du noyau - KLD</title>
|
||||
<!-- Traduction à vérifier
|
||||
Dynamic Kernel Linker Facility - KLD</title> -->
|
||||
|
||||
<para>L'interface kld permet aux administrateurs système d'ajouter
|
||||
et d'enlever dynamiquement une fonctionnalité à un système en marche.
|
||||
Cela permet aux développeurs de pilote de périphérique de charger leurs nouveaux changements
|
||||
dans le noyau en fonctionnement sans redémarrer constamment pour tester ces derniers.
|
||||
</para>
|
||||
|
||||
<para>L'interface kld est utilisé au travers des commandes d'administrateur suivantes :
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><simpara><command>kldload</command> - charge un nouveau module dans le noyau</simpara></listitem>
|
||||
<listitem><simpara><command>kldunload</command> - décharge un module du noyau</simpara></listitem>
|
||||
<listitem><simpara><command>kldstat</command> - liste les modules chargés dans le noyau</simpara></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>Structure squelettique d'un module de noyau</para>
|
||||
|
||||
<programlisting>/*
|
||||
* Squelette KLD
|
||||
* Inspiré de l'article d'Andrew Reiter paru sur Daemonnews
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/systm.h> /* uprintf */
|
||||
#include <sys/errno.h>
|
||||
#include <sys/param.h> /* defines utilise dans kernel.h */
|
||||
#include <sys/kernel.h> /* types utilise dans le module d'initialisation */
|
||||
|
||||
/*
|
||||
* charge le gestionnaire quit traite du chargement et déchargement d'un KLD.
|
||||
*/
|
||||
|
||||
static int
|
||||
skel_loader(struct module *m, int what, void *arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (what) {
|
||||
case MOD_LOAD: /* kldload */
|
||||
<!-- Désolé, les accents n'existent pas dans la console alors je ne les ai pas mis là non plus
|
||||
-->
|
||||
uprintf("Skeleton KLD charge.\n");
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
uprintf("Skeleton KLD decharge.\n");
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* Declare ce module au reste du noyau */
|
||||
|
||||
DECLARE_MODULE(skeleton, skel_loader, SI_SUB_KLD, SI_ORDER_ANY);</programlisting>
|
||||
|
||||
|
||||
<sect2>
|
||||
<title>Makefile</title>
|
||||
|
||||
<para>FreeBSD fournit un fichier d'inclusion "makefile" que vous pouvez utiliser pour
|
||||
compiler rapidement votre ajout au noyau.</para>
|
||||
|
||||
<programlisting>SRCS=skeleton.c
|
||||
KMOD=skeleton
|
||||
|
||||
.include <bsd.kmod.mk></programlisting>
|
||||
|
||||
<para>Lancer simplement la commande <command>make</command> avec ce fichier Makefile
|
||||
créera un fichier <filename>skeleton.ko</filename> qui peut
|
||||
être chargé dans votre système en tapant :
|
||||
<screen> &prompt.root
|
||||
kldload -v ./skeleton.ko
|
||||
</screen>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Accéder au pilote d'un périphérique</title>
|
||||
|
||||
<para>Unix fournit un ensemble d'appels sytème communs utilisable par
|
||||
les applications de l'utilisateur. Les couches supérieures du noyau renvoient
|
||||
ces appels au pilote de périphérique correspondant quand un utilisateur
|
||||
accède au fichier spécial de périphérique. Le script <command>/dev/MAKEDEV</command>
|
||||
crée la plupart des fichiers spéciaux de périphérique pour votre système mais si vous
|
||||
faites votre propre développement de pilote, il peut être nécessaire de créer
|
||||
vos propres fichiers spéciaux de périphérique avec la commande <command>mknod</command>
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Créer des fichiers spéciaux de périphériques statiques</title>
|
||||
|
||||
<para>La commande <command>mknod</command> nécessite quatre
|
||||
arguments pou créer un fichier spécial de périphérique. Vous devez spécifier le nom
|
||||
de ce fichier spécial de périphérique, le type de périphérique, le numéro majeur
|
||||
et le numéro mineur du périphérique.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Les fichiers spéciaux de périphérique dynamiques</title>
|
||||
|
||||
<para>Le périphérique système de fichiers, ou devfs, fournit l'accès à
|
||||
l'espace des noms des périphériques du noyau dans l'espace du système de fichiers global.
|
||||
Ceci élimine les problèmes de pilote sans fichier spécial statique, ou de fichier spécial sans pilote installé.
|
||||
Devfs est toujours un travail en cours mais il fonctionne déjà assez bien.</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Les périphériques caractères</title>
|
||||
|
||||
<para>Un pilote de périphérique caractère est un pilote qui tranfère les données
|
||||
directement au processus utilisateur ou vers celui-ci. Il s'agit du plus commun
|
||||
des types de pilote de périphérique et il y en a plein d'exemples simples dans
|
||||
l'arbre des sources.</para>
|
||||
|
||||
<para>Cet exemple simple de pseudo-périphérique enregistre toutes les valeurs
|
||||
que vous lui avez écrites et peut vous les renvoyer quand vous les lui
|
||||
demandez.</para>
|
||||
|
||||
<programlisting>/*
|
||||
* un simple pseudo-périphérique `echo' KLD
|
||||
*
|
||||
* Murray Stokely
|
||||
*/
|
||||
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/systm.h> /* uprintf */
|
||||
#include <sys/errno.h>
|
||||
#include <sys/param.h> /* defines utilises dans kernel.h */
|
||||
#include <sys/kernel.h> /* types utilises dans me module d'initialisation */
|
||||
#include <sys/conf.h> /* cdevsw struct */
|
||||
#include <sys/uio.h> /* uio struct */
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#define BUFFERSIZE 256
|
||||
|
||||
/* Prototypes des fonctions */
|
||||
d_open_t echo_open;
|
||||
d_close_t echo_close;
|
||||
d_read_t echo_read;
|
||||
d_write_t echo_write;
|
||||
|
||||
/* Points d'entrée du périphérique Caractère */
|
||||
static struct cdevsw echo_cdevsw = {
|
||||
echo_open,
|
||||
echo_close,
|
||||
echo_read,
|
||||
echo_write,
|
||||
noioctl,
|
||||
nopoll,
|
||||
nommap,
|
||||
nostrategy,
|
||||
"echo",
|
||||
33, /* reserve pour lkms - /usr/src/sys/conf/majors */
|
||||
nodump,
|
||||
nopsize,
|
||||
D_TTY,
|
||||
-1
|
||||
};
|
||||
|
||||
typedef struct s_echo {
|
||||
char msg[BUFFERSIZE];
|
||||
int len;
|
||||
} t_echo;
|
||||
|
||||
/* variables */
|
||||
static dev_t sdev;
|
||||
static int len;
|
||||
static int count;
|
||||
static t_echo *echomsg;
|
||||
|
||||
MALLOC_DECLARE(M_ECHOBUF);
|
||||
MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "cache pour le module echo");
|
||||
|
||||
/*
|
||||
* Cette fonction est appele par les appels systeme kld[un]load(2) pour
|
||||
* determiner quelles actions doivent etre faites quand le
|
||||
* module est charge ou decharge
|
||||
*/
|
||||
|
||||
static int
|
||||
echo_loader(struct module *m, int what, void *arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (what) {
|
||||
case MOD_LOAD: /* kldload */
|
||||
sdev = make_dev(<literal>&</literal>echo_cdevsw,
|
||||
0,
|
||||
UID_ROOT,
|
||||
GID_WHEEL,
|
||||
0600,
|
||||
"echo");
|
||||
/* aloocation de mémoire noyau pour l'utilisation de ce module */
|
||||
/* malloc(256,M_ECHOBUF,M_WAITOK); */
|
||||
MALLOC(echomsg, t_echo *, sizeof(t_echo), M_ECHOBUF, M_WAITOK);
|
||||
printf("Peripherique Echo charge.\n");
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
destroy_dev(sdev);
|
||||
FREE(echomsg,M_ECHOBUF);
|
||||
printf("Peripherique Echo decharge.\n");
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
int
|
||||
echo_open(dev_t dev, int oflags, int devtype, struct proc *p)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
uprintf("Peripherique \"echo\" ouvert avec succes.\n");
|
||||
return(err);
|
||||
}
|
||||
|
||||
int
|
||||
echo_close(dev_t dev, int fflag, int devtype, struct proc *p)
|
||||
{
|
||||
uprintf("Fermeture du peripherique \"echo.\"\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* La fonction read prend juste comme parametre
|
||||
* le cache qui a ete sauve par l'appel à echo_write()
|
||||
* et le retourne a l'utilisateur pour acces.
|
||||
* uio(9)
|
||||
*/
|
||||
|
||||
int
|
||||
echo_read(dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
int err = 0;
|
||||
int amt;
|
||||
|
||||
/* De quelle taille est cette operation read ? Aussi grande que l'utilisateur le veut,
|
||||
ou aussi grande que les donnees restantes */
|
||||
amt = MIN(uio->uio_resid, (echomsg->len - uio->uio_offset > 0) ? echomsg->len - uio->uio_offset : 0);
|
||||
if ((err = uiomove(echomsg->msg + uio->uio_offset,amt,uio)) != 0) {
|
||||
uprintf("uiomove echoue!\n");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* echo_write prend un caractere en entree et le sauve
|
||||
* dans le cache pour une utilisation ulterieure.
|
||||
*/
|
||||
|
||||
int
|
||||
echo_write(dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
/* Copie la chaine d'entree de la memoire de l'utilisateur a la memoire du noyau*/
|
||||
err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_len,BUFFERSIZE));
|
||||
|
||||
/* Maintenant nous avons besoin de terminer la chaine par NULL */
|
||||
*(echomsg->msg + MIN(uio->uio_iov->iov_len,BUFFERSIZE)) = 0;
|
||||
/* Enregistre la taille */
|
||||
echomsg->len = MIN(uio->uio_iov->iov_len,BUFFERSIZE);
|
||||
|
||||
if (err != 0) {
|
||||
uprintf("Ecriture echouee: mauvaise adresse!\n");
|
||||
}
|
||||
|
||||
count++;
|
||||
return(err);
|
||||
}
|
||||
|
||||
DEV_MODULE(echo,echo_loader,NULL);</programlisting>
|
||||
|
||||
<para>Pour installer ce pilote, vous devrez d'abord créer un fichier spécial dans
|
||||
votre système de fichiers avec une commande comme : </para>
|
||||
|
||||
<screen>
|
||||
&prompt.root mknod /dev/echo c 33 0
|
||||
</screen>
|
||||
|
||||
<para>Avec ce pilote chargé, vous devriez maintenant êtr capable de taper
|
||||
quelque chose comme :</para>
|
||||
|
||||
<screen>
|
||||
&prompt.root echo -n "Test Donnees" > /dev/echo
|
||||
&prompt.root cat /dev/echo
|
||||
Test Donnees
|
||||
</screen>
|
||||
|
||||
<para>Périphériques réels dans le chapître suivant.</para>
|
||||
|
||||
<para>Informations additionnelles
|
||||
<itemizedlist>
|
||||
<listitem><simpara><ulink
|
||||
url="http://www.daemonnews.org/200010/blueprints.html">Dynamic
|
||||
Kernel Linker (KLD) Facility Programming Tutorial</ulink> -
|
||||
<ulink url="http://www.daemonnews.org">Daemonnews</ulink> October 2000</simpara></listitem>
|
||||
<listitem><simpara><ulink
|
||||
url="http://www.daemonnews.org/200007/newbus-intro.html">How
|
||||
to Write Kernel Drivers with NEWBUS</ulink> - <ulink
|
||||
url="http://www.daemonnews.org">Daemonnews</ulink> July
|
||||
2000</simpara></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Pilotes Réseau</title>
|
||||
|
||||
<para>Les pilotes pour périphérique réseau n'utilisent pas les fichiers spéciaux pour
|
||||
pouvoir être acessibles. Leur sélection est basée sur d'autres décisions
|
||||
faites à l'intérieur du noyau et plutôt que d'appeler open(), l'utilisation
|
||||
d'un périphérique réseau se fait généralement en se servant de l'appel système
|
||||
socket(2).</para>
|
||||
|
||||
<para>man ifnet(), périphérique "en boucle", drivers de Bill Paul,
|
||||
etc..</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
335
fr_FR.ISO8859-1/books/developers-handbook/locking/chapter.sgml
Normal file
335
fr_FR.ISO8859-1/books/developers-handbook/locking/chapter.sgml
Normal file
|
@ -0,0 +1,335 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
The FreeBSD SMP Next Generation Project
|
||||
$Id: chapter.sgml,v 1.1 2002-02-14 14:25:02 gioria Exp $
|
||||
Original revision: 1.2
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
|
||||
<chapter id="locking">
|
||||
<title>Notes sur le verrouillage</title>
|
||||
|
||||
<para><emphasis>Ce chapître est maintenu par The FreeBSD SMP Next
|
||||
Generation Project
|
||||
<email>freebsd-smp@FreeBSD.org</email>.</emphasis></para>
|
||||
|
||||
|
||||
<para>Ce document souligne le verrouillage utilisé dans le noyau FreeBSD
|
||||
pour permettre d'utiliser du vrai multi-processeur à l'intérieur du noyau.
|
||||
Le verrouillage peut être réalisé par différents moyens.
|
||||
Les structures de données puvent être protégées par des mutex ou &man.lockmgr.9; verrous.
|
||||
Quelques variables sont protégées simplement par l'utilisation continuelle d'opérations
|
||||
atomiques pour y accéder.
|
||||
</para>
|
||||
|
||||
<sect1>
|
||||
<title>Les mutex</title>
|
||||
|
||||
<para>Un mutex est simplement un verrou utilisé pour garantir exclusion mutuelle.
|
||||
Spécifiquement, un mutex ne peut appartenir qu'à une entité à la fois.
|
||||
Si une autre entité désire obtenir un mutex déjà pris
|
||||
, elle doit attendre jusqu'à ce que le mutex soit relaché. Dans le noyau
|
||||
FreeBSD, les mutex appartiennent aux processus.</para>
|
||||
|
||||
<para>Les mutex peuvent être acquis récursivement, mais ils sont conçus
|
||||
pour n'être pris que pendant une courte période. Spécifiquement, le détenteur
|
||||
ne doit pas se suspendre pendant qu'il retient un mutex. Si vous avez besoin de
|
||||
maintenir un verrouillage pendant une suspension, utilisez un &man.lockmgr.9; verrou ("lock").</para>
|
||||
|
||||
<para>Chaque mutex a plusieurs intérêts :</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Nom de la variable</term>
|
||||
<listitem>
|
||||
<para>Nom de la variable <type>struct mtx</type> dans
|
||||
le code source du noyau.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Nom logique</term>
|
||||
<listitem>
|
||||
<para>Le nom du mutex lui est assigné par
|
||||
<function>mtx_init</function>. Ce nom est affiché dans
|
||||
les messages de trace KTR, témoigne des erreurs et avertissements et est
|
||||
utilisé pour distinguer les mutex dans les traces.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Type</term>
|
||||
<listitem>
|
||||
<para>Le type du mutex en termes de constantes nommées
|
||||
<constant>MTX_*</constant>. La signification de chaque
|
||||
constante nommée est documentée dans &man.mutex.9;.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><constant>MTX_DEF</constant></term>
|
||||
<listitem>
|
||||
<para>Un mutex endormi</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>MTX_SPIN</constant></term>
|
||||
<listitem>
|
||||
<para>Un mutex tournant</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>MTX_COLD</constant></term>
|
||||
<listitem>
|
||||
<para>Ce mutex est initialisé très tard. Toutefois, il
|
||||
doit être déclaré via
|
||||
<function>MUTEX_DECLARE</function>, et la constante nommée
|
||||
<constant>MTX_COLD</constant> doit être passée à
|
||||
<function>mtx_init</function>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>MTX_TOPHALF</constant></term>
|
||||
<listitem>
|
||||
<para>Ce mutex tournant ne désactive pas les
|
||||
interruptions.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>MTX_NORECURSE</constant></term>
|
||||
<listitem>
|
||||
<para>Ce mutex n'a pas la permission d'être recursif.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Protégés</term>
|
||||
<listitem>
|
||||
<para>Une liste de structures de données ou des membres de structure de données
|
||||
que cette entrée protège. Pour les membres de structures de données,
|
||||
le nom sera de la forme <structname/structure name/.<structfield/member name/.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Fonctions dépendantes</term>
|
||||
<listitem>
|
||||
<para>Les fonctions qui peuvent seulement être appelées si ce mutex est
|
||||
pris.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<table frame="all" colsep="1" rowsep="1" pgwide="1">
|
||||
<title>Liste du mutex</title>
|
||||
|
||||
<tgroup cols="5">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Nom de la variable</entry>
|
||||
<entry>Nom logique</entry>
|
||||
<entry>Type</entry>
|
||||
<entry>Protégés</entry>
|
||||
<entry>Fonctions dépendantes</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<!-- The scheduler lock -->
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>sched_lock</entry>
|
||||
<entry><quote>sched lock</quote></entry>
|
||||
<entry>
|
||||
<constant>MTX_SPIN</constant> |
|
||||
<constant>MTX_COLD</constant>
|
||||
</entry>
|
||||
<entry>
|
||||
<varname>_gmonparam</varname>,
|
||||
<varname>cnt.v_swtch</varname>,
|
||||
<varname>cp_time</varname>,
|
||||
<varname>curpriority</varname>,
|
||||
<structname/mtx/.<structfield/mtx_blocked/,
|
||||
<structname/mtx/.<structfield/mtx_contested/,
|
||||
<structname/proc/.<structfield/p_contested/,
|
||||
<structname/proc/.<structfield/p_blocked/,
|
||||
<structname/proc/.<structfield/p_flag/
|
||||
(<constant>P_PROFIL</constant> XXX,
|
||||
<constant>P_INMEM</constant>,
|
||||
<constant>P_SINTR</constant>,
|
||||
<constant>P_TIMEOUT</constant>,
|
||||
<constant>P_SWAPINREQ</constant> XXX,
|
||||
<constant>P_INMEN</constant> XXX),
|
||||
<structname/proc/.<structfield/p_nice/,
|
||||
<structname/proc/.<structfield/p_procq/,
|
||||
<structname/proc/.<structfield/p_blocked/,
|
||||
<structname/proc/.<structfield/p_estcpu/,
|
||||
<structname/proc/.<structfield/p_nativepri/,
|
||||
<structname/proc/.<structfield/p_priority/,
|
||||
<structname/proc/.<structfield/p_usrpri/,
|
||||
<structname/proc/.<structfield/p_rtprio/,
|
||||
<structname/proc/.<structfield/p_rqindex/,
|
||||
<structname/proc/.<structfield/p_stats->p_prof/,
|
||||
<structname/proc/.<structfield/p_stats->p_ru/,
|
||||
<structname/proc/.<structfield/p_stat/,
|
||||
<structname/proc/.<structfield/p_cpticks/
|
||||
<structname/proc/.<structfield/p_iticks/,
|
||||
<structname/proc/.<structfield/p_uticks/,
|
||||
<structname/proc/.<structfield/p_sticks/,
|
||||
<structname/proc/.<structfield/p_swtime/,
|
||||
<structname/proc/.<structfield/p_slptime/,
|
||||
<structname/proc/.<structfield/p_runtime/,
|
||||
<structname/proc/.<structfield/p_pctcpu/,
|
||||
<structname/proc/.<structfield/p_oncpu/,
|
||||
<structname/proc/.<structfield/p_asleep/,
|
||||
<structname/proc/.<structfield/p_wchan/,
|
||||
<structname/proc/.<structfield/p_wmesg/,
|
||||
<structname/proc/.<structfield/p_slpq/,
|
||||
<structname/proc/.<structfield/p_vmspace/
|
||||
(XXX - in <function>statclock</function>),
|
||||
<varname>pscnt</varname>,
|
||||
<varname>slpque</varname>,
|
||||
<varname>itqueuebits</varname>,
|
||||
<varname>itqueues</varname>,
|
||||
<varname>rtqueuebits</varname>,
|
||||
<varname>rtqueues</varname>,
|
||||
<varname>queuebits</varname>,
|
||||
<varname>queues</varname>,
|
||||
<varname>idqueuebits</varname>,
|
||||
<varname>idqueues</varname>,
|
||||
<varname>switchtime</varname>,
|
||||
</entry>
|
||||
<entry>
|
||||
<function>setrunqueue</function>,
|
||||
<function>remrunqueue</function>,
|
||||
<function>mi_switch</function>,
|
||||
<function>chooseproc</function>,
|
||||
<function>schedclock</function>,
|
||||
<function>resetpriority</function>,
|
||||
<function>updatepri</function>,
|
||||
<function>maybe_resched</function>,
|
||||
<function>cpu_switch</function>,
|
||||
<function>cpu_throw</function>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- The vm86 pcb lock -->
|
||||
<row>
|
||||
<entry>vm86pcb_lock</entry>
|
||||
<entry><quote>vm86pcb lock</quote></entry>
|
||||
<entry>
|
||||
<constant>MTX_DEF</constant> |
|
||||
<constant>MTX_COLD</constant>
|
||||
</entry>
|
||||
<entry>
|
||||
<varname>vm86pcb</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
<function>vm86_bioscall</function>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- Giant -->
|
||||
<row>
|
||||
<entry>Giant</entry>
|
||||
<entry><quote>Giant</quote></entry>
|
||||
<entry>
|
||||
<constant>MTX_DEF</constant> |
|
||||
<constant>MTX_COLD</constant>
|
||||
</entry>
|
||||
<entry>nearly everything</entry>
|
||||
<entry>lots</entry>
|
||||
</row>
|
||||
|
||||
<!-- The callout lock -->
|
||||
<row>
|
||||
<entry>callout_lock</entry>
|
||||
<entry><quote>callout lock</quote></entry>
|
||||
<entry>
|
||||
<constant>MTX_SPIN</constant>
|
||||
</entry>
|
||||
<entry>
|
||||
<varname>callfree</varname>,
|
||||
<varname>callwheel</varname>,
|
||||
<varname>nextsoftcheck</varname>,
|
||||
<structname/proc/.<structfield/p_itcallout/,
|
||||
<structname/proc/.<structfield/p_slpcallout/,
|
||||
<varname>softticks</varname>,
|
||||
<varname>ticks</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Les verrous du gestionnaire de verrous (Lock Manager)</title>
|
||||
|
||||
<para>Les verrous qui sont fournis par l'interface &man.lockmgr.9;
|
||||
sont les verrous du gestionnaire de verrous. Ces verrous sont des verrous
|
||||
lecture-écriture et peuvent être retenus par un process suspendu.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title>&man.lockmgr.9; List de verrou</title>
|
||||
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Nom de la variable</entry>
|
||||
<entry>Protégés</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><varname>allproc_lock</varname></entry>
|
||||
<entry>
|
||||
<varname>allproc</varname>
|
||||
<varname>zombproc</varname>
|
||||
<varname>pidhashtbl</varname>
|
||||
<structname/proc/.<structfield/p_list/
|
||||
<structname/proc/.<structfield/p_hash/
|
||||
<varname>nextpid</varname>
|
||||
</entry>
|
||||
<entry><varname>proctree_lock</varname></entry>
|
||||
<entry>
|
||||
<structname/proc/.<structfield/p_children/
|
||||
<structname/proc/.<structfield/p_sibling/
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Variables protégées atomiquement</title>
|
||||
|
||||
<para>Une variable protégée atomiquement est une variable spéciale qui
|
||||
n'est pas protégé par un verrou explicite. Toutefois, tous les accès de
|
||||
données aux variables utilisent des opérations atomiques spéciales
|
||||
comme décrit dans &man.atomic.9;. Très peu de variables sont traitées
|
||||
de cette façon, bien que les autres primitives de synchronisation comme
|
||||
les mutex soient implémentées avec des variables protégées atomiquement.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><varname>astpending</varname></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><structname/mtx/.<structfield/mtx_lock/</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
</chapter>
|
376
fr_FR.ISO8859-1/books/developers-handbook/pci/chapter.sgml
Normal file
376
fr_FR.ISO8859-1/books/developers-handbook/pci/chapter.sgml
Normal file
|
@ -0,0 +1,376 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: chapter.sgml,v 1.1 2002-02-14 14:25:02 gioria Exp $
|
||||
Original revision: 1.3
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
<chapter id="pci">
|
||||
<title>Les périphériques PCI</title>
|
||||
|
||||
<para>Ce chapître traitera des mécanismes de FreeBSD pour
|
||||
écrire un pilote de périphérique pour un périphérique sur
|
||||
bus PCI.</para>
|
||||
|
||||
<sect1>
|
||||
<title>Rechercher et rattacher</title>
|
||||
|
||||
<para>Informations ici sur comment le code du bus PCI fait un cycle
|
||||
sur les périphériques non rattachés et voir si le nouvellement chargé
|
||||
pilote de périphérique chargeable dans le noyau (kld)
|
||||
sera rattaché à l'un d'eux.</para>
|
||||
|
||||
<programlisting>/*
|
||||
* Simple KLD pour jouer avec les fonctions PCI.
|
||||
*
|
||||
* Murray Stokely
|
||||
*/
|
||||
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/systm.h> /* uprintf */
|
||||
#include <sys/errno.h>
|
||||
#include <sys/param.h> /* defines used in kernel.h */
|
||||
#include <sys/kernel.h> /* types used in module initialization */
|
||||
#include <sys/conf.h> /* cdevsw struct */
|
||||
#include <sys/uio.h> /* uio struct */
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h> /* structs, prototypes for pci bus stuff */
|
||||
|
||||
#include <pci/pcivar.h> /* For get_pci macros! */
|
||||
|
||||
/* Prototypes des fonctions */
|
||||
d_open_t mypci_open;
|
||||
d_close_t mypci_close;
|
||||
d_read_t mypci_read;
|
||||
d_write_t mypci_write;
|
||||
|
||||
/* Points d'entrée du pilote de périphérique caractère */
|
||||
|
||||
static struct cdevsw mypci_cdevsw = {
|
||||
mypci_open,
|
||||
mypci_close,
|
||||
mypci_read,
|
||||
mypci_write,
|
||||
noioctl,
|
||||
nopoll,
|
||||
nommap,
|
||||
nostrategy,
|
||||
"mypci",
|
||||
36, /* reserved for lkms - /usr/src/sys/conf/majors */
|
||||
nodump,
|
||||
nopsize,
|
||||
D_TTY,
|
||||
-1
|
||||
};
|
||||
|
||||
/* variables */
|
||||
static dev_t sdev;
|
||||
|
||||
/* Nous sommes plus interresses dans la recherche/attachement
|
||||
que dans l'ouverture/fermeture/lecture/ecriture a ce point */
|
||||
|
||||
int
|
||||
mypci_open(dev_t dev, int oflags, int devtype, struct proc *p)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
uprintf("Peripherique \"monpci\" ouvert avec succes.\n");
|
||||
return(err);
|
||||
}
|
||||
|
||||
int
|
||||
mypci_close(dev_t dev, int fflag, int devtype, struct proc *p)
|
||||
{
|
||||
int err=0;
|
||||
|
||||
uprintf("Peripherique \"monpci.\ "ferme\n");
|
||||
return(err);
|
||||
}
|
||||
|
||||
int
|
||||
mypci_read(dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
uprintf("lecture dans monpci!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
mypci_write(dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
uprintf("Ecriture dans monpci!\n");
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* PCI Support Functions */
|
||||
|
||||
/*
|
||||
* Retourne la chaine d'identification si ce peripherique est le notre
|
||||
*/
|
||||
static int
|
||||
mypci_probe(device_t dev)
|
||||
{
|
||||
uprintf("MonPCI Probe\n"
|
||||
"ID Fabricant: 0x%x\n"
|
||||
"ID Peripherique : 0x%x\n",pci_get_vendor(dev),pci_get_device(dev));
|
||||
|
||||
if (pci_get_vendor(dev) == 0x11c1) {
|
||||
uprintf("Nous avons le WinModem, recherche reussi!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
/* La fonction Attach n'est appelée que si
|
||||
la recherche est reussie*/
|
||||
|
||||
static int
|
||||
mypci_attach(device_t dev)
|
||||
{
|
||||
uprintf("Rattachement de MonPCI pour: ID Peripherique: 0x%x\n",pci_get_vendor(dev));
|
||||
sdev = make_dev(<literal>&</literal>mypci_cdevsw,
|
||||
0,
|
||||
UID_ROOT,
|
||||
GID_WHEEL,
|
||||
0600,
|
||||
"monpci");
|
||||
uprintf("Peripherique Monpci charge.\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
/* Detach le peripherique. */
|
||||
|
||||
static int
|
||||
mypci_detach(device_t dev)
|
||||
{
|
||||
uprintf("Monpci detache!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Appele lors de l'arret du systeme apres sync. */
|
||||
|
||||
static int
|
||||
mypci_shutdown(device_t dev)
|
||||
{
|
||||
uprintf("Monpci arrete!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* routine de suspension du peripherique
|
||||
*/
|
||||
static int
|
||||
mypci_suspend(device_t dev)
|
||||
{
|
||||
uprintf("Monpci suspendu!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* routine de reprise du peripherique
|
||||
*/
|
||||
|
||||
static int
|
||||
mypci_resume(device_t dev)
|
||||
{
|
||||
uprintf("Monpci resume!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static device_method_t mypci_methods[] = {
|
||||
/* Interface Peripherique*/
|
||||
DEVMETHOD(device_probe, mypci_probe),
|
||||
DEVMETHOD(device_attach, mypci_attach),
|
||||
DEVMETHOD(device_detach, mypci_detach),
|
||||
DEVMETHOD(device_shutdown, mypci_shutdown),
|
||||
DEVMETHOD(device_suspend, mypci_suspend),
|
||||
DEVMETHOD(device_resume, mypci_resume),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t mypci_driver = {
|
||||
"monpci",
|
||||
mypci_methods,
|
||||
0,
|
||||
/* sizeof(struct mypci_softc), */
|
||||
};
|
||||
|
||||
static devclass_t mypci_devclass;
|
||||
|
||||
DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);</programlisting>
|
||||
|
||||
<para>Informations complémentaires
|
||||
<itemizedlist>
|
||||
<listitem><simpara><ulink url="http://www.pcisig.org">PCI
|
||||
Special Interest Group</ulink></simpara></listitem>
|
||||
|
||||
<listitem><simpara>PCI System Architecture, Fourth Edition by
|
||||
Tom Shanley, et al.</simpara></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Les ressources du bus</title>
|
||||
|
||||
<para>FreeBSD fournit un mécanisme orienté objet pour demander
|
||||
des ressources du bus parent. Pratiquement tous les périphériques
|
||||
seront un fils membre d'un type de bus (PCI, ISA, USB, SCSI, etc)
|
||||
et ces périphériques nécessite des ressources issues de leur bus parent
|
||||
(comme des segments de mémoire, des interruptions or des canaux DMA).</para>
|
||||
|
||||
<sect2>
|
||||
<title>Registres d'adresse de base</title>
|
||||
|
||||
<para>Pour faire de particulièrement utile avec un périphérique PCI,
|
||||
vous aurez besoin d'obtenir les <emphasis>registres d'adresse de base</emphasis>
|
||||
(Base Address Registers ou BARs) de l'espace de configuration PCI.
|
||||
Les détails spécifiques au PCI sur l'obtention du registre d'adresse de base
|
||||
sont masqués dans la fonction <function>bus_alloc_resource()</function>.</para>
|
||||
|
||||
<para>Par exemple, un pilote typique aura sa fonction <function>attach()</function>
|
||||
similaire à ceci : </para>
|
||||
|
||||
<programlisting> sc->bar0id = 0x10;
|
||||
sc->bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->bar0id),
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
if (sc->bar0res == NULL) {
|
||||
uprintf("Allocation memoire du registre PCI de base 0 echouee!\n");
|
||||
error = ENXIO;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
sc->bar1id = 0x14;
|
||||
sc->bar1res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->bar1id),
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
if (sc->bar1res == NULL) {
|
||||
uprintf("Allocation memoire du registre PCI de base 1 echouee!\n");
|
||||
error = ENXIO;
|
||||
goto fail2;
|
||||
}
|
||||
sc->bar0_bt = rman_get_bustag(sc->bar0res);
|
||||
sc->bar0_bh = rman_get_bushandle(sc->bar0res);
|
||||
sc->bar1_bt = rman_get_bustag(sc->bar1res);
|
||||
sc->bar1_bh = rman_get_bushandle(sc->bar1res);
|
||||
|
||||
</programlisting>
|
||||
|
||||
<para>Des références pour chaque registre d'adresse de base sont gardées
|
||||
dans la structure <structname>softc</structname> afin qu'elle puisse
|
||||
être utilisée pour écrire dans le périphérique plus tard.</para>
|
||||
|
||||
<para>Ces références peuvent alors être utilisées pour lire ou écrire
|
||||
dans les registres du périphérique avec les fonctions <function>bus_space_*</function>.
|
||||
Par exemple, un pilote peut contenir une fonction raccourci
|
||||
pour lire dans un registre spécifique à une carte comme cela :
|
||||
</para>
|
||||
|
||||
<programlisting>uint16_t
|
||||
board_read(struct ni_softc *sc, uint16_t address) {
|
||||
return bus_space_read_2(sc->bar1_bt, sc->bar1_bh, address);
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>De façon similaire, une autre peut écrire dans les registres avec : </para>
|
||||
|
||||
<programlisting>void
|
||||
board_write(struct ni_softc *sc, uint16_t address, uint16_t value) {
|
||||
bus_space_write_2(sc->bar1_bt, sc->bar1_bh, address, value);
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>Ces fonctions existent en versions 8bit, 16bit et 32bit
|
||||
et vous devriez utiliser
|
||||
<function>bus_space_{read|write}_{1|2|4}</function>
|
||||
en conséquence.</para>
|
||||
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Les interruptions</title>
|
||||
|
||||
<para>Les interruptions sont alloués à partir du code orienté objet du
|
||||
bus de façon similaire aux ressources mémoire. D'abord une ressource
|
||||
IRQ doit être allouée à partir du bus parent, et alors le
|
||||
gestionnaire d'interruption doit être règlé pour traiter cet IRQ.</para>
|
||||
|
||||
<para>A nouveau, un exemple de fonction
|
||||
<function>attach()</function> en dit plusqu'un long discours.</para>
|
||||
|
||||
<programlisting>/* Recupere la ressource IRQ */
|
||||
|
||||
sc->irqid = 0x0;
|
||||
sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &(sc->irqid),
|
||||
0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->irqres == NULL) {
|
||||
uprintf("Allocation IRQ echouee!\n");
|
||||
error = ENXIO;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* Maitnenant nous choisissons notre gestionnaire d'interruption */
|
||||
|
||||
error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_MISC,
|
||||
my_handler, sc, &(sc->handler));
|
||||
if (error) {
|
||||
printf("Ne peut regler l'IRQ\n");
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
sc->irq_bt = rman_get_bustag(sc->irqres);
|
||||
sc->irq_bh = rman_get_bushandle(sc->irqres);
|
||||
</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>DMA</title>
|
||||
<para>Sur les PC, les périphériques qui veulent utiliser la gestion de
|
||||
bus DMA doivent travailler avec des adresses physiques. C'est un problème
|
||||
puisque FreeBSD utilise une mémoire virtuelle et travaille presque
|
||||
exclusivement avec des adresses virtuelles. Heureusement, il y a une
|
||||
fonction <function>vtophys()</function> pour nous aider.</para>
|
||||
|
||||
<programlisting>#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#define vtophys(virtual_address) (...)
|
||||
</programlisting>
|
||||
|
||||
<para>La solution est toutefois un peu différente sur Alpha, et
|
||||
ce que nous voulons réellement est une fonction appelée
|
||||
<function>vtobus()</function>.</para>
|
||||
|
||||
<programlisting>#if defined(__alpha__)
|
||||
#define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va)
|
||||
#else
|
||||
#define vtobus(va) vtophys(va)
|
||||
#endif
|
||||
</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Désallouer les resources</title>
|
||||
|
||||
<para>Il est très important de désallouer toutes les ressources
|
||||
qui furent allouées pendant <function>attach()</function>.
|
||||
Unsoin tout particulier doit être pris pour désallouer
|
||||
les bonnes choses même lors d'un échec afin que le système reste
|
||||
utilisable lorsque votre driver meurt.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
|
16
fr_FR.ISO8859-1/books/developers-handbook/scsi/chapter.sgml
Normal file
16
fr_FR.ISO8859-1/books/developers-handbook/scsi/chapter.sgml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: chapter.sgml,v 1.1 2002-02-14 14:25:02 gioria Exp $
|
||||
Original revision: 1.3
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
<chapter id="scsi">
|
||||
|
||||
<title>Contrôleurs SCSI Common Access Method (CAM) **</title>
|
||||
<sect1><title>En cours de traduction</title>
|
||||
<para>En cours de traduction</para>
|
||||
</sect1>
|
||||
</chapter>
|
425
fr_FR.ISO8859-1/books/developers-handbook/secure/chapter.sgml
Normal file
425
fr_FR.ISO8859-1/books/developers-handbook/secure/chapter.sgml
Normal file
|
@ -0,0 +1,425 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: chapter.sgml,v 1.1 2002-02-14 14:25:02 gioria Exp $
|
||||
Original revision: 1.3
|
||||
$FreeBSD$
|
||||
|
||||
-->
|
||||
|
||||
<chapter id="secure">
|
||||
<title>Programmation sécurisée</title>
|
||||
|
||||
<para>Ce chapître a été écrit par Murray Stokely.</para>
|
||||
|
||||
<sect1><title>Synopsis</title>
|
||||
|
||||
<para>Ce chapître décrit quelques problèmes de sécurité qui
|
||||
ont tourmenté les programmeurs Unix depuis des dizaines d'années
|
||||
et quelques uns des nouveaux outils disponibles pour aider
|
||||
les programmeurs à éviter l'écriture de code non sécurisé.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="secure-philosophy"><title>Méthodologie de développement
|
||||
sécurisé</title>
|
||||
|
||||
<para>Ecrire des applications sécurisées demande une très minutieuse
|
||||
et pessimiste vision de la vie. Les applications devrait fonctionner
|
||||
avec le principe du <quote>privilège moindre</quote> de façon à ce
|
||||
qu'aucun processus ne fonctionne avec plus que le strict minimum dont
|
||||
il a besoin pour accomplir sa tâche. Le code pré-testé devrait être
|
||||
réutilisé autant que possible pour éviter les erreurs communes que
|
||||
d'autres peuvent déjà avoir réparées.</para>
|
||||
|
||||
<para>Un des pièges de l'environnement Unix est qu'il est facile
|
||||
d'affecter la stabilité de l'environnement.
|
||||
Les applications ne devraient jamais avoir confiance dans la saisie
|
||||
de l'utilisateur (sous toutes ses formes),
|
||||
les ressources système, la communication inter-processus, ou l'enchaînement
|
||||
des évènements. Les processus Unix n'exécutent pas de manière synchrone
|
||||
aussi, logiquement, les opérations sont rarement atomiques.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Dépassement de capacité</title>
|
||||
|
||||
<para>Les dépassements de capacité ("Buffer Overflows") existent depuis
|
||||
les débuts de l'architecture de Von-Neuman <xref linkend="COD">.
|
||||
Ils gagnèrent une grande notoriété en 1988 avec le ver pour Internet
|
||||
de Morris. Malheureusement, la même attaque basique reste effective
|
||||
aujourd'hui. Des 17 rapports de sécurité du CERT de 1999, 10
|
||||
furent causés directement des bogues logiciels de dépassement de
|
||||
capacité. De loin la plus commune de types d'attaques par dépassement de
|
||||
capacité est basée sur la corruption de la pile.</para>
|
||||
|
||||
<para>La plupart des systèmes informatiques modernes utilise une pile
|
||||
pour passer les arguments aux procédures et stocker les variables locales
|
||||
Une pile est une zone mémoire dernier entré-premier sorti (Last In-First
|
||||
Out : LIFO) dans la zone de mémoire haute de l'image d'un processus.
|
||||
Quand un programme invoque une fonction une nouvelle structure pile est
|
||||
créée. Cette structure pile consiste dans les arguments passés à la
|
||||
fonction aussi bien que dans une quantité dynamique d'espace pour
|
||||
la variable locale. Le pointeur de pile est un registre qui référence la
|
||||
position courante du sommet de la pile. Etant donné que cette valeur
|
||||
change constamment au fur et à mesure que de nouvelles valeurs sont
|
||||
ajoutées au sommet de la pile, beaucoup d'implémentations fournissent
|
||||
aussi un pointeur de structure qui est positionné dans le voisinage du
|
||||
début de la structure pile de façon à ce que les variables locales soient
|
||||
plus facilement adressables relativement à cette valeur.
|
||||
<xref linkend="COD"> L'adresse de retour des appels de fonction est aussi
|
||||
stocké dans la pile, et cela est la cause des découvertes des
|
||||
dépassements de pile puisque faire déborder une variable locale dans une
|
||||
fonction peut écraser l'adresse de retour de cette fonction, permettant
|
||||
potentiellement à un utilisateur malveillant d'exécuter le code qu'il ou
|
||||
elle désire.</para>
|
||||
|
||||
<para>Bien que les attaques basées sur les dépassements de pile soient
|
||||
de loin les plus communes, il serait aussi possible de faire exploser
|
||||
la pile avec une attaque du tas (malloc/free).</para>
|
||||
|
||||
<para>Le langage de programmation C ne réalise pas de vérifications
|
||||
automatiques des limites sur les tableaux ou pointeurs comme d'autres
|
||||
langages le font. De plus, la librairie standard du C est remplie d'une
|
||||
poignée de fonctions très dangereuses.</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols=2>
|
||||
<tbody>
|
||||
<row><entry><function>strcpy</function>(char *dest, const char
|
||||
*src)</entry>
|
||||
<entry><simpara>Peut faire déborder le tampon dest</simpara></entry>
|
||||
</row>
|
||||
|
||||
<row><entry><function>strcat</function>(char *dest, const char
|
||||
*src)</entry>
|
||||
<entry><simpara>Peut faire déborder le tampon dest</simpara></entry>
|
||||
</row>
|
||||
|
||||
<row><entry><function>getwd</function>(char *buf)</entry>
|
||||
<entry><simpara>Peut faire déborder le tampon buf</simpara></entry>
|
||||
</row>
|
||||
|
||||
<row><entry><function>gets</function>(char *s)</entry>
|
||||
<entry><simpara>Peut faire déborder le tampon s</simpara></entry>
|
||||
</row>
|
||||
|
||||
<row><entry><function>[vf]scanf</function>(const char *format,
|
||||
...)</entry>
|
||||
<entry><simpara>Peut faire déborder ses arguments.</simpara></entry>
|
||||
</row>
|
||||
|
||||
<row><entry><function>realpath</function>(char *path, char
|
||||
resolved_path[])</entry>
|
||||
<entry><simpara>Peut faire déborder le tampon path</simpara></entry>
|
||||
</row>
|
||||
|
||||
<row><entry><function>[v]sprintf</function>(char *str, const char
|
||||
*format, ...)</entry>
|
||||
<entry><simpara>Peut faire déborder le tampon str.</simpara></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
|
||||
<sect2><title>Exemple de dépassement de capacité</title>
|
||||
|
||||
<para>L'exemple de code suivant contient un dépassement de capacité
|
||||
conçu pour écraser l'adresse de retour et "sauter" l'instruction suivant
|
||||
immédiatement l'appel de la fonction. (Inspiré
|
||||
par <xref linkend="Phrack">)</para>
|
||||
|
||||
<programlisting>#include <sgmltag>stdio.h</sgmltag>
|
||||
|
||||
void manipulate(char *buffer) {
|
||||
char newbuffer[80];
|
||||
strcpy(newbuffer,buffer);
|
||||
}
|
||||
|
||||
int main() {
|
||||
char ch,buffer[4096];
|
||||
int i=0;
|
||||
|
||||
while ((buffer[i++] = getchar()) != '\n') {};
|
||||
|
||||
i=1;
|
||||
manipulate(buffer);
|
||||
i=2;
|
||||
printf("La valeur de i est : %d\n",i);
|
||||
return 0;
|
||||
}</programlisting>
|
||||
|
||||
<para>Examinons quel serait l'aspect de l'image mémoire de ce processus
|
||||
si nous avions entré 160 espaces dans notre petit programme avant
|
||||
d'appuyer sur <keycap>Entrée</keycap>.</para>
|
||||
|
||||
<para>[XXX Schéma ici!]</para>
|
||||
|
||||
<para>Evidemment une entrée plus malveillante pourrait être imaginée pour
|
||||
exécuter des instructions déjà compilées (comme exec(/bin/sh)).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2><title>Eviter les dépassements de capacité</title>
|
||||
|
||||
<para>La solution la plus simple au problème de débordement de pile
|
||||
est de toujours utiliser de la mémoire restreinte en taille et
|
||||
les fonctions de copie de chaîne de caractères. <function>strncpy</function>
|
||||
et <function>strncat</function> font parties de la libraire standard du
|
||||
C. Ces fonctions acceptent une valeur de longueur comme paramètre qui
|
||||
qui ne devrait pas être plus grande que la taille du tampon de
|
||||
destination. Ces fonctions vont ensuite copier `taille' octets de la
|
||||
source vers la destination. Toutefois, il y a un certain nombre de
|
||||
problèmes avec ces fonctions. Aucune fonction ne garantit une terminaison
|
||||
par le caractère NULL si la taille du tampon d'entrée est aussi grand
|
||||
que celui de destination. Le paramètre taille est aussi utilisé de façon
|
||||
illogique entre <function>strncpy</function> et <function>strncat</function>
|
||||
aussi il est facile pour les programmeurs d'être déroutés sur leur
|
||||
utilisation convenable. Il y a aussi une perte significative des
|
||||
performances comparé à <function>strcpy</function> lorsque l'on copie
|
||||
une courte chaîne dans un grand tampon puisque <function>strncpy</function>
|
||||
remplit de caractères NULL jusqu'à la taille spécifiée.</para>
|
||||
|
||||
<para>Dans OpenBSD, une autre implémentation de la copie de mémoire
|
||||
a été créée pour contourner ces problèmes. Les fonctions <function>strlcpy</function>
|
||||
et <function>strlcat</function> garantissent qu'elles termineront
|
||||
toujours le tampon de destination par un caractère NULL losque l'argument
|
||||
de taille est différent de zéro. Pour plus d'informations sur ces
|
||||
fonctions, voir <xref linkend="OpenBSD">. Les fonctions <function>strlcpy</function> et
|
||||
<function>strlcat</function> d'OpenBSD ont été inclues dans FreeBSD
|
||||
depuis la version 3.5.</para>
|
||||
|
||||
<sect3><title>V#233;rifications des limites en fonctionnement basées sur le compilateur</title>
|
||||
<!--Compiler based run-time bounds -->
|
||||
|
||||
<para>Malheureusement il y a toujours un très important assortiment de
|
||||
code en utilisation publique qui copie aveuglément la mémoire sans
|
||||
utiliser une des routines de copie limitée dont nous venons juste de
|
||||
discuter. Heureusement, il y a une autre solution. Plusieurs produits
|
||||
complémentaires pour compilateur et librairies existent pour faire
|
||||
de la vérification de limites pendant le fonctionnement en C/C++.</para>
|
||||
|
||||
<para>StackGuard est un de ces produits qui est implémenté comme un
|
||||
petit correctif ("patch") pour le générateur de code gcc. Extrait du
|
||||
site Internet de StackGuard, http://immunix.org/stackguard.html :
|
||||
<blockquote><para>"StackGuard détecte et fait échouer les attaques
|
||||
par débordement de pile en empêchant l'adresse de retour sur la pile
|
||||
d'être altérée. StackGuard place un mot "canari"
|
||||
<footnote><para>NDT : Jaune de préférence pour être bien visible</para></footnote>
|
||||
à côté de l'adresse de retour quand la fontion est appelée. Si le mot
|
||||
"canari" a été altéré au retour de la fonction, alors une attaque par
|
||||
débordement de pile a été tentée et le programme répond en envoyant
|
||||
une alerte d'intrusion dans la trace système (syslog) et
|
||||
s'arrête alors."</para></blockquote>
|
||||
|
||||
<blockquote><para>"StackGuard est implémenté comme un petit correctif
|
||||
au générateur de code gcc, spécifiquement sur les routines
|
||||
function_prolog() et function_epilog(). function_prolog() a été
|
||||
amélioré pour laisser des "canaris" sur la pile quand les fonctions
|
||||
démarrent, et function_epilog vérifie l'intégrité des "canaris" quand
|
||||
la fonction se termine. Tout essai pour corrompre l'adresse de retour
|
||||
est alors détectée avant que la fonction ne retourne."</para></blockquote>
|
||||
</para>
|
||||
|
||||
<para>Recompiler votre application avec StackGuard est un
|
||||
moyen efficace pour stopper la plupart des attques par dépassement de
|
||||
capacité, mais cela peut toujours être compromis.</para>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3><title>Vérifications des limites en fonctionnement basées sur les librairies</title>
|
||||
|
||||
<para>Les mécanismes basés sur le compilateur sont totalement inutiles
|
||||
pour logiciel seulement binaire que vous ne pouvez recompiler. Pour
|
||||
ces situations, il existe un nombre de librairies qui re-implémente
|
||||
les fonctions peu sûres de la librairie C
|
||||
(<function>strcpy</function>, <function>fscanf</function>,
|
||||
<function>getwd</function>, etc..) et assurent que ces
|
||||
fonctions ne peuvent pas écrire plus loin que le pointeur de pile.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><simpara>libsafe</simpara></listitem>
|
||||
<listitem><simpara>libverify</simpara></listitem>
|
||||
<listitem><simpara>libparnoia</simpara></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Malheureusement ces défenses basées sur les librairies possèdent
|
||||
un certain nombre de défauts. Ces librairies protègent seulement d'un
|
||||
très petit ensemble de problèmes liés à la sécurité et oublient de
|
||||
réparer le problème actuel. Ces défenses peuvent échouer si
|
||||
l'application a été compilée avec -fomit-frame-pointer. De même, les
|
||||
variables d'environnement LD_PRELOAD et LD_LIBRARY_PATH peuvent être
|
||||
réécrites/non définies par l'utilisateur.</para>
|
||||
</sect3>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Les problèmes liés à SetUID</title>
|
||||
|
||||
<para>Il y a au moins 6 differents ID (identifiants) associés à un
|
||||
processus donné. A cause de cela, vous devez être très attentif avec
|
||||
l'accès que votre processus possède à un instant donné. En particulier,
|
||||
toutes les applications ayant reçu des privilèges par seteuid doivent
|
||||
les abandonnés dès qu'ils ne sont plus nécessaires.</para>
|
||||
|
||||
<para>L'identifiant de l'utilisateur réel (real user ID) peut seulement
|
||||
être changé par un processus super-utilisateur. Le programme <application>login</application>
|
||||
met celui à jour quand un utilisateur se connecte et il est rarement
|
||||
changé.</para>
|
||||
|
||||
<para>L'identifiant de l'utilisateur effectif (effective user ID) est mis
|
||||
à jour par les fonctions <function>exec()</function> si un programme
|
||||
possède son bit seteuid placé. Une application peut appeler
|
||||
<function>seteuid()</function> à n'importe quel moment pour règler
|
||||
l'identifiant de l'utilisateur effectif sur l'identifiant d'un
|
||||
utilisateur réel ou sur le "set-user-ID" sauvé.
|
||||
Quand l'identifiant de l'utilisateur effectif est placé par les
|
||||
fonctions <function>exec()</function>, la valeur précédente est sauvée
|
||||
dans le "set-user-ID" sauvé.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="chroot"><title>Limiter l'environnement de votre programme</title>
|
||||
|
||||
<para>La méthode traditionnelle pour restreindre l'accès d'un processus
|
||||
se fait avec l'appel système <function>chroot()</function>. Cet appel
|
||||
système change le répertoire racine depuis lequel tous les autres chemins
|
||||
sont référencés pour un processus et ses fils. Pour que cet appel
|
||||
réussisse, le processus doit avoir exécuté (recherché)
|
||||
la permission dans le répertoire référencé. Le nouvel environnement
|
||||
environment ne prend pas effet que lorsque vous appelez <function>chdir()</function>
|
||||
dans celui-ci.
|
||||
Il doit être aussi noté qu'un processus peut facilement s'échapper
|
||||
d'un environnement chroot s'il a les privilèges du super-utilisateur.
|
||||
Cela devrait être accompli en créant des fichiers spéciaux de
|
||||
périphérique pour la mémoire du noyau, en attachant un dévermineur à un
|
||||
processus depuis l'extérieur de sa "prison", ou par d'autres manières
|
||||
créatrices.</para>
|
||||
|
||||
<para>Le comportement de l'appel système <function>chroot()</function>
|
||||
peut être un peu contrôlé avec la commande <command>sysctl</command> et
|
||||
la variable kern.chroot_allow_open_directories.
|
||||
Quand cette valeur est règlée à 0, <function>chroot()</function> échouera
|
||||
avec EPERM s'il y a un répertoire d'ouvert. Si la variable est règlée sur
|
||||
la valeur par défaut 1, alors <function>chroot()</function> échouera
|
||||
avec EPERM s'il y a un répertoire d'ouvert et que le processus est déjà
|
||||
sujet à un appel <function>chroot()</function>. Pour toute autre valeur, la
|
||||
vérification des répertoires ouverts sera totalement court-circuitée.</para>
|
||||
|
||||
<sect2><title>La fonctionnalité "prison" de FreeBSD</title>
|
||||
|
||||
<para>Le concept de Prison ("Jail") étend
|
||||
<function>chroot()</function> en limitant les droits du
|
||||
super-utilisateur pour créer un véritable `serveur virtuel'. Une fois
|
||||
qu'une prison est mise en place, toute communication réseau doit avoir lieu
|
||||
au travers de l'adresse IP spécifiée, et le droit du
|
||||
"privilège super-utilisateur" dans cette prison est sévèrement gêné.</para>
|
||||
|
||||
<para>Tant qu'il se trouve en prison, tout test avec les droits du
|
||||
super-utilisateur dans le noyau au travers d'un appel à
|
||||
<function>suser()</function> échouera.
|
||||
Toutefois, quelques appels à <function>suser()</function> ont été
|
||||
changés par la nouvelle interface <function>suser_xxx()</function>.
|
||||
Cette fonction est responsable de fournir ou de retirer les accès
|
||||
aux droits du super-utilisateur pour les processus emprisonnés.</para>
|
||||
|
||||
<para>Un processus super-utilisateur dans un environnement emprisonné
|
||||
a le pouvoir de : </para>
|
||||
<itemizedlist>
|
||||
<listitem><simpara>Manipuler les identitifications avec
|
||||
<function>setuid</function>, <function>seteuid</function>,
|
||||
<function>setgid</function>, <function>setegid</function>,
|
||||
<function>setgroups</function>, <function>setreuid</function>,
|
||||
<function>setregid</function>, <function>setlogin</function></simpara></listitem>
|
||||
<listitem><simpara>Règler les limites en ressources avec <function>setrlimit</function></simpara></listitem>
|
||||
<listitem><simpara>Modifier quelques variables du noyau par sysctl
|
||||
(kern.hostname)</simpara></listitem>
|
||||
<listitem><simpara><function>chroot()</function></simpara></listitem>
|
||||
<listitem><simpara>Règler les paramètres d'un noeud virtuel (vnode):
|
||||
<function>chflags</function>,
|
||||
<function>fchflags</function></simpara></listitem>
|
||||
<listitem><simpara>Règler les attributs d'un noeud virtuel comme
|
||||
les permissions d'un fichier, le propriétaire, le groupe, la taille,
|
||||
la date d'accès, et la date de modification.</simpara></listitem>
|
||||
<listitem><simpara>Se lier à des ports privilégiés sur Internet
|
||||
(ports < 1024)</simpara></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para><function>Jail</function> est un outil très utile pour exécuter
|
||||
des applications dans un environnement sécurisé mais il a des
|
||||
imperfections. Actuellement, les mécanismes IPC (Inter-Process
|
||||
Communications) n'ont pas été convertis pour utiliser <function>suser_xxx</function>
|
||||
aussi des applications comme MySQL ne peuvent être exécutée dans une prison.
|
||||
L'accès super-utilisateur peut avoir un sens très limité dans une prison,
|
||||
mais il n'y aucune façon de spécifier exactement ce que très limité
|
||||
veut dire.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2><title>Les capacitès des processus POSIX.1e</title>
|
||||
|
||||
<para>Posix a réalisé un document de travail qui ajoute l'audit
|
||||
d'évènement, les listes de contrôle d'accès, les privilèges fins,
|
||||
l'étiquetage d'information, et le contrôle d'accès mandaté.</para>
|
||||
<para>Il s'agit d'un travail en cours et c'est l'objectif du projet <ulink
|
||||
url="http://www.trustedbsd.org">TrustedBSD</ulink>. Une partie
|
||||
du travail initial a été intégré dans FreeBSD-current
|
||||
(cap_set_proc(3)).</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1><title>La confiance</title>
|
||||
|
||||
<para>Une application ne devrait jamais supposer que tout est sain
|
||||
dans l'environnement des utilisateurs. Cela inclut (mais n'est
|
||||
certainement pas limité à) : la saisie de l'utilisateur, les signaux,
|
||||
les variables d'environnement, les ressources, les communication
|
||||
inter-processus, les mmaps, le répertoire de travail du système de
|
||||
fichiers, les descripteurs de fichier, le nombre de fichiers ouverts,
|
||||
etc.</para>
|
||||
|
||||
<para>Vous ne devriez jamais supposer que vous pouvez gérer toutes les
|
||||
formes de saisie invalide qu'un utilisateur peut entrer. Votre
|
||||
application devrait plutôt utiliser un filtrage positif pour
|
||||
seulement permettre un sous-ensemble spécifique que vous jugez
|
||||
sain. Une mauvaise validation des entrées a été la cause de beaucoup
|
||||
découvertes de bogues, spécialement avec les scripts CGI sur le web.
|
||||
Pour les noms de fichier, vous devez être tout particulièrement attentif
|
||||
aux chemins ("../", "/"), liens symboliques et caractères d'échappement
|
||||
de l'interpréteur de commandes.</para>
|
||||
|
||||
<para>Perl possède une caractéristique tès sympathique appelée mode
|
||||
"Taint" qui peut être utilisée pour empêcher les scripts d'utiliser
|
||||
des données externes au programme par un moyen non sûr. Ce mode vérifiera
|
||||
les arguments de la ligne de commandes, les variables d'environnement,
|
||||
les informations localisées (propres aux pays), les résultats de certains
|
||||
appels système (<function>readdir()</function>,
|
||||
<function>readlink()</function>,
|
||||
<function>getpwxxx()</function>) et toute entrée de fichier.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Les conditions de course</title>
|
||||
|
||||
<para>Une condition de course est un comportement anormal causé par
|
||||
une dépendance inattendue sur le séquencement relatif des évènements. En
|
||||
d'autres mots, un programmeur a supposé à tort qu'un évènement
|
||||
particulier se passerait avant un autre.</para>
|
||||
|
||||
<para>Quelques causes habituelles de conditions de course sont les
|
||||
signaux, les vérifications d'accès et les fichiers ouverts.
|
||||
Les signaux sont des évènements asynchrones par nature aussi un soin
|
||||
particulier doit être pris pour les utiliser.
|
||||
Vérifier les accès avec <function>access(2)</function> puis
|
||||
<function>open(2)</function> n'est clairement pas atomique.
|
||||
Les utilisateurs peuvent déplacer des fichiers entre les deux appels.
|
||||
Les applications privilégiées devraient plutôt faire un appel à
|
||||
<function>seteuid()</function> puis appeler <function>open()</function>
|
||||
directement. Dans le même esprit, une application devrait toujours règler
|
||||
un umask correct avant un appel à <function>open()</function> pour
|
||||
prévenir le besoin d'appels non valides à <function>chmod()</function>.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
2312
fr_FR.ISO8859-1/books/developers-handbook/tools/chapter.sgml
Normal file
2312
fr_FR.ISO8859-1/books/developers-handbook/tools/chapter.sgml
Normal file
File diff suppressed because it is too large
Load diff
21
fr_FR.ISO8859-1/books/developers-handbook/usb/chapter.sgml
Normal file
21
fr_FR.ISO8859-1/books/developers-handbook/usb/chapter.sgml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
The FreeBSD Documentation Project
|
||||
The FreeBSD French Documentation Project
|
||||
|
||||
$Id: chapter.sgml,v 1.1 2002-02-14 14:25:03 gioria Exp $
|
||||
Original revision: 1.1
|
||||
$FreeBSD$
|
||||
-->
|
||||
|
||||
<chapter id="usb">
|
||||
<title>Périphériques USB ***</title>
|
||||
|
||||
<para><emphasis>Ce chapître a été écrit par &a.nhibma;. Les modifications pour le
|
||||
manuel par &a.murray;.</emphasis></para>
|
||||
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>Chapître à traduire.</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
Loading…
Reference in a new issue