Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-doc
Path: blob/main/documentation/content/ru/books/arch-handbook/driverbasics/_index.po
18098 views
# SOME DESCRIPTIVE TITLE
# Copyright (C) YEAR The FreeBSD Project
# This file is distributed under the same license as the FreeBSD Documentation package.
# Vladlen Popolitov <[email protected]>, 2025, 2026.
msgid ""
msgstr ""
"Project-Id-Version: FreeBSD Documentation VERSION\n"
"POT-Creation-Date: 2025-05-01 19:56-0300\n"
"PO-Revision-Date: 2026-03-08 09:11+0000\n"
"Last-Translator: Vladlen Popolitov <[email protected]>\n"
"Language-Team: Russian <https://translate-dev.freebsd.org/projects/"
"documentation/booksarch-handbookdriverbasics_index/ru/>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 4.17\n"

#. type: Title =
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:1
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:14
#, no-wrap
msgid "Writing FreeBSD Device Drivers"
msgstr "Написание драйверов устройств для FreeBSD"

#. type: YAML Front Matter: title
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:1
#, no-wrap
msgid "Chapter 9. Writing FreeBSD Device Drivers"
msgstr "Глава 9. Написание драйверов устройств для FreeBSD"

#. type: Title ==
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:52
#, no-wrap
msgid "Introduction"
msgstr "Введение"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:55
msgid ""
"This chapter provides a brief introduction to writing device drivers for "
"FreeBSD. A device in this context is a term used mostly for hardware-related "
"stuff that belongs to the system, like disks, printers, or a graphics "
"display with its keyboard. A device driver is the software component of the "
"operating system that controls a specific device. There are also so-called "
"pseudo-devices where a device driver emulates the behavior of a device in "
"software without any particular underlying hardware. Device drivers can be "
"compiled into the system statically or loaded on demand through the dynamic "
"kernel linker facility `kld'."
msgstr ""
"В этой главе представлено краткое введение в написание драйверов устройств "
"для FreeBSD. Устройство в данном контексте — это термин, используемый в "
"основном для аппаратных компонентов системы, таких как диски, принтеры или "
"графический дисплей с клавиатурой. Драйвер устройства — это программный "
"компонент операционной системы, который управляет конкретным устройством. "
"Также существуют так называемые псевдоустройства, где драйвер эмулирует "
"поведение устройства программно, без использования какого-либо конкретного "
"аппаратного обеспечения. Драйверы устройств могут быть статически "
"скомпилированы в систему или загружены по требованию через механизм "
"динамической загрузки модулей ядра `kld`."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:57
msgid ""
"Most devices in a UNIX(R)-like operating system are accessed through device-"
"nodes, sometimes also called special files. These files are usually located "
"under the directory [.filename]#/dev# in the filesystem hierarchy."
msgstr ""
"Большинство устройств в операционной системе, подобной UNIX(R), доступны "
"через специальные файлы устройств, также называемые узлами устройств. Эти "
"файлы обычно расположены в каталоге [.filename]#/dev# в иерархии файловой "
"системы."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:59
msgid ""
"Device drivers can roughly be broken down into two categories; character and "
"network device drivers."
msgstr ""
"Драйверы устройств можно условно разделить на две категории: символьные "
"драйверы и драйверы сетевых устройств."

