aboutsummaryrefslogtreecommitdiff
path: root/ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml')
-rw-r--r--ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml410
1 files changed, 0 insertions, 410 deletions
diff --git a/ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml b/ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml
deleted file mode 100644
index 39bb5ae739..0000000000
--- a/ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml
+++ /dev/null
@@ -1,410 +0,0 @@
-<?xml version="1.0" encoding="koi8-r" standalone="no"?>
-<!--
- The FreeBSD Russian Documentation Project
-
- $FreeBSD$
- $FreeBSDru: frdp/doc/ru_RU.KOI8-R/books/developers-handbook/driverbasics/chapter.sgml,v 1.1 2001/01/10 08:45:03 andy Exp $
-
- Original revision: 1.3
--->
-
-<chapter id="driverbasics">
- <title>Написание драйверов устройств для FreeBSD</title>
-
- <para>Эту главу написал Мюррэй Стокели (Murray Stokely) на основе множества
- источников, включая справочную страницу intro(4), созданную Джоргом
- Вуншем (Joerg Wunsch).</para>
-
- <sect1>
- <title>Введение</title>
-
- <para>Эта глава является кратким введением в процесс написания драйверов
- устройств для FreeBSD. В этом контексте термин устройство используется
- в основном для вещей, связанных с оборудованием, относящимся к системе,
- таких, как диски, печатающие устройства или графические дисплеи с
- клавиатурами. Драйвер устройства является программной компонентой
- операционной системы, управляющей некоторым устройством. Имеются также
- так называемые псевдо-устройства, в случае которых драйвер устройства
- эмулирует поведение устройства программно, без наличия какой-либо
- соответствующей аппаратуры. Драйверы устройств могут быть
- вкомпилированы в систему статически или могут загружаться по требованию
- при помощи механизма динамического компоновщика ядра `kld'.</para>
-
- <para>Большинство устройств в Unix-подобной операционной системе доступны
- через файлы устройств (device-nodes), иногда также называемые
- специальными файлами. В иерархии файловой системы эти файлы обычно
- находятся в каталоге <filename>/dev</filename>. Пока система devfs
- полностью не интегрирована во FreeBSD, каждый файл устройства должен
- создаваться статически и вне зависимости от наличия соответствующего
- драйвера устройста. Большинство файлов устройств в системе создаются
- при помощи команды <command>MAKEDEV</command>.</para>
-
- <para>Драйверы устройств могут быть условно разделены на две категории;
- драйверы символьных и сетевых устройств.</para>
- </sect1>
-
- <sect1>
- <title>Механизм динамического компоновщика ядра - KLD</title>
-
- <para>Интерфейс kld позволяет системным администраторам динамически
- добавлять и убирать функциональность из работающей системы. Это
- позволяет разработчикам драйверов устройств загружать собственные
- изменения в работающее ядро без постоянных перезагрузок для
- тестирования изменений.</para>
-
- <para>Для работы с интерфейсом kld используются следующие команды
- администратора:
-
- <itemizedlist>
- <listitem>
- <simpara>
- <command>kldload</command> - загружает новый модуль ядра
- </simpara>
- </listitem>
-
- <listitem>
- <simpara>
- <command>kldunload</command> - выгружает модуль ядра
- </simpara>
- </listitem>
-
- <listitem>
- <simpara>
- <command>kldstat</command> - выводит список загруженных в данный
- момент модулей
- </simpara>
- </listitem>
- </itemizedlist>
- </para>
-
- <para>Скелет модуля ядра</para>
-
- <programlisting>
-/*
- * KLD Skeleton
- * Inspired by Andrew Reiter's Daemonnews article
- */
-
-#include &lt;sys/types.h&gt;
-#include &lt;sys/module.h&gt;
-#include &lt;sys/systm.h&gt; /* uprintf */
-#include &lt;sys/errno.h&gt;
-#include &lt;sys/param.h&gt; /* defines used in kernel.h */
-#include &lt;sys/kernel.h&gt; /* types used in module initialization */
-
-/*
- * Load handler that deals with the loading and unloading of a KLD.
- */
-
-static int
-skel_loader(struct module *m, int what, void *arg)
-{
- int err = 0;
-
- switch (what) {
- case MOD_LOAD: /* kldload */
- uprintf("Skeleton KLD loaded.\n");
- break;
- case MOD_UNLOAD:
- uprintf("Skeleton KLD unloaded.\n");
- break;
- default:
- err = EINVAL;
- break;
- }
- return(err);
-}
-
-/* Declare this module to the rest of the kernel */
-
-DECLARE_MODULE(skeleton, skel_loader, SI_SUB_KLD, SI_ORDER_ANY);
- </programlisting>
-
- <sect2>
- <title>Makefile</title>
-
- <para>Во FreeBSD имеются заготовки для включения в make-файлы, которые
- вы можете использовать для быстрой компиляции собственных дополнений
- к ядру.</para>
-
- <programlisting>
-SRCS=skeleton.c
-KMOD=skeleton
-
-.include &lt;bsd.kmod.mk&gt;
- </programlisting>
-
- <para>Простой запуск команды <command>make</command> с этим make-файлом
- приведет к созданию файла <filename>skeleton.ko</filename>, который
- можно загрузить в вашу систему, набрав:
-
- <screen>
-&prompt.root kldload -v ./skeleton.ko
- </screen>
- </para>
- </sect2>
- </sect1>
-
- <sect1>
- <title>Обращение к драйверу устройства</title>
-
- <para>Unix дает некоторый общий набор системных вызовов для использования
- в пользовательских приложениях. Когда пользователь обращается к
- файлу устройства, высокие уровни ядра перенаправляют эти обращения к
- соответствующему драйверу устройства. Скрипт
- <command>/dev/MAKEDEV</command> создает большинство файлов устройств в
- вашей системе, однако если вы ведете разработку своего собственного
- драйвера, то может появиться необходимость в создании собственных
- файлов устройств при помощи команды <command>mknod</command>.</para>
-
- <sect2>
- <title>Создание статических файлов устройств</title>
-
- <para>Для создания файла устройства команде <command>mknod</command>
- требуется указать четыре аргумента. Вы должны указать имя этого
- файла устройства, тип устройства, старшее число устройства и младшее
- число устройства.</para>
- </sect2>
-
- <sect2>
- <title>Динамические файлы устройств</title>
-
- <para>Файловая система устройств, devfs, предоставляет доступ к
- пространству имен устройств ядра из глобального пространства имен
- файловой системы. Это устраняет потенциальную проблемы наличия
- драйвера без статического файла устройства или файла устройства без
- установленного драйвера устройства. Devfs все еще находится в
- разработке, однако она уже достаточно хорошо работает.</para>
- </sect2>
- </sect1>
-
- <sect1>
- <title>Символьные устройства</title>
-
- <para>Драйвер символьного устройства передает данные непосредственно в
- или из процесса пользователя. Это самый распространенный тип драйвера
- устройства и в дереве исходных текстов имеется достаточно простых
- примеров таких драйверов.</para>
-
- <para>В этом простом примере псевдо-устройство запоминает какие угодно
- значения, которые вы в него записываете, и затем может выдавать их
- назад при чтении из этого устройства.</para>
-
- <programlisting>
-/*
- * Simple `echo' pseudo-device KLD
- *
- * Murray Stokely
- */
-
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-
-#include &lt;sys/types.h&gt;
-#include &lt;sys/module.h&gt;
-#include &lt;sys/systm.h&gt; /* uprintf */
-#include &lt;sys/errno.h&gt;
-#include &lt;sys/param.h&gt; /* defines used in kernel.h */
-#include &lt;sys/kernel.h&gt; /* types used in module initialization */
-#include &lt;sys/conf.h&gt; /* cdevsw struct */
-#include &lt;sys/uio.h&gt; /* uio struct */
-#include &lt;sys/malloc.h&gt;
-
-#define BUFFERSIZE 256
-
-/* Function prototypes */
-d_open_t echo_open;
-d_close_t echo_close;
-d_read_t echo_read;
-d_write_t echo_write;
-
-/* Character device entry points */
-static struct cdevsw echo_cdevsw = {
- echo_open,
- echo_close,
- echo_read,
- echo_write,
- noioctl,
- nopoll,
- nommap,
- nostrategy,
- "echo",
- 33, /* reserved for lkms - /usr/src/sys/conf/majors */
- nodump,
- nopsize,
- D_TTY,
- -1
-};
-
-typedef struct s_echo {
- char msg[BUFFERSIZE];
- int len;
-} t_echo;
-
-/* vars */
-static dev_t sdev;
-static int len;
-static int count;
-static t_echo *echomsg;
-
-MALLOC_DECLARE(M_ECHOBUF);
-MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module");
-
-/*
- * This function acts is called by the kld[un]load(2) system calls to
- * determine what actions to take when a module is loaded or unloaded.
- */
-
-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");
- /* kmalloc memory for use by this driver */
- /* malloc(256,M_ECHOBUF,M_WAITOK); */
- MALLOC(echomsg, t_echo *, sizeof(t_echo), M_ECHOBUF, M_WAITOK);
- printf("Echo device loaded.\n");
- break;
- case MOD_UNLOAD:
- destroy_dev(sdev);
- FREE(echomsg,M_ECHOBUF);
- printf("Echo device unloaded.\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("Opened device \"echo\" successfully.\n");
- return(err);
-}
-
-int
-echo_close(dev_t dev, int fflag, int devtype, struct proc *p)
-{
- uprintf("Closing device \"echo.\"\n");
- return(0);
-}
-
-/*
- * The read function just takes the buf that was saved via
- * echo_write() and returns it to userland for accessing.
- * uio(9)
- */
-
-int
-echo_read(dev_t dev, struct uio *uio, int ioflag)
-{
- int err = 0;
- int amt;
-
- /* How big is this read operation? Either as big as the user wants,
- or as big as the remaining data */
- 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 failed!\n");
- }
-
- return err;
-}
-
-/*
- * echo_write takes in a character string and saves it
- * to buf for later accessing.
- */
-
-int
-echo_write(dev_t dev, struct uio *uio, int ioflag)
-{
- int err = 0;
-
- /* Copy the string in from user memory to kernel memory */
- err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_len,BUFFERSIZE));
-
- /* Now we need to null terminate */
- *(echomsg->msg + MIN(uio->uio_iov->iov_len,BUFFERSIZE)) = 0;
- /* Record the length */
- echomsg->len = MIN(uio->uio_iov->iov_len,BUFFERSIZE);
-
- if (err != 0) {
- uprintf("Write failed: bad address!\n");
- }
-
- count++;
- return(err);
-}
-
-DEV_MODULE(echo,echo_loader,NULL);
- </programlisting>
-
- <para>Перед тем, как устанавливать этот драйвер, в вашей файловой системе
- вам нужно создать файл устройства при помощи команды, подобной
- следующей:</para>
-
- <screen>
-&prompt.root mknod /dev/echo c 33 0
- </screen>
-
- <para>Когда этот драйвер загружен, вы можете выполнять следующие
- действия:</para>
-
- <screen>
-&prompt.root echo -n "Test Data" > /dev/echo
-&prompt.root cat /dev/echo
-Test Data
- </screen>
-
- <para>Об устройствах, обслуживающих реальное оборудование, рассказывается
- в следующей главе..</para>
-
- <para>Дополнительные источники информации
- <itemizedlist>
- <listitem>
- <simpara><ulink
- url="http://www.daemonnews.org/200010/blueprints.html">Учебник
- по программированию механизма динамического компоновщика ядра
- (KLD)</ulink> - <ulink
- url="http://www.daemonnews.org">Daemonnews</ulink>
- Октябрь 2000
- </simpara>
- </listitem>
-
- <listitem>
- <simpara><ulink
- url="http://www.daemonnews.org/200007/newbus-intro.html">Как
- писать драйверы ядра в парадигме NEWBUS</ulink> - <ulink
- url="http://www.daemonnews.org">Daemonnews</ulink> Июль 2000
- </simpara>
- </listitem>
- </itemizedlist>
- </para>
- </sect1>
-
- <sect1>
- <title>Сетевые драйверы</title>
-
- <para>В случае драйверов сетевых устройств файлы устройств для доступа к
- ним не используются. Их выбор основан на другом механизме, работающем
- в ядре, и не использующем вызов open(); об использование сетевых
- устройств в общем случае рассказано в описании системного вызова
- socket(2).</para>
-
- <para>Почитайте справочную информацию о вызове ifnet(), устройстве
- loopback, почитайте драйверы Билла Пола (Bill Paul), и так
- далее..</para>
- </sect1>
-</chapter>