DragonFlyBSD: Ядро и мир

Автор: Алексей Федорчук
2005.12.08

Сборка собственного ядра — один из любимых видов спорта истинных POSIX’ивстов. А для пользователей BSD-систем спорт этот традиционно приобретает черты многоборья. Потому что они располагают средствами не просто перекомпилировать ядро, но и построить собственный мир — полностью пересобрать базовую систему.

Содержание

Преамбула

Не будут исключением и пользователи DragonFly. Не то что в перед ними стоит жизненно важная задача — выполнить процедуры make buildkernel и makebuildworld в кратчайшие сроки после установки новой системы. Все, нужное для применения этой ОС в мирных целях (поддержка распространенных интерфейсов, всевозможных файловых систем, сетевых карт и протоколов, USB-устройств и звуковых карт), либо встроено в ядро GENERIC, либо реализовано в качестве загружаемых модулей. Да и сама по себе система, установленная со снапшота LATEST-STABLE, без всякой пересборки работает быстро и стабильно.

И тем не менее, отказываться от сборки собственного ядра и «мира» нет оснований. Во-первых, ядро GENERIC предназначено для инсталляции на некую абстрактную машину, и потому включает в себя немерянное количество опций, в конкретной ситуации не нужных — например, поддержку всевозможных сетевых карт (а часто ли в настольной машине их больше одной?) и SCSI-контроллеров (а их-то в современном десктопе и того меньше). Да еще и отладочную информацию содержит, простому пользователю совершенно не нужную. За счет всего этого ядро распухает до совершенно неприличных размеров (у меня образ ядра по умолчанию составил более 5 Мбайт).

Конечно, на современных машинах размер ядра не столь уж критичен. Однако при всем при том в ядре не оказывается по крайней мере одной опции, жизненно важной в современных условиях. И это — поддержка графической консоли, давно уже ставшая привычной для пользователей Linux. Почему я полагаю эту опцию жизненно важной — расскажу со временем (как и о графической консоли вообще и в DragonFly в частности). А пока прошу поверить на слово — уже одно это оправдывает толику времени, потраченную на конфигурирование и сборку нового ядра.

Резоны для немедленной сборки «мира» не столь однозначны. Поскольку в каждый момент времени можно получить стабильный снапшот возрастом не более чем в неделю, то он является не только надежным, но и более чем современным с точки зрения своего состава. Так что единственным стимулом (кроме тяги к экспериментам) может быть стремление к тюнингу системы — исключению лишних компонентов, оптимизации под процессор, и тому подобные иррациональные (но очень действенные) факторы…

Так что сначала я рассмотрю канонический путь — последовательную сборку «мира» и ядра, а затем вернусь к вопросу о пересборке ядра отдельно. Ну и некоторым другим частностям.

Принципы сборки ядра и «мира» в DragonFly те же, что и во FreeBSD: прямая правка файлов конфигурации в текстовом редакторе, сборка посредством команды make с указанием соответствующей цели, инсталляция. И все это очень подробно описано в документации (см. список ссылок). Однако коснуться этого вопроса мне представляется необходимым, и по двум причинам.

Во-первых, процесс конфигурирования и сборки ядра в DragonFly имеет некоторую специфику по сравнению с FreeBSD (все-таки другое ядро, и да и ОС совсем другая). А во-вторых, все указанные документы обновляются гораздо медленнее, чем сама система, и описанное в них не всегда точно соответствует современным реалиям.

Маленькое отступление: вообще DragonFlyBSD Handbook требует аккуратного обращения. Большая часть его заимствована из FreeBSD Handbook (что понятно: системы-то схожие, а заново написать такой труд за год, да еще и при ограниченном составе участников проекта, — задача непосильная). И заимствовано подчас механически, без приведения в соответствие со спецификой DragonFly. То же касается и man-страниц: те из них, что посвящены описанию программ, общих в обеих операционках, иногда просто целиком перенесены в DragonFly без всякой коррекции. Так что подчас единственно достоверными источниками актуальной информации оказываются комментарии в Make-файлах.

Получение исходников

Прежде чем приступать к конфигурированию и пересборке системы, не худо было бы разжиться ее исходными текстами. На установочном диске DragonFly их нет, единственный источник — это Сеть. Ежедневный снапшот всей системы (включая, конечно, и ядро) доступен на ftp-сервере проекта, но только через cvsup. Пакет этот входит в штатный комплект DragonFly (в числе дополнительных пакетов, устанавливаемых на стадии конфигурирования). Настройка его не сложна, как в дистрибутиве (в каталоге /usr/share/examples/cvsup), так и на странице Download сайта проекта имеются примеры конфигов на разные случаи жизни: для получения исходников только ядра, или всей системы в целом, в стабильном или текущем ее варианте.

По умолчанию полученные через cvsup исходники помещаются в специальный подкаталог файловой системы /home/home/dcvs), что не всегда удобно. И потому имеет смысл несколько подредактировать конфиги (они называются dragonfly-cvs-supfile и dragonfly-cvs-sys-supfile — для получения всех исходников или только ядра, соответственно). Мой конфиг для получения всех исходников (плюс дерева портов dfports) выглядит следующим образом:

# All DragonFlyBSD sources, sys and dfports
*default host=cvsup.dragonflybsd.org
*default base=/usr
*default prefix=/usr
*default release=cvs tag=DragonFly_Stable
*default delete use-rel-suffix

cvs-src
#cvs-sys
cvs-root
cvs-dfports
#cvs-site

Если нужны только исходники ядра, комментарий со строки cvs-sys следует перенести на строку cvs-src. А строка cvs-site предписывает получать документацию с сайта проекта. Которая обновляется не столь уж часто:-), и потому в синхронизации не нуждается.

Важный аспект — какие именно исходники качать, стабильной ветви или разрабатываемой. В примере (в строке default release) предлагается первый вариант. Его настоятельно рекомендую тем, кто собирается использовать DragonFly для реальной практической работы. Любители же экспериментов могут изменить ее таким образом:

*default release=cvs tag=.

Однако при этом следует помнить, что базовая система из текущего дерева снапшотов собирается через раз (а то и через два на третий). А если и соберется — может работать несколько странно (примеры странностей я приведу в дальнейшем — и не говорите, что вас не предупреждали).

Есть и другой способ получения исходников системы (вместе с ядром): скачать полный их тарбалл целиком с одного из зеркал проекта (на главном ftp-сервере такого не обнаружить). Правда, мне известно единственное такое зеркало — ftp://ftp.fortunaty.net/DragonFly/.

Наконец, на GoBSD, кроме iso-образа собственной сборки, доступен и тарбалл исходников, из которых он был скомпилирован.