#. type: Title ==
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:61
#, no-wrap
msgid "Dynamic Kernel Linker Facility - KLD"
msgstr "Динамический загрузчик модулей ядра - KLD"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:64
msgid ""
"The kld interface allows system administrators to dynamically add and remove "
"functionality from a running system. This allows device driver writers to "
"load their new changes into a running kernel without constantly rebooting to "
"test changes."
msgstr ""
"Интерфейс kld позволяет системным администраторам динамически добавлять и "
"удалять функциональность в работающей системе. Это позволяет разработчикам "
"драйверов устройств загружать свои новые изменения в работающее ядро без "
"постоянной перезагрузки для проверки изменений."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:66
msgid "The kld interface is used through:"
msgstr "Интерфейс kld используется с помощью следующих команд:"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:68
msgid "`kldload` - loads a new kernel module"
msgstr "`kldload` - загружает новый модуль ядра"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:69
msgid "`kldunload` - unloads a kernel module"
msgstr "`kldunload` — выгружает модуль ядра"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:70
msgid "`kldstat` - lists loaded modules"
msgstr "`kldstat` — выводит список загруженных модулей"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:72
msgid "Skeleton Layout of a kernel module"
msgstr "Каркасная структура модуля ядра"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:79
#, no-wrap
msgid ""
"/*\n"
" * KLD Skeleton\n"
" * Inspired by Andrew Reiter's Daemonnews article\n"
" */\n"
msgstr ""
"/*\n"
" * KLD Skeleton\n"
" * Inspired by Andrew Reiter's Daemonnews article\n"
" */\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:86
#, no-wrap
msgid ""
"#include <sys/types.h>\n"
"#include <sys/systm.h>  /* uprintf */\n"
"#include <sys/errno.h>\n"
"#include <sys/param.h>  /* defines used in kernel.h */\n"
"#include <sys/module.h>\n"
"#include <sys/kernel.h> /* types used in module initialization */\n"
msgstr ""
"#include <sys/types.h>\n"
"#include <sys/systm.h>  /* uprintf */\n"
"#include <sys/errno.h>\n"
"#include <sys/param.h>  /* defines used in kernel.h */\n"
"#include <sys/module.h>\n"
"#include <sys/kernel.h> /* types used in module initialization */\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:90
#, no-wrap
msgid ""
"/*\n"
" * Load handler that deals with the loading and unloading of a KLD.\n"
" */\n"
msgstr ""
"/*\n"
" * Load handler that deals with the loading and unloading of a KLD.\n"
" */\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:95
#, no-wrap
msgid ""
"static int\n"
"skel_loader(struct module *m, int what, void *arg)\n"
"{\n"
"\tint err = 0;\n"
msgstr ""
"static int\n"
"skel_loader(struct module *m, int what, void *arg)\n"
"{\n"
"\tint err = 0;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:109
#, no-wrap
msgid ""
"\tswitch (what) {\n"
"\tcase MOD_LOAD:                /* kldload */\n"
"\t\tuprintf(\"Skeleton KLD loaded.\\n\");\n"
"\t\tbreak;\n"
"\tcase MOD_UNLOAD:\n"
"\t\tuprintf(\"Skeleton KLD unloaded.\\n\");\n"
"\t\tbreak;\n"
"\tdefault:\n"
"\t\terr = EOPNOTSUPP;\n"
"\t\tbreak;\n"
"\t}\n"
"\treturn(err);\n"
"}\n"
msgstr ""
"\tswitch (what) {\n"
"\tcase MOD_LOAD:                /* kldload */\n"
"\t\tuprintf(\"Skeleton KLD loaded.\\n"
"\");\n"
"\t\tbreak;\n"
"\tcase MOD_UNLOAD:\n"
"\t\tuprintf(\"Skeleton KLD unloaded.\\n"
"\");\n"
"\t\tbreak;\n"
"\tdefault:\n"
"\t\terr = EOPNOTSUPP;\n"
"\t\tbreak;\n"
"\t}\n"
"\treturn(err);\n"
"}\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:111
#, no-wrap
msgid "/* Declare this module to the rest of the kernel */\n"
msgstr "/* Declare this module to the rest of the kernel */\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:117
#, no-wrap
msgid ""
"static moduledata_t skel_mod = {\n"
"\t\"skel\",\n"
"\tskel_loader,\n"
"\tNULL\n"
"};\n"
msgstr ""
"static moduledata_t skel_mod = {\n"
"\t\"skel\",\n"
"\tskel_loader,\n"
"\tNULL\n"
"};\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:119
#, no-wrap
msgid "DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);\n"
msgstr "DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);\n"

