diff options
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.sgml | 410 |
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 <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 */ - -/* - * 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 <bsd.kmod.mk> - </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 <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> - -#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> |