Предварительное конфигурирование

В любом случае — исходники получены и помещены куда следует (в /usr/src — как говорилось в предыдущей статье, под эту ветвь файловой системы целесообразно выделить самостоятельный раздел объемом около гигабайта. Приступаем к конфигурированию.

Цель его — определение общих условий компиляции ядра и «мира», многие из них имеют силу и для системы портов, но об этом — в другой раз. А условия эти описываются в специальном конфигурационном файле — /etc/make.conf. В свежеинсталлированной системе такого не имеется — его нужно скопировать с прототипа

$ cp /etc/defaults/make.conf /etc/make.conf

и отредактировать по своим потребностям.

Устройство /etc/make.conf достаточно просто: это список определений переменных, значения которых будут подставляться в опции командной строки компилятора gcc и при выполнении команды make. Рассмотрим те из них, которые важны для сборке ядра и «мира» (переменные, важные для системы портов, будут рассмотрены в соответствующей статье). И в порядке их логики, а не расположения строк в /etc/make.conf.

А в порядке логики первой переменной оказывается версия компилятора: ведь от нее будут зависеть многие другие параметры.

В прошлой статье уже говорилось о том, что в инсталлированной DragonFlyBSD доступны две параллельные версии gcc — 2.95 и 3.4.X. И обсуждался вопрос о их сравнительных достоинствах и недостатках. Однако применительно к сборке ядра и «мира» могу, основываясь на опыте выполнения более чем десятка этих процедур, высказаться вполне определенно:

Если вы хотите получить безукоризненно работающую, быструю и компактную систему, пользуйтесь gcc-2.95.

Не то чтобы система, собранная с gcc-3.4, будет обязательно нестабильной. Однако хоть какие-нибудь мелкие, но неприятные странности в ней обнаружатся почти обязательно.

К тому же использование gcc-3.4 в нашем случае и не очень целесообразно. Ибо основные его преимущества перед gcc-2.95 — в улучшенной генерации кода С++ и возможности оптимизации под современные процессоры. Однако применительно к ядру и «миру» ни то, ни другое не работают. Ибо, ни ядро, ни системные и пользовательские утилиты базовой системы не содержат ни кода Си++, ни расширенных инструкций, использование которых (от MMX до SSE3) и достигается оптимизацией под Pentium-4 или Athlon.

Другое дело — прикладные программы, собираемые из портов, для них оба фактора могут иметь значение. Однако до портов нам еще далеко. Так что на стадии сборки базовой системы остаемся со старым добрым gcc-2.95, для которого время остановилось на процессоре i686. В принципе он и так будет вызываться из команды make по умолчанию. Однако аккуратности ради определим его явным образом в файле /etc/make.conf с помощью специальной переменной:

CCVER?=gcc2

Памятуя о том, что это не вечно, добавим еще и такую строку:

#CCVER?=gcc34

что позволит нам в дальнейшем, при сборке портов, изменить умолчальный компилятор просто перестановкой символов комментария.

А пока двигаемся дальше — теперь уже именно к процессору. Тип его задается переменной

CPUTYPE=значение

устанавливающей флаги -mcpu=значение и -march=значение. При использовании gcc-2.95 (а мы вроде бы на нем и остановились?) старшим из допустимых процессоров оказывается i686 (он же — PentiumPro). С gcc-3.4 можно дать и более поздние модели (вплоть до p4 и k7, что подробно описано в комментариях к /etc/make.conf). Однако, как я уже говорил, практического значения это не имеет.

Установка переменной CPUTYPE определяет значения флагов mcpu и march, что делает невозможным запуск собранных бинарников на машине с более слабым процессором. Добавив переменную

NO_CPU_CFLAGS= true

этого можно избежать, то есть, ограничившись флагом mcpu, сохранить возможность запуска на более старых машинах. Но оно нам нужно? Ведь на более слабой машине, чем стоит на нашем столе, мы свое ядро запускать не собираемся. Тем более, что найти что-то слабее i686 нынче нелегко.

Определившись с компилятором и процессоров, нужно задать уровень, по которому первый будет оптимизировать код под второй. Для чистого Си-кода это достигается установкой значений специальной переменной, по умолчанию выглядящей так:

CFLAGS= -O -pipe

То есть по умолчанию принят самый низкий уровень оптимизации (-O эквивалентно -O1, ниже — только -O0, то есть отсутствие всякой оптимизации), и может возникнуть желание повысить его до -O2 или даже -O3. Сразу должен предупредить — при использовании gcc-2.95, это лучше и не пытаться сделать — сборка «мира», как правило, завершается ошибками при любых уровнях, кроме умолчального (ядро может собраться успешно и при -O2, о чем я скажу чуть позже).

При сборке с компилятором gcc-3.4 теоретически можно прибегнуть и к более высоким уровням: в списках рассылки проекта DragonFly мне встречались сообщения об успешной компиляции «мира» даже при уровне -O3, а при -O2 я и сам это проделывал не один раз. Однако безошибочное завершение компиляции — это одно, а вот безошибочная работа системы после этого — совсем другое. И вот гарантировать последнее при уровнях выше умолчального я бы не стал.

Аномалии в работе системы, «заоптимизированной до посинения», возможны всякие разные: от отказа выключения компьютера по команде halt -p и ошибок в размонтировании файловых систем до совсем уж неприятных вещей.

Так, у меня однажды после сборки «мира» с флагом -O2 (справедливости ради замечу, что это был не снапшот проекта, а GoBSD Preview 2) напрочь отказались работать многие системные утилиты — от man до gz. И что самое печальное — откатиться назад не удавалось: по вышеуказанной причине попытка перекомпиляции с более низким флагом оптимизации очень скоро вызывала сообщение об ошибке. То есть работоспособность системы казалась невосстановимой без полной реинсталляции.

Очередное отступление: я прекрасно понимаю, что мои (во многом лицемерные:-)) предупреждения касаемо оптимизации не окажут никакого воздействия на истого POSIX’виста-экспериментатора. Как и сам я не принимал во внимание советы резонных людей — пока не опробовал все на собственной шкуре. А поскольку в ходе такого опробования вероятны ситуации, подобные описанной в предыдущем абзаце, в заключительном разделе этой статьи будет рассказано, как выйти из них малой, относительно, кровью.

Переменная CFLAGS задает флаги компилятора gcc глобально — то есть как для сборки ядра и «мира», так и портов (почему при переходе к портированию ее можно будет изменить — большинство портов нормально собираются с уровнем оптимизации -O2 и даже -O3). Однако флаги для сборки ядра можно определить и автономно — для этого служит переменная COPTFLAGS= значение. Как и в случае для CFLAGS, умолчальное ее значение —