#. type: Title ===
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:121
#, no-wrap
msgid "Makefile"
msgstr "Makefile"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:124
msgid ""
"FreeBSD provides a system makefile to simplify compiling a kernel module."
msgstr ""
"FreeBSD предоставляет системный makefile для упрощения компиляции модуля "
"ядра."

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:129
#, no-wrap
msgid ""
"SRCS=skeleton.c\n"
"KMOD=skeleton\n"
msgstr ""
"SRCS=skeleton.c\n"
"KMOD=skeleton\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:131
#, no-wrap
msgid ".include <bsd.kmod.mk>\n"
msgstr ".include <bsd.kmod.mk>\n"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:134
msgid ""
"Running `make` with this makefile will create a file "
"[.filename]#skeleton.ko# that can be loaded into the kernel by typing:"
msgstr ""
"Запуск `make` с этим makefile создаст файл [.filename]#skeleton.ko#, который "
"можно загрузить в ядро, набрав:"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:138
#, no-wrap
msgid "# kldload -v ./skeleton.ko\n"
msgstr "# kldload -v ./skeleton.ko\n"

#. type: Title ==
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:141
#, no-wrap
msgid "Character Devices"
msgstr "Символьные устройства"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:144
msgid ""
"A character device driver is one that transfers data directly to and from a "
"user process. This is the most common type of device driver and there are "
"plenty of simple examples in the source tree."
msgstr ""
"Драйвер символьного устройства — это драйвер, который передаёт данные "
"напрямую между устройством и пользовательским процессом. Это наиболее "
"распространённый тип драйвера устройств, и в дереве исходного кода есть "
"множество простых примеров."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:146
msgid ""
"This simple example pseudo-device remembers whatever values are written to "
"it and can then echo them back when read."
msgstr ""
"Этот простой пример псевдоустройства запоминает все значения, записанные в "
"него, и может затем воспроизводить их при чтении."

