# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-05-01 19:56-0300\n" "PO-Revision-Date: 2025-11-20 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \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 \n" "#include /* uprintf */\n" "#include \n" "#include /* defines used in kernel.h */\n" "#include \n" "#include /* types used in module initialization */\n" msgstr "" "#include \n" "#include /* uprintf */\n" "#include \n" "#include /* defines used in kernel.h */\n" "#include \n" "#include /* 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 \n" msgstr ".include \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 \n" "#include /* uprintf */\n" "#include /* defines used in kernel.h */\n" "#include \n" "#include /* types used in module initialization */\n" "#include /* cdevsw struct */\n" "#include /* uio struct */\n" "#include \n" msgstr "" "#include \n" "#include /* uprintf */\n" "#include /* defines used in kernel.h */\n" "#include \n" "#include /* types used in module initialization */\n" "#include /* cdevsw struct */\n" "#include /* uio struct */\n" "#include \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-устройства."