COPTFLAGS= -O -pipe

Однако, в отличие от «мира», ядро успешно собирается и благополучно работает и при более высоких степенях оптимизации — при -O2 вне зависимости от версии компилятора, и при -O3 — компилятором gcc-3.4. Так что при желании к одному из них можно прибегнуть — другое дело, нужно ли?

Из прочих переменных, имеющих отношение к сборке ядра, заслуживает внимание такая:

#NO_MODULES=    true

Суть ее — вот в чем: в отличие от Linux, в DragonFly (как и во FreeBSD) модули поддержки функций, в принципе таковую допускающих, собираются в любом случае (не зависимо от того, включены они в ядро или нет). Если же снять комментарий с этой строки, то модули ядра собираться не будут вообще. То есть функциональность ядра будет определяться исключительно теми опциями, которые жестко в него встроены. Хорошо это или плохо — вопрос спорный. Во FreeBSD я всегда жестко встраивал нужные мне функции в ядро, запрещая сборку модулей — дабы не загромождать файловую систему множеством заведомо ненужных модулей. Однако идеология архитектуры DragonFly — перенос драйверов устройств в userland, то есть пользовательское пространство памяти, — как бы подталкивает к модульной поддержке всего, чего только можно — даже поддержку всех файловых систем, кроме нативной UFS (очевидно, что FS, на которой лежит корень файлового древа, модульно поддерживаться не может). И потому в своем примере я эту строку оставил закрытой комментарием.

Что же касается переменных, оказывающих влияние на сборку «мира», то их довольно много, и собраны они в отдельной секции:

# To avoid building various parts of the base system:

Все строки, определяющие эти переменные, по умолчанию закомментированы и имеют вид вроде

#NO_CVS=        true

Из чего очевидно, что, если снять символ комментария с такой строки, то соответствующая часть базовой системы не будет компилироваться при сборке «мира». Что позволяет избавиться от балласта, полученного при первичной установке системы. На мой взгляд, кандидатов на отсеивание тут довольно много — но их каждый должен определять для себя сам.

Конфигурирование ядра

Следующий шаг, после настройки условий компиляции — собственно конфигурирование нового ядра. В BSD-системах для этого не предусмотрено никаких инструментов типа make menuconfig — включение и выключение опций выполняется в самом обычном текстовом редакторе прямым редактированием конфигурационного файла.

Конфигурационный файл умолчального ядра GENEREC (того самого, которое загружается с LiveCD при инсталляции и без всяких изменений переносится на диск при установке) находится в каталоге /usr/src/sys/i386/conf: каталог sys — штатное место для исходников ядра, в i386 помещаются части, имеющие отношение к соответствующей архитектуре (на сегодняшний день — единственной, поддерживаемой DragonFly), conf — место помещения конфигурационных файлов. Кроме GENERIC, там содержится еще файл TINDERBOX (какое-то тестировочное ядро, страница в Интернете, на которой должно быть объяснено, что это такое, в данный момент находится в состоянии Under Construction) и, главное, всеобщий LINT. Последний — не реальный конфиг (собрать на его основе работающее ядро, как говорят резонные люди, невозможно), а список всех возможных опций настройки ядра. То есть если вам кажется, что в ядре GENERIC чего-то не хватает — ищите в LINT, и обрящете. Благо LINT (в отличие от GENERIC) неплохо структурирован, разделяясь на секции типа — CPU OPTIONS, COMPATIBILITY OPTIONS и так далее, и довольно подробно прокомментирован.

Итак, процесс конфигурирования ядра DragonFly сводится к модифицированию файла GENERIC (в любимом текстовом редакторе) на предмет вычеркивания лишних строк и внесения недостающих опций из файла LINT. Правда, сам GENERIC по вполне понятным причинам редактировать не рекомендуется. Так что для начала копируем его содержание в новый файл:

$ cp GENERIC MYKERNEL

Имя файла конфигурации ядра по традиции дается символами верхнего регистра. Само по себе оно совершенно произвольно. Однако также традиционно принято, чтобы оно совпадало с именем (hostname) машины — и это действительно удобно. Теперь открываем MYKERNEL в подходящем (то есть любом) текстовом редакторе, не забыв проверить, выключен ли режим переноса строк (впрочем, это — общее правило при модификации конфигов). Параллельно (в другой виртуальной консоли) открываем командой типа less файл LINT — для сверки, так сказать, с картотекой. И еще одна консоль может оказаться не лишней: на нее можно направить вывод команды

$ dmesg | less

чтобы сверяться, при необходимости, со списком наличного «железа».

При редактировании нашего конфига нужно иметь ввиду, что от своего папаши-GENERIC‘а он унаследовал из рук вон плохую структуризацию: порядок перечисления опций конфигурирования подчиняется логике, ведомой одному Аллаху. И часто не совпадает с тем порядком, в котором они следуют в файле LINT. Само по себе это никакого значения не имеет (опции ядра могут быть перечислены вообще в произвольном порядке), но доставляет по первости некоторые неудобства.

Смысл многих опций в прототипе нашего конфига более-менее понятен из а) их названия и б) сопутствующих комментариев. Если тех покажется недостаточным, следует обратиться к файлу LINT: очень возможно, что там описание будет более полным. Если же и из ясности не найдется и в них — придется положиться на интуицию и всякого рода общие соображения (а также сведения из DragonFly BSD Handbook — со всеми сделанными ранее оговорками).

Мое твердой убеждение — неясные опции следует вычеркивать безжалостно: скорее всего, они оттого-то и непонятны, что обеспечиваемые ими функции лично мне не нужны. Впрочем, существует и противоположная точка зрения: при сомнении нужно сохранять то, что имеется по умолчанию. Какому пути следовать — каждый решает для себя сам.

Минимизации опций, встраиваемых в ядро, способствует еще и то, что подавляющее большинство обеспечиваемых ими функций все равно будут доступны — через загружаемые модули. Правда, не все — некоторые очень важные функции поддерживаются только непосредственно в ядре. Чтобы узнать, возможна ли модульная поддержка нужной опции, достаточно просмотреть каталог /modules. Кроме того, некоторое (не вполне полное) представление о функциях, поддерживаемых модульно, можно получить из просмотра файла /boot/defaults/loader.conf — к рассмотрению его мы еще вернемся).

И еще: при вычеркивании или вписывании опций следует помнить, что некоторые из них связаны между собой. Большинство таких взаимозависимостей оговорены в комментариях, да и я в своем примере буду останавливаться на всех известных мне зависимостях.