#. type: Block title
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:147
#, no-wrap
msgid "Example of a Sample Echo Pseudo-Device Driver for FreeBSD 10.X - 12.X"
msgstr "Пример образца драйвера псевдоустройства Echo для FreeBSD 10.X - 12.X"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:159
#, no-wrap
msgid ""
"/*\n"
" * Simple Echo pseudo-device KLD\n"
" *\n"
" * Murray Stokely\n"
" * Søren (Xride) Straarup\n"
" * Eitan Adler\n"
" */\n"
msgstr ""
"/*\n"
" * Simple Echo pseudo-device KLD\n"
" *\n"
" * Murray Stokely\n"
" * Søren (Xride) Straarup\n"
" * Eitan Adler\n"
" */\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:168
#, no-wrap
msgid ""
"#include <sys/types.h>\n"
"#include <sys/systm.h>  /* uprintf */\n"
"#include <sys/param.h>  /* defines used in kernel.h */\n"
"#include <sys/module.h>\n"
"#include <sys/kernel.h> /* types used in module initialization */\n"
"#include <sys/conf.h>   /* cdevsw struct */\n"
"#include <sys/uio.h>    /* uio struct */\n"
"#include <sys/malloc.h>\n"
msgstr ""
"#include <sys/types.h>\n"
"#include <sys/systm.h>  /* uprintf */\n"
"#include <sys/param.h>  /* defines used in kernel.h */\n"
"#include <sys/module.h>\n"
"#include <sys/kernel.h> /* types used in module initialization */\n"
"#include <sys/conf.h>   /* cdevsw struct */\n"
"#include <sys/uio.h>    /* uio struct */\n"
"#include <sys/malloc.h>\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:170
#, no-wrap
msgid "#define BUFFERSIZE 255\n"
msgstr "#define BUFFERSIZE 255\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:176
#, no-wrap
msgid ""
"/* Function prototypes */\n"
"static d_open_t      echo_open;\n"
"static d_close_t     echo_close;\n"
"static d_read_t      echo_read;\n"
"static d_write_t     echo_write;\n"
msgstr ""
"/* Function prototypes */\n"
"static d_open_t      echo_open;\n"
"static d_close_t     echo_close;\n"
"static d_read_t      echo_read;\n"
"static d_write_t     echo_write;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:186
#, no-wrap
msgid ""
"/* Character device entry points */\n"
"static struct cdevsw echo_cdevsw = {\n"
"\t.d_version = D_VERSION,\n"
"\t.d_open = echo_open,\n"
"\t.d_close = echo_close,\n"
"\t.d_read = echo_read,\n"
"\t.d_write = echo_write,\n"
"\t.d_name = \"echo\",\n"
"};\n"
msgstr ""
"/* Character device entry points */\n"
"static struct cdevsw echo_cdevsw = {\n"
"\t.d_version = D_VERSION,\n"
"\t.d_open = echo_open,\n"
"\t.d_close = echo_close,\n"
"\t.d_read = echo_read,\n"
"\t.d_write = echo_write,\n"
"\t.d_name = \"echo\",\n"
"};\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:191
#, no-wrap
msgid ""
"struct s_echo {\n"
"\tchar msg[BUFFERSIZE + 1];\n"
"\tint len;\n"
"};\n"
msgstr ""
"struct s_echo {\n"
"\tchar msg[BUFFERSIZE + 1];\n"
"\tint len;\n"
"};\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:195
#, no-wrap
msgid ""
"/* vars */\n"
"static struct cdev *echo_dev;\n"
"static struct s_echo *echomsg;\n"
msgstr ""
"/* vars */\n"
"static struct cdev *echo_dev;\n"
"static struct s_echo *echomsg;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:198
#, no-wrap
msgid ""
"MALLOC_DECLARE(M_ECHOBUF);\n"
"MALLOC_DEFINE(M_ECHOBUF, \"echobuffer\", \"buffer for echo module\");\n"
msgstr ""
"MALLOC_DECLARE(M_ECHOBUF);\n"
"MALLOC_DEFINE(M_ECHOBUF, \"echobuffer\", \"buffer for echo module\");\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:207
#, no-wrap
msgid ""
"/*\n"
" * This function is called by the kld[un]load(2) system calls to\n"
" * determine what actions to take when a module is loaded or unloaded.\n"
" */\n"
"static int\n"
"echo_loader(struct module *m __unused, int what, void *arg __unused)\n"
"{\n"
"\tint error = 0;\n"
msgstr ""
"/*\n"
" * This function is called by the kld[un]load(2) system calls to\n"
" * determine what actions to take when a module is loaded or unloaded.\n"
" */\n"
"static int\n"
"echo_loader(struct module *m __unused, int what, void *arg __unused)\n"
"{\n"
"\tint error = 0;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:220
#, no-wrap
msgid ""
"\tswitch (what) {\n"
"\tcase MOD_LOAD:                /* kldload */\n"
"\t\terror = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK,\n"
"\t\t    &echo_dev,\n"
"\t\t    &echo_cdevsw,\n"
"\t\t    0,\n"
"\t\t    UID_ROOT,\n"
"\t\t    GID_WHEEL,\n"
"\t\t    0600,\n"
"\t\t    \"echo\");\n"
"\t\tif (error != 0)\n"
"\t\t\tbreak;\n"
msgstr ""
"\tswitch (what) {\n"
"\tcase MOD_LOAD:                /* kldload */\n"
"\t\terror = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK,\n"
"\t\t    &echo_dev,\n"
"\t\t    &echo_cdevsw,\n"
"\t\t    0,\n"
"\t\t    UID_ROOT,\n"
"\t\t    GID_WHEEL,\n"
"\t\t    0600,\n"
"\t\t    \"echo\");\n"
"\t\tif (error != 0)\n"
"\t\t\tbreak;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:236
#, no-wrap
msgid ""
"\t\techomsg = malloc(sizeof(*echomsg), M_ECHOBUF, M_WAITOK |\n"
"\t\t    M_ZERO);\n"
"\t\tprintf(\"Echo device loaded.\\n\");\n"
"\t\tbreak;\n"
"\tcase MOD_UNLOAD:\n"
"\t\tdestroy_dev(echo_dev);\n"
"\t\tfree(echomsg, M_ECHOBUF);\n"
"\t\tprintf(\"Echo device unloaded.\\n\");\n"
"\t\tbreak;\n"
"\tdefault:\n"
"\t\terror = EOPNOTSUPP;\n"
"\t\tbreak;\n"
"\t}\n"
"\treturn (error);\n"
"}\n"
msgstr ""
"\t\techomsg = malloc(sizeof(*echomsg), M_ECHOBUF, M_WAITOK |\n"
"\t\t    M_ZERO);\n"
"\t\tprintf(\"Echo device loaded.\\n"
"\");\n"
"\t\tbreak;\n"
"\tcase MOD_UNLOAD:\n"
"\t\tdestroy_dev(echo_dev);\n"
"\t\tfree(echomsg, M_ECHOBUF);\n"
"\t\tprintf(\"Echo device unloaded.\\n"
"\");\n"
"\t\tbreak;\n"
"\tdefault:\n"
"\t\terror = EOPNOTSUPP;\n"
"\t\tbreak;\n"
"\t}\n"
"\treturn (error);\n"
"}\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:242
#, no-wrap
msgid ""
"static int\n"
"echo_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused,\n"
"    struct thread *td __unused)\n"
"{\n"
"\tint error = 0;\n"
msgstr ""
"static int\n"
"echo_open(struct cdev *dev __unused, int oflags __unused, int devtype "
"__unused,\n"
"    struct thread *td __unused)\n"
"{\n"
"\tint error = 0;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:246
#, no-wrap
msgid ""
"\tuprintf(\"Opened device \\\"echo\\\" successfully.\\n\");\n"
"\treturn (error);\n"
"}\n"
msgstr ""
"\tuprintf(\"Opened device \\\"echo\\\" successfully.\\n"
"\");\n"
"\treturn (error);\n"
"}\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:251
#, no-wrap
msgid ""
"static int\n"
"echo_close(struct cdev *dev __unused, int fflag __unused, int devtype __unused,\n"
"    struct thread *td __unused)\n"
"{\n"
msgstr ""
"static int\n"
"echo_close(struct cdev *dev __unused, int fflag __unused, int devtype "
"__unused,\n"
"    struct thread *td __unused)\n"
"{\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:255
#, no-wrap
msgid ""
"\tuprintf(\"Closing device \\\"echo\\\".\\n\");\n"
"\treturn (0);\n"
"}\n"
msgstr ""
"\tuprintf(\"Closing device \\\"echo\\\".\\n"
"\");\n"
"\treturn (0);\n"
"}\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:266
#, no-wrap
msgid ""
"/*\n"
" * The read function just takes the buf that was saved via\n"
" * echo_write() and returns it to userland for accessing.\n"
" * uio(9)\n"
" */\n"
"static int\n"
"echo_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)\n"
"{\n"
"\tsize_t amt;\n"
"\tint error;\n"
msgstr ""
"/*\n"
" * The read function just takes the buf that was saved via\n"
" * echo_write() and returns it to userland for accessing.\n"
" * uio(9)\n"
" */\n"
"static int\n"
"echo_read(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)\n"
"{\n"
"\tsize_t amt;\n"
"\tint error;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:274
#, no-wrap
msgid ""
"\t/*\n"
"\t * How big is this read operation?  Either as big as the user wants,\n"
"\t * or as big as the remaining data.  Note that the 'len' does not\n"
"\t * include the trailing null character.\n"
"\t */\n"
"\tamt = MIN(uio->uio_resid, uio->uio_offset >= echomsg->len + 1 ? 0 :\n"
"\t    echomsg->len + 1 - uio->uio_offset);\n"
msgstr ""
"\t/*\n"
"\t * How big is this read operation?  Either as big as the user wants,\n"
"\t * or as big as the remaining data.  Note that the 'len' does not\n"
"\t * include the trailing null character.\n"
"\t */\n"
"\tamt = MIN(uio->uio_resid, uio->uio_offset >= echomsg->len + 1 ? 0 :\n"
"\t    echomsg->len + 1 - uio->uio_offset);\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:277
#, no-wrap
msgid ""
"\tif ((error = uiomove(echomsg->msg, amt, uio)) != 0)\n"
"\t\tuprintf(\"uiomove failed!\\n\");\n"
msgstr ""
"\tif ((error = uiomove(echomsg->msg, amt, uio)) != 0)\n"
"\t\tuprintf(\"uiomove failed!\\n"
"\");\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:280
#, no-wrap
msgid ""
"\treturn (error);\n"
"}\n"
msgstr ""
"\treturn (error);\n"
"}\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:290
#, no-wrap
msgid ""
"/*\n"
" * echo_write takes in a character string and saves it\n"
" * to buf for later accessing.\n"
" */\n"
"static int\n"
"echo_write(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)\n"
"{\n"
"\tsize_t amt;\n"
"\tint error;\n"
msgstr ""
"/*\n"
" * echo_write takes in a character string and saves it\n"
" * to buf for later accessing.\n"
" */\n"
"static int\n"
"echo_write(struct cdev *dev __unused, struct uio *uio, int ioflag __unused)\n"
"{\n"
"\tsize_t amt;\n"
"\tint error;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:297
#, no-wrap
msgid ""
"\t/*\n"
"\t * We either write from the beginning or are appending -- do\n"
"\t * not allow random access.\n"
"\t */\n"
"\tif (uio->uio_offset != 0 && (uio->uio_offset != echomsg->len))\n"
"\t\treturn (EINVAL);\n"
msgstr ""
"\t/*\n"
"\t * We either write from the beginning or are appending -- do\n"
"\t * not allow random access.\n"
"\t */\n"
"\tif (uio->uio_offset != 0 && (uio->uio_offset != echomsg->len))\n"
"\t\treturn (EINVAL);\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:301
#, no-wrap
msgid ""
"\t/* This is a new message, reset length */\n"
"\tif (uio->uio_offset == 0)\n"
"\t\techomsg->len = 0;\n"
msgstr ""
"\t/* This is a new message, reset length */\n"
"\tif (uio->uio_offset == 0)\n"
"\t\techomsg->len = 0;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:304
#, no-wrap
msgid ""
"\t/* Copy the string in from user memory to kernel memory */\n"
"\tamt = MIN(uio->uio_resid, (BUFFERSIZE - echomsg->len));\n"
msgstr ""
"\t/* Copy the string in from user memory to kernel memory */\n"
"\tamt = MIN(uio->uio_resid, (BUFFERSIZE - echomsg->len));\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:306
#, no-wrap
msgid "\terror = uiomove(echomsg->msg + uio->uio_offset, amt, uio);\n"
msgstr "\terror = uiomove(echomsg->msg + uio->uio_offset, amt, uio);\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:310
#, no-wrap
msgid ""
"\t/* Now we need to null terminate and record the length */\n"
"\techomsg->len = uio->uio_offset;\n"
"\techomsg->msg[echomsg->len] = 0;\n"
msgstr ""
"\t/* Now we need to null terminate and record the length */\n"
"\techomsg->len = uio->uio_offset;\n"
"\techomsg->msg[echomsg->len] = 0;\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:315
#, no-wrap
msgid ""
"\tif (error != 0)\n"
"\t\tuprintf(\"Write failed: bad address!\\n\");\n"
"\treturn (error);\n"
"}\n"
msgstr ""
"\tif (error != 0)\n"
"\t\tuprintf(\"Write failed: bad address!\\n"
"\");\n"
"\treturn (error);\n"
"}\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:317
#, no-wrap
msgid "DEV_MODULE(echo, echo_loader, NULL);\n"
msgstr "DEV_MODULE(echo, echo_loader, NULL);\n"

#. type: delimited block = 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:321
msgid "With this driver loaded try:"
msgstr "Загрузив этот драйвер, попробуйте:"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:329
#, no-wrap
msgid ""
"# echo -n \"Test Data\" > /dev/echo\n"
"# cat /dev/echo\n"
"Opened device \"echo\" successfully.\n"
"Test Data\n"
"Closing device \"echo\".\n"
msgstr ""
"# echo -n \"Test Data\" > /dev/echo\n"
"# cat /dev/echo\n"
"Opened device \"echo\" successfully.\n"
"Test Data\n"
"Closing device \"echo\".\n"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:332
msgid "Real hardware devices are described in the next chapter."
msgstr "Реальные аппаратные устройства описаны в следующей главе."

#. type: Title ==
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:334
#, no-wrap
msgid "Block Devices (Are Gone)"
msgstr "Блочные устройства (удалены)"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:337
msgid ""
"Other UNIX(R) systems may support a second type of disk device known as "
"block devices. Block devices are disk devices for which the kernel provides "
"caching. This caching makes block-devices almost unusable, or at least "
"dangerously unreliable. The caching will reorder the sequence of write "
"operations, depriving the application of the ability to know the exact disk "
"contents at any one instant in time."
msgstr ""
"Другие системы UNIX(R) могут поддерживать второй тип дисковых устройств, "
"известный как блочные устройства. Блочные устройства — это дисковые "
"устройства, для которых ядро предоставляет кэширование. Это кэширование "
"делает блочные устройства практически непригодными или, по крайней мере, "
"опасно ненадёжными. Кэширование изменяет порядок операций записи, лишая "
"приложение возможности точно знать содержимое диска в любой момент времени."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:339
msgid ""
"This makes predictable and reliable crash recovery of on-disk data "
"structures (filesystems, databases, etc.) impossible. Since writes may be "
"delayed, there is no way the kernel can report to the application which "
"particular write operation encountered a write error, this further compounds "
"the consistency problem."
msgstr ""
"Это делает невозможным предсказуемое и надёжное восстановление после сбоев "
"для структур данных на диске (файловых систем, баз данных и т. д.). "
"Поскольку операции записи могут быть отложены, ядро не может сообщить "
"приложению, какая именно операция записи столкнулась с ошибкой, что "
"усугубляет проблему согласованности."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:341
msgid ""
"For this reason, no serious applications rely on block devices, and in fact, "
"almost all applications which access disks directly take great pains to "
"specify that character (or \"raw\") devices should always be used. As the "
"implementation of the aliasing of each disk (partition) to two devices with "
"different semantics significantly complicated the relevant kernel code, "
"FreeBSD dropped support for cached disk devices as part of the modernization "
"of the disk I/O infrastructure."
msgstr ""
"По этой причине ни одно серьезное приложение не полагается на блочные "
"устройства, и фактически почти все приложения, которые обращаются к дискам "
"напрямую, прилагают значительные усилия, чтобы указать, что следует всегда "
"использовать символьные (или \"сырые\") устройства. Поскольку реализация "
"псевдонимов для каждого диска (раздела) в виде двух устройств с разной "
"семантикой значительно усложняла соответствующий код ядра, FreeBSD "
"отказалась от поддержки кэшируемых дисковых устройств в рамках модернизации "
"инфраструктуры ввода-вывода для дисков."

#. type: Title ==
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:343
#, no-wrap
msgid "Network Drivers"
msgstr "Драйверы сетевых устройств"

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:346
msgid ""
"Drivers for network devices do not use device nodes in order to be accessed. "
"Their selection is based on other decisions made inside the kernel and "
"instead of calling open(), use of a network device is generally introduced "
"by using the system call socket(2)."
msgstr ""
"Драйверы сетевых устройств не используют узлы устройств для доступа. Их "
"выбор основан на других решениях, принимаемых внутри ядра, и вместо вызова "
"open() использование сетевого устройства обычно осуществляется через "
"системный вызов socket(2)."

#. type: Plain text
#: documentation/content/en/books/arch-handbook/driverbasics/_index.adoc:347
msgid "For more information see ifnet(9), the source of the loopback device."
msgstr ""
"Для получения дополнительной информации см. ifnet(9), исходный текст "
"loopback-устройства."