Как обычно, процесс конфигурирования чего бы то ни было гораздо проще показать, чем описать. Так что я просто дам ниже пример своего файла конфигурации ядра, снабдив соответствующими комментариями. Особо оговаривая обязательность и необязательность опций, а также их взаимосвязи. Унаследованные из GENERIC ненужные, по моему мнения (но, возможно, потребующиеся в какой-либо ситуации) опции закрыты символом комментария (#).

Пример конфигурационного файла ядра

Во первых строках своего письма (сиречь конфига) следует указать, что это за ядро, и с какой целью конфигурировалось — просто для памяти:

#
# ALV -- Мой файл конфигурации ядра DragonFly/i386
#
# Включена поддержка графической консоли
# Выключены все ненужные опции (SCSI, RAID, лишние сетевые карты)

Далее — общие опции, характеризующие машину.

machine         i386

Это — не обозначение процессора, а указание на архитектуру компьютера (то есть синоним Intel-совместимой машины с 32-разрядным процессором). И хотя сейчас это — единственная поддерживаемая архитектура, но строка с явным ее определением обязательна.

#cpu            I386_CPU
#cpu            I486_CPU
#cpu            I586_CPU
cpu             I686_CPU

А вот это уже о процессоре. По умолчанию включены все строки — очевидно, что для собственных целей следует оставить только одну (что-то мне подсказывает, что последнюю — это все камни от PentiumPro и выше, включая Athlon и Pentium 4), но уж одна-то должна присутствовать непременно. Указание здесь имени процессора не отменяет его определения в переменной CPUTYPE файла /etc/make.conf, и наоборот.

ident           ALV

Это — идентификатор текущей сборки ядра. Может быть абсолютно любым, но логично давать его совпадающим с именем файла конфигурации. Это строка, как и три предшествующие, является обязательной.

maxusers        0

Вопреки названию, эта строка определяет не столько максимальное количество пользователей системы, сколько количество одновременно работающих процессов, открытых файлов, буферов памяти и так далее. Если поставить здесь 0, система будет рассчитывать все это по собственному разумению, исходя из наличных ресурсов (и сделает это лучше, чем, например, я). Так что если нет глубокого понимания сути этих материй (а у меня, например, нет), оставляем все как есть.

#makeoptions    DEBUG=-g

Эта строка предписывает включить в бинарник ядра отладочную информацию. Мне она не нужна (все равно не знаю, что с ней делать), и потому здесь у меня стоит знак комментария.

Следующий блок строк — сборная солянка опций поддержки файловых систем и некоторых других функций. Рассмотрим их последовательно.

#options        MATH_EMULATE

Количество слов, посвященных эмуляции сопроцессора, давно превысило возраст (в миллисекундах) последней машины, такового не имеющей. Вычеркиваем.

options INET #options INET6

Поддержка IP (Internet Protocol) версий 4 и 6, соответственно. Первая строка необходима, вторая пока, скорее всего, — нет (IPv6 в настоящее время мало где поддерживается).

options         FFS
options         FFS_ROOT

Поддержка FFS (нативной файловой системы DragonFly) и загрузки с оной. Очевидно, ни без того, ни без другого не обойтись. Причем, как будет ясно в дальнейшем, это — практически единственная файловая система, поддержку которой необходимо встроить в ядро.

options SOFTUPDATES

Поддержка механизма Softupdates для файловой системы UFS — очень полезной особенности, повышающей как надежность файловых операций, так и, парадоксальным образом, их быстродействие. Практически необходимая опция.

options         UFS_DIRHASH

Опция, зело способствующая скорости доступа к содержимому каталогов (особенно с большим количеством файлов). Так что не помешает.

#options MFS
#options MD_ROOT

Поддержка файловой системы в оперативной памяти (mfs — Memory File System) и возможности загрузки с RAM-диска. Если последней не предполагается — можно спокойно вычеркнуть обе строки. Это ничуть не помешает использованию mfs как таковой, даже ее монтированию при старте системы (как это предлагалось в прошлой статье для каталогов tmp и /usr/obj): нужный модуль (/modules/mfs.ko) будет загружен автоматически.

#options NFS
#options NFS_ROOT

Поддержка одноименной сетевой файловой системы и загрузки по сети, соответсвенно. С ними можно поступить аналогично: если загрузка по сети не требуется, доступ к машинам локальной сети будет прекрасно обеспечиваться через соответствующий модуль.

#options        MSDOSFS
#options        CD9660
#options        CD9660_ROOT

Поддержка FAT всякого рода, файловой системы CD-дисков (iso9660) и возможности загрузки с последних. При эпизодическом использовании во включении их нет никакой необходимости (также как отпадает необходимость внесения из LINT строки options EXT2FS для доступа к файловой системе Linux). Все эти функции обеспечиваются собираемыми по умолчанию модулями, активизируемыми при обращении к устройствам, несущим соответствующие файловые системы. А отключение опции CD9660_ROOT загрузке с CD при должных установках BIOS не препятствует, требуясь только при загрузке с этого носителя через BSD loader (о котором речь пойдет в одной из ближайших статей).

#options         PROCFS

Поддержка файловой системы процессов. Каковая используется многими программами для получения информации о системе или для непосредственного ее просмотра, как обычных файлов. Однако и для этой файловой системы реализована модульная поддержка, обспечивающая, в том числе, и ее автоматическое монтирование при старте системы.

options         COMPAT_43

Опция совместимости с 43BSD (одного из родоначальников BSD-клана — не путать с FreeBSD 4.3). Необходима — без нее ядро не соберется.

#options        SCSI_DELAY=15000

Задержка перед опробованием SCSI-устройств. Вам оно нужно? Я так обхожусь.

options         UCONSOLE

Эта строка обеспечивает захват системной консоли любым пользователем. В BSD-системах, в отличие от Linux, первый виртуальный терминал сохранил рудимент древней системной консоли — на него по умолчанию сыпятся системные сообщения. Так вот, эта опция позволяет в принципе перенаправить их, например, в окно эмулятора терминала Иксового сеанса. Теоретически могу представить себе ситуацию, когда это нужно (например, при автоматическом запуске Иксов после загрузки машины).

#options        USERCONFIG
#options        VISUAL_USERCONFIG

Включение редактора конфигурации ядра, вызываемого при загрузке, и визуальной оболочки для него. Может пригодиться при тестировании всякого железа. Я ни разу потребности не ощутил.

#options        KTRACE

Трассировщик для отладки ядра. Как-то обхожусь — и пока жив.

options         SYSVSHM

Поддержка разделяемой памяти в стиле System V. Требуется некоторым программам. В частности, Иксы без этой опции ругаются при старте (но тем не менее работают). Лучше, однако, оставить.

options        SYSVMSG
options        SYSVSEM

Поддержка сообщений и семафоров, соответственно, в стиле System V. Как ехидно сказано в Handbook’е, не делают почти ничего, кроме как добавляют по несколько сот байт кода в ядро. Тем не менее, следствием было установлено, что некоторые программы для работы с аудио (в частности, waveplay и waverecord, возможно, и другие) без семафоров обйтись не могут. Так что во избежание лучше оставить обе.

#options        P1003_1B
#options        _KPOSIX_PRIORITY_SCHEDULING

Расширения для систем реального времени. Я в этом ничего не понимаю — и потому вычеркиваю.

#options        ICMP_BANDLIM

Опция предназначена, в частности, для защиты от DoS-атак, что важно для сервера, но вряд ли актуально для десктопа.

#options KBD_INSTALL_CDEV

В руководстве задумчиво сказано, что благодаря этой опции некий CDEV добавляется в каталог /dev. Возможно, кому-то это и нужно, но я живу без этого.

#options        AHD_REG_PRETTY_PRINT

Распечатка регистров для облегчения отладки. Если таковой не предполагается — прожить без нее можно.

Далее идут блоки поддержки SMP и отладки. Многопроцессорной машины у меня нет, и отладкой ядра я не занимаюсь, поэтому все их строки закомментированы.

# To make an SMP kernel, the next two are needed
#options        SMP
#options        APIC_IO
# Debugging for Development
#options        DDB
#options        DDB_TRACE
#options        INVARIANTS
#options        INVARIANT_SUPPORT

А теперь начинается самый большой раздел — поддержка всякого рода устройств. Он же — и требующий наибольшего внимания. Не потому, что остальные разделы не важны, просто здесь легче всего допустить ошибку.

device          isa
#device         eisa
device          pci

Поддержка одноименных системных шин. Очевидно, что вторая строка не нужна, третья необходима. Как ни странно, необходимой оказывается и первая строка — даже если в машине нет ни одного ISA-разъема: шина-то есть, и через нее работают мышь и клавиатура (в исполнении PS/2). И для syscons она требуется.

# Floppy drives
#device         fdc0    at isa? port IO_FD1 irq 6 drq 2
#device         fd0     at fdc0 drive 0
#device         fd1     at fdc0 drive 1

Поддержка флоппи-дисководов. У меня такового давно нет — и потому ремарка, ремарка и еще раз ремарка.

# ATA and ATAPI devices

Секция поддержка ATA-устройств.

#device          ata0    at isa? port IO_WD1 irq 14
#device          ata1    at isa? port IO_WD2 irq 15

Поддержка старых IDE-контроллеров, ныне давно вымерших.

device          ata
device          atadisk                 # ATA disk drives
device          atapicd                 # ATAPI CDROM drives

Общая поддержка ATA-интерфейса, ATA-винчестеров и ATAPI-CD. Необходимо, если только не все накопители в системе — SCSI (что — вряд ли).

#device         atapifd                 # ATAPI floppy drives
#device         atapist                 # ATAPI tape drives

Поддержка ATAPI-floppy (сиречь Zip и LS-приводов) и ATAPI-стриммеров, соответственно. Необходимо, если есть соответствующие устройства.

#device         atapicam

Common Access Method, обеспечивающий, в частности, эмуляцию SCSI-шины через ATA-интерфейс. До недавнего времени требовалась для записи дисков CD-R/RW утилитой cdrecord. Ныне последняя работает напрямую с ATA-приводами. И к тому же в BSD-системах испокон веков для этой цели существовала собственная утилита burncd, также ни в какой эмуляции SCSI не нуждающаяся. Впрочем, для записи DVD-R/RW эмуляция SCSI вроде бы по прежнему нужна — за отсутствием соответствующего девайса информации на этот счет не имею (но буду за таковую признателен).

options         ATA_STATIC_ID

Статическая нумерация дисковых устройств в зависимости от их положения на IDE-канале (а не в порядке подключения). Нужно или нет — вопрос привычки (я привык).

# SCSI Controllers

Секция поддержки конкретных SCSI-контроллеров. У меня нет ни одного, и потому все ее содержимое вычеркнуто.

# SCSI peripherals

А вот это — общая поддержка SCSI-устройств, и без этой секции, как сейчас станет ясным, в современных условиях не обойтись.

device          scbus
device          da

Общая поддержка SCSI-шины и SCSI-дисков (da — Direct Access). Практически необходимы — в Unix’ах все напоители, не являющиеся IDE, имеют обыкновение прикидываться SCSI-дисками. То есть эти опции необходимы для использования обычных USB-флешек и внешних USB-винчестеров. А также — Zip-приводов на параллельном порту, но это уже не очень актуально.

#device         sa              # Sequential Access (tape etc)
#device         cd              # CD

Поддержка стриммеров и CD ROM со SCSI-интерфейсом. У кого есть — сами знают, что нужно.

Еще одна строка из того же блока —

device          pass

Она нужна, насколько я знаю, для эмуляции SCSI через ATA, о чем говорилось выше.

Далее идут две секции, посвященные RAID-контроллерам:

# RAID controllers interfaced to the SCSI subsystem

и

# RAID controllers

За отсутствием оных у меня вычеркнуты на корню.

Теперь переходим к опциям, так или иначе связанным с поддержкой консоли.

# atkbdc0 controls both the keyboard and the PS/2 mouse
device          atkbdc0 at isa? port IO_KBD
device          atkbd0  at atkbdc? irq 1 flags 0x1
device          psm0    at atkbdc? irq 12

Это — поддержка контроллера клавиатуры, собственно клавиатуры как таковой и мыши PS/2. Необходимо.

device          vga0    at isa?

Поддержка стандартного VGA-режима консольного экрана. Необходимо, так как с точки зрения консоли крутейший GeForce не более чем обычный VGA-адаптер.

# splash screen/screen saver
pseudo-device   splash

Псевдоустройство, обеспечивающее вывод заставки при загрузке системы, а в дальнейшем — загрузку модулей скринсейверов. Добавлять по вкусу.

options         SC_HISTORY_SIZE=1000

Максимальный размер буфера экрана (в строках) — того самого буфера истории, который можно пролистать при включенной клавише ScrollLock (не путать с буфером истории команд, он определяется настройками шелла). Мне умолчальных 200 строк явно мало.

options         SC_MOUSE_CHAR=0x3

Переопределение кодов для т.н. графического курсора мыши в консоли. Требуется, если в качестве кодировки вывода используется KOI8 (иначе текст на экране портится). В предыдущей статье того же результата мы достигали внесением соответствующей строки в файл /etc/rc.conf, которую теперь можно будет убрать. Впрочем, кому что проще.

#options         VESA

Поддержка видеорежимов VESA-стандарта (все современные карты с ним совместимы). Требуется, если есть желание использовать нестандартные разрешения (точнее, плотность символов) в текстовой консоли, графические заставки при загрузке и графические же скринсейверы. Доступна также в виде модуля, хотя и не загружающегося автоматически (это следует настроить при конфигурировании загрузчика, о чем речь пойдет в одной из ближайших статей).

options         SC_PIXEL_MODE

Та самая, обещанная, опция, оправдывающая весь процесс — поддержка графической консоли. В качестве загружаемого модуля эта функция не поддерживается, в ядре GENERIC эта строка отсутствует, переносится из файла LINT.

#options         MAXCONS=10

Опция (также перенесенная из LINT, сохранена (с ремаркой) в назидание самому себе. Теоретически устанавливает ограничение числа виртуальных консолей (умолчальное значение — 16, из них в свежеустановленной системе активизировано 8). Во FreeBSD использование ее не влекло никогда вреда ни малейшего. В DragonFly же, собрав ядро с этой опцией, я после рестарта получил ровно две виртуальные консоли — и ни одной свободной (то есть и Иксы было не запустить). Причины остались неизвестными — по вычеркивании опции и пересборке ядра все пришло в норму.

device          agp

Поддержка шины agp. Сейчас (пока еще?) — необходимость.

device npx0 at nexus? port IO_NPX irq 13

Поддержка «железного» сопроцессора — необходима, даже если такового не имеется, без этой опции ядро отказывается компилироваться.

#device          apm0

Поддержка расширенного управления питанием (APM). Насколько я понимаю, при наличие ACPI (собираемого в виде модуля, и только в виде него) не нужна.

# PCCARD (PCMCIA) support
device          pccard
device          cardbus
device          cbb
device          pcic

Поддержка PC-карт (они же — PCMCIA): общая (pccard), интерфейса для новых PCI-карт (cardbus и cbb), моста ISA/PCCARD для старых ISA-карт (pcic), в числе последних — «железные» модемы. Требуется на ноутбуках (если соответствующие карты имеются). Впрочем, реализуема и в виде модулей, и потому даже в этом случае в ядро их втсраивать не обязательно.

# Serial (COM) ports
device          sio0    at isa? port IO_COM1 flags 0x10 irq 4
device          sio1    at isa? port IO_COM2 irq 3
device          sio2    at isa? disable port IO_COM3 irq 5
device          sio3    at isa? disable port IO_COM4 irq 9

Поддержка последовательных портов. Первые две строки — для внешних, вторые — если имеется внутренний модем, определяемый как COM3 или COM4.

# Parallel port
device          ppc0    at isa? irq 7
device          ppbus           # Parallel port bus (required)
device          lpt             # Printer
#device         plip            # TCP/IP over parallel
device          ppi             # Parallel port interface device
#device         vpo             # Requires scbus and da

Группа опций поддержки параллельного порта. Смысл большинства ясен из названия или неактуален, так что за подробностями — к комментариям в LINT. Только о последней строке: это тот самый Zip-привод на параллельном порту, который прикидывается SCSI-диском и потому требует поддержки scbus и da.

Теперь пойдет подразмел о сетевых картах. Карт этих, как известно, не много много, а очень много, и подраздел очень длинный. Однако реально нужно только ниже перечисленное.

device          miibus

Эта опция необходима для многих сетевых карт, а также и для использования модемного соединения. Так что скорее всего, нужна.

device          fxp

Поддержка чипсетного сетевого адаптера от Intel ICH#. Эту строку следует заменить на ту, что соответствует наличной сетевой карте (какой — смотрим в выводе dmesg или ifconfig.

pseudo-device   loop

Сетевое loopback-устройство. Требуется для «внутримашинной» сети — например, запуска web-сервера.

pseudo-device   ether

Поддержка Ethrnet-соединения. Необходимо.

pseudo-device   ppp     1
pseudo-device   tun

Поддержка «ядерного» (через демон pppd) или пользовательского (через программу ppp) соединения точка-точка; одно из двух необходимо для модемного подключения.

pseudo-device   pty

Поддержка псевдотерминалов. Необходима, так как требуется программам типа telnet, а также Иксовым эмуляторам терминалов.

pseudo-device   md

Поддержка Memory Disks, тех самых псевдоустройств, на которых базируется файловая система mfs (о ней говорилось выше). Доступна в виде модуля

pseudo-device   bpf             #Berkeley packet filter
pseudo-device   crypto          # core crypto support, used by wlan

Первая опция, насколько я понимаю, необходима, вторая же может функционировать и как модуль.

И теперь два последниз блока — о USB и Firewire.

device          uhci            # UHCI PCI->USB interface
device          ohci            # OHCI PCI->USB interface
device          usb             # USB Bus (required)

Общая поддержка USB (третье) и типов USB-контроллеров для USB 2.0. Третья строка необходима в любом случае, одна из двух первых — также.

device          ugen

Поддержка всего класса USB-устройств. Необходимо.

device          uhid

«Гуманистический» интерфейс для взаимодействия с человеком. Включает поддержку USB-клавиатур и мышей.

#device         ukbd
device          ums

То же самое, но по отдельности — поддержка клавиатуры и мыши, соответственно.

device          ulpt
device          uscanner

Принтеры и сканеры с USB-интерфейсом, соответственно.

device          umass

Поддержка внешних накопителей с USB-интерфейсом — флэшек, внешних винчестеров и, как ни странно, цифровых камер (вернее, их накопителей, как втроенных, так и внешних), а также карт-ридеров. Прикидываются SCSI-дисками и потому требуют поддержки scbus и da.

# USB Ethernet, requires mii
#device         aue             # ADMtek USB ethernet
#device         cue             # CATC USB ethernet
#device         kue             # Kawasaki LSI USB ethernet

Сетевые USB-соединения. За отсутствием оных, ничего сказать не могу.

Все функции работы с USB-устройствами могут выполняться также за счет модулей ядра (собственно, последнее время я так и делаю). Только, в отличие от опций файловых систем, автоматически они загружаться не будут, это следует сделать вручную или конфигурированием загрузчика.

# FireWire support
#device         firewire
#device         sbp
#device         fwe

Общая поддержка интерфейса Firewire, соответствующих накопителей и соединений. Увы — за отсуствием таковых, более ничего по этому поводу не знаю. Но подозреваю, что с ними дело обстоит примерно также, как и с USB-устройствами.

Файл конфигурации можно дополнить еще некоторыми опциями, которых нет в GENERIC — их потребуется перенести из LINT. Например, не запрещается встроить в ядро поддержку звука, вписав строку типа

device          pcm

обеспечивающую работу многих карт для PCI-шины (например, SB AWE 137X). Впрочем, делать это не обязательно — поддержка звука прекрасно осуществляется и загружаемыми модулями.

Если в системе имеется более одного диска, можно организовать из них программный RAID-массив — в strip-режиме это даст заметный выигрыш в быстродействии на файловых операциях. Для чего хорошо добавить строку поддержки соответствующего псевдоустройства:

pseudo-device   ccd     4

где цифра соответствует их количеству (псевдоустройств, не дисков — то есть в домашних условиях можно ограничится единицей). Есть и другой способ создания программного RAID’а — механизм Vinum, также поддерживаемый опцией ядра (или модульно), но я им не пользовался и потому за него говорить не буду. Как и за многие другие опции, перечисленные в файле LINT: надеюсь, те, кто имел с ними дело, помогут мне пополнить приведенное описание.

Еще несколько предварительных действий

По завершении конфигурирования ядра можно приступать к сборке его, вместе с «миром» или отдельно. Но сначала нужно позаботится о плацдарме для этого — месте помещения временных продуктов компиляции. Каковым по умолчанию выступает каталог /usr/obj.

В прошлой статье я говорил, что каталог этот неплохо бы вынести на отдельную файловую систему. Которую можно разместить как на дисковом разделе, так и в оперативной памяти (на mfs). Настало время обсудить достоинства и недостатки того и другого решения.

Преимущества монтирования в /usr/obj файловой системы mfs очевидны: скорость сборки ядра и «мира» за счет ликвидации операций записи огромного количества мелких файлов (как неоднократно подчеркивалось, это — отнюдь не сильная сторона файловой системы UFS). Однако столь ли значителен выигрышь времени? Существующие оценки для FreeBSD 5-й ветки (где используется сходная схема сборки ядра и «мира») укладываются в диапазон 10-15%, мои расчеты, мои измерения для DragonFly — ближе к первой цифре. Поскольку весь процесс, как будет показано ниже, занимает около часа — выигрывается 5 минут на каждую пересборку — много это или мало, судите сами.

Второе преимущество — при монтировании в /usr/obj mfs нет необходимости очищать этот каталог от промежуточных продуктов компиляции. Что, кроме экономии дискового пространства (впрочем, столь же грошовой), полезно, если требуется начать пересборку с «чистого листа» (например, в случае регулярного повторения неудачных компиляций). Однако, если сборка ядра и «мира» выполнились успешно — это преимущество становится недостатком — по причинам, которые станут ясными из следующего раздела. Пока же отмечу, что только при сохранении содержимого каталога /usr/obj в дальнейшем можно будет выполнить операции make quickworld и make quickkernel, действительно экономящие время сравнительно с построением ядра и «мира» по полной программе.

Так что в итоге я полностью отказался от использования mfs для монтирования в каталог /usr/obj. Если же мои рассуждения кажутся неубедительными — перед началом сборки не забудьте выполнить такое монтирования (ведь в прошлой статье мы решили не делать этого автоматически при старте системы).

Очевидно, что все описанные ранее действия (начиная с редактирования /etc/make.conf) требовали прав суперпользователя. Не обойтись без них и далее, когда начнется собственно

Процесс сборки

А начинается он с перехода в каталог /usr/src. После чего идет выполнение директив make с указанием различных целей — в зависимости от того, собирается ли «мир» и ядро вместе или по отдельности, впервые или повторно.

Рассмотрим сначала канонический вариант — первую совместную сборку «мира» и ядра. Должен сразу предупредить — все описанное ниже установлено экспериметальным путем и расходится с тем. что дано в документации. Более того, расхождения будут даже с комментариями в /usr/src/Makefile — обычно наиболее достоверном источнике сведений о сборке из текущего дерева исходников. Но уверяю вас — именно описанный мной вариант сборки работает.

В «конспективном изложении» последовательность необходимых команд выглядит так:

$ make buildworld
$ make buildkernel KERNCONF=MYKERNEL
$ make installkernel KERNCONF=MYKERNEL
$ make preupgrade
$ make installworld
$ make upgrade

Обращаю внимание: в отличие от аналогичной процедуры во FreeBSD текущей версии, в промежутках между директивами не требуется ни перехода в однопользовательский режим, ни, тем более, перезагрузки. Последняя выполняется по завершении всего процесса. Да и то, лучше делать это не сразу, а предварительно выполнив некоторые настройки, о которых я расскажу в следующем разделе.

Теперь рассмотрим, что происходит при выполнении каждой директивы. Опять оговариваюсь — я даю свою реконструкцию событий, основанную на чтении сообщений в ходе компиляции, так как соответствующих описаний в документации я не нашел.

Директива make buildworld выполняет т.н. bootstrapping. Буквально это — подъем за шнурки от собственных ботинок; более наглядной будет аналогия с бароном Мюнхгаузеном, вытаскивающим себя из болота за косичку от собственного парика. Сначала посредством наличных (native) gcc, binutils, make и тому подобных инструментов они пересобирают сами себя, с помещением результатов в промежуточный подкаталог внутри /usr/obj/usr/src/. Затем базовая система, включая главные системные библиотеки, пересобирается полностью — уже посредством новоскомпилированных инструментов, также с помещением в промежуточный подкаталог, который и послужит в дальнейшем источником инсталляции (и — не только).

Отступление: не правда ли, что-то знакомое? Совершенно верно, примерно по той же схеме собирается Gentoo Linux, если начать установку со stage1. Да и при сборке Linux from Scratch выполняется та же примерно последовательность действий.

В результате процесс сборки «мира» оказывается весьма длительным — на современных машинах он занимает минут 40-60 (примерно вдвое дольше, чем аналогичная процедура во FreeBSD), а то и еще большее время (в зависимости от числа исключенных, компонентов в /etc/make.conf). Но это — только впервые, при последующих пересборках период ожидания (иногда) можно и сократить.

Следующая директива

$ make buildkernel KERNCONF=MYKERNEL

выполняет компиляцию ядра и его модулей — в качестве последних собираются все функции, в принципе доступные как модули, в том числе и встроенные в ядро. Все это хозяйство опять-таки помещается в промежуточный подкаталог — в /usr/obj/usr/src/sys/MYKERNEL. В качестве значения опции KERNCONF выступает имя созданного ранее файла конфигурации ядра — если не указать его явно, будет просто пересобрано ядро GENERIC.

Важно, что цель buildkernel предполагает, что ядро и модули будут собираться не с помощью нативных компилятора и прочих инструментальных средств, а теми, что были предварительно собраны в ходе выполнения цели buildworld (и помещены в каталог /usr/obj/usr/src/world_i386).

Откуда ядро и модули будут помещены на свои законные места директивой

make installkernel KERNCONF=MYKERNEL

А законные их места в DragonFly — это корень файловой системы (/kernel) и каталог /modules, соответственно. Ранее существовавшие ядро и каталог с модулями при этом будут переименованы в /kernel.old и /modules.old. Спешить с их удалением не след — не ровен час, еще понадобятся (о чем — в заключительном разделе статьи).

Следующая директива

$ make preupgrade

не освещена в документации, но, тем не менее, обязательна. Она добавляет виртуальных пользователей и группы, к которым принадлежат общесистемные утилиты, которые будут установлены на ледующем этапе — директивой

$ make installworld

Цель ее очень проста — перенести новособранные файлы базовой системы из каталога /usr/obj/usr/src/world_i386 в соответствующие ветви корневой файловой системы. После чего остается последний штрих — выполнение директивы

$ make upgrade

которая, в соответствие со своим названием, обеспечивает обновление настроечных файлов в каталоге /etc (старые, модифицированные пользователем, конфиги при этом не затираются).

Теперь остается только выполнить описанные далее (и, возможно, не обязательные) настроечные мероприятия — и перезагрузиться. Результатом чего будет быстрая, стабильная и компактная система. Сравнимая по визуальному быстродействию с лучшими представителями FreeBSD 4-й ветки (и заведомо превосходящая пятую). Работающая без сбоев, глюков и аномалий. Занимающая 200-300 Мбайт дискового пространства. И являющая, таким образом, надежную базу для наращивания приложениями.

Правда, повторюсь еще раз: такой, неизменно превосходный, результат будет достигнут только при выполнении следующих условий:

  • установки с дистрибутива LATEST-SRABLE;
  • получения через cvs исходников стабильной же ветки;
  • сборки ядра и «мира» компилятором gcc-2.95 со «щадящими» флагами (-march=i686 -O1).

В любом ином случае — как говорится, «фирма веников не вяжет, но гарантий не дает»:-).

Возможны варианты

Тем не менее, не исключаю возможности того, что выполнять процедуру построения ядра и «мира» по полной программе покажется нецелесообразным. А ядро пересобрать хочется — ради той же графической консоли, например. Что делать?

Все документы, существующие на данный момент, дружно указывают выполнить ту же директиву make buildkernel, что и в предыдущем случае. И все они не правы. Потому что в свежеинсталлированнй системе ответом на команду

$ make buildkernel KERNCONF=MYKERNEL

будет сообщение об ошибке и предложение сначала выполнить операцию make buildworld. Оно и понятно — как было сказано выше, цель buildkernel предполагает наличие в каталоге /usr/obj/usr/src/world_i386 новособранной системы. И потому приходится обратиться к комментариям в файле /usr/src/Makefile — благо он содержит исчерпывающие указания на сей счет. Так вот, из этого авторитетного источника следует, что для сборки одного только ядра, отдельно от всего остального «мира», должна использоваться команда

$ make nativekernel KERNCONF=MYKERNEL

После чего с чистой совестью можно отправляеться курить — на современных машинах процесс будет длиться минут 10. По завершении чего свежесобранное ядро вместе с принадлежащими ему модулями инсталлируются той же командой

$ make installkernel KERNCONF=MYKERNEL

Если же ядро и «мир» собирались ранее, и содержимое каталога /usr/obj с тех пор сохранилось — команда make buildkernel вполне допустима. Более того, в этом случае есть способ сократить и время выполнения полного цикла перестройки системы. Для этого предназначена последовательность директив

$ make guickworld
$ make quickkernel KERNCONF=MYKERNEL

с последующей инсталляцией и upgrade. При этом пропускается стадия bootstrapping’а при сборке «мира». Однако проходит этот способ только в том случае, если исходники системы в промежутке между сборками не обновлялись.

Что дальше

А дальше остается только радоваться жизни (и новому ядру). Правда, для полного счастья нужно еще научиться обращаться с модулями ядра — ведь многие функции в описанной выше конфигурации доступны именно через них.

Некоторые модули никакого особого обращения не требуют. Так, модули поддержки чуждых файловых систем (MSDOS, iso9660, ext2fs) загружаются автоматически при их монтировании. В чем легко убедиться командой kldstat(она предназначена для просмотра списка загруженных модулей) до

$ kldstat                                                                     16:43 ttyv0
Id Refs Address    Size     Name
1    6 0xc0100000 2e25fc   kernel
2    1 0xc0417000 58718    acpi.ko

и после

$ kldstat                                                                     16:43 ttyv0
Id Refs Address    Size     Name
1    6 0xc0100000 2e25fc   kernel
2    1 0xc0417000 58718    acpi.ko
3    1 0xd7871000 9000     cd9660.ko

монтирования, например, CD-диска. Правда, по размонтировании файловой системы такой модуль столь же автоматически же не выгружается. Но это (при необходимости) легко проделать командой

$ kldunload cd9660

удаляющей ранее загруженные (любым способом) модули из памяти.

Другие модули (например, USB-устройств и поддержки звуковых карт) такой роскоши не подразумевают — при потребности их следует загрузить руками. Это делается командой kldload имя_модуля. Например, последовательностью

$ kldload snd_pcm
$ kldload snd_ich

Мы обеспечиваем работу чипсетного аудио от Intel ICH#.

Понятно, что такой способ не приемлем для модуля поддержки, например, USB-мыши. Однако автоматическую загрузку его при старте можно обеспечить настройкой загрузчика системы. Подробный разговор о нем впереди, пока же лишь дам краткий рецепт.

Загружаемые по умолчанию при старте системы модули описываются в файле /boot/defaults/loadr.conf, и модулей поддержки USB-устройств в нем не обнаруживается (так как эти функции встроены в ядро GENERIC). Сам по себе он редактированию не подлежит. Однако можно создать свой конфигурационный файл — /boot/loadr.conf и прописать в нем то, что нужно. В частности, модули, необходимые для работы USB-мыши, включают в себя:

usb_load="YES"
ugen_load="YES"
ums_load="YES"

Очевидно, что эту процедуру можно проделать сразу после сборки «мира» и ядра, до перезагрузки (или даже во время компиляции). В этом случае после рестарта мы получаем систему с функционирующей консольной мышью.

Ссылки

Получить исходники системы через cvs можно с ftp-сервера проекта (ftp://ftp.dragonflybsd.org/) или одного из его зеркал (список). В виде тарбалла дерево исходников доступно здесь: ftp://ftp.fortunaty.net/DragonFly/.