FreeBSD: ядро и его конфигурирование

Алексей Федорчук
[email protected]

Конфигурирование и перекомпиляция ядра - практически непременный атрибут индивидуальной настройки этой системы.

При первичной установке системы инсталлируется некое прекомпилированное ядро, рассчитанное на поддержку максимально широкого круга наиболее распространенного железа (в частности, немерянного количества SCSI-адаптеров и сетевых карт). Конфигурация такого умолчального ядра описывается в файле /usr/src/sys/i386/conf/GENERIC, почему его часто называют ядром GENERIC. Задача пользователя - модифицировать этот файл таким образом, чтобы включить все необходимые ему опции, исключив заведомо ненужные.

Список всех доступных опций ядра FreeBSD версий 5-й ветви, вместе с более или менее внятными комментариями, находится в файле /usr/src/sys/conf/NOTES. В отличие от файла LINT ветви 4 и ранее, он в принципе не предназначен для компиляции на его основе работоспособного ядра, а служит лишь для описания возможностей конфигурирования.

Многие опции ядра не обязательно жестко встраивать в него - для них возможна модульная поддержка. Все доступные модули ядра во FreeBSD по умолчанию собираются автоматически и устанавливаются в каталог /boot/kernel, в котором находится и файл загружаемого образа ядра (/boot/kernel/kernel). Нужно заметить, что в 5-й ветви в виде модулей изначально, сразу же после установки системы, доступна поддержка множества опций, которые ранее требовали непременной пересборки ядра (например, звука). И потому ныне не обязательно бросаться конфигурировать ядро сразу же по завершении инсталляции. Однако и откладывать этот процесс также не стоит.

Пересборка ядра начинается с установки его исходников. Это можно сделать на стадии первичной установки, выбрав в меню Distributions -> Custom -> src пункты include (здесь находятся заголовочные файлы) и sys (собственно исходники ядра). Ту же процедуру можно проделать и впоследствии - через тот же sysinstall или вручную, подмонтировав дистрибутивный CD и выполнив последовательность команд:

$ cd /usr/src
$ cat /cdrom/src/ssys.?? | tar xzvf -
$ tar xzvf /cdrom/src/sinclude.aa

Во второй строке обращаю внимание на форму шаблона - конкатенировать следует только файлы вида ssys.aa и так далее (ясно, что inf-файл здесь абсолютно не нужен) и на символ -, предписывающий использовать в качестве аргумента команды tar вывод команды cat.

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

В любом случае после установки исходников в каталоге /usr/src можно будет увидеть подкаталоги sys и include.

В настоящее время существует две схемы конфигурирования и сборки ядра - новая, принятая в версиях 5-й вертки, и старая, унаследованная от веток 3 и 4 (хотя версии 4-й ветки вполне можно конфигурировать и по новой схеме). Старая схема многократно описывалась (например, Иваном Паскалем), и потому ниже основное внимание будет уделено новой. Однако и старая схема не потеряла своей актуальности и в некоторых случаях может быть целесообразна. Почему я скажу пару слов о ее отличиях.

Новая схема по последовательности действий совпадает с пересборкой "мира" (процедура make world). Она начинается с перехода в корень дерева исходников системы вообще

$ cd /usr/src

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

Собственно конфигурирование ядра во FreeBSD, в отличие от Linux, выполняется не с помощью меню-ориентированных средств, а прямым редактированием конфигурационного файла. Создавать оный с нуля не обязательно:-), за основу вполне можно взять файл sys/i386/GENERIC (все пути далее указываются, исходя из нахождения в каталоге /usr/src. Дабы не покорежить его безвозвратно, его следует скопировать в файл с другим именем:

$ cp sys/i386/GENERIC sys/i386/MYKERNEL

Имя конфигурационного файла может быть любым, и верхний регистр - просто дань традиции. Однако лучше давать своим ядрам осмысленные имена, например, по имени хоста или пользователя, с добавлением порядкового номера сборки. Я именую их так - AL01, ALV02 и т.д.

Теперь открываем скопированный файл в любимом текстовом редакторе

$ joe sys/i386/MYKERNEL

Параллельно, на другой виртуальной консоли, открываем эталонный файл NOTES:

$ less sys/conf/NOTES

Кроме этого, полезно еще на следующей консоли вывести вывод команды dmesg для сверки с реально имеющимся оборудованием.

А теперь - самое сложное: вычеркивание (желательно простановкой комментариев - я делаю это в виде ##, чтобы отличить свои ремарки от изначально имевшихся в GENERIC) ненужных опций из файла MYKERNEL и перетаскивание нужных - из файла NOTES.

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

Главное же - в том, что последовательность опций в GENERIC (которую наследует MYKERNEL) и в NOTES весьма разная. Если последний файл довольно логично структурирован разбиением на секции, то в первом опции идут общим списком (и логика их последовательности лично для меня недоступна).

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

$ make buildkernel KERNCONF=MYKERNEL

после чего в течении некоторого времени будет выполняться собственно сборка ядра. В скобках замечу, что если опустить параметр KERNCONF=MYKERNEL, то пересборке будет подвергаться ядро GENERIC (не так уж бессмысленно, как может показаться: такая процедура иногда требуется при апдейтинге исходников системы).

При сборке ядра по новой схеме все промежуточные продукты компиляции будут помещаться в подкаталоги каталога /usr/obj. И если в эту точку предварительно подмонтировать виртуальную файловую систему mfs, можно выиграть пару минут по скорости компиляции:-). Главное же - в этом случае без всяких дополнительных действий всегда гарантируется сборка ядра с "чистого листа", что не может не радовать...

Вторым же действием

$ make installkernel KERNCONF=MYKERNEL

осуществляется инсталляция ядра. То есть, попросту говоря, копирование файла его образа (вместе с вновь собранными модулями) из /usr/obj/src/sys... в каталог /boot/kernel. Предварительно каталог, содержащий старое ядро и его модули, переименовывается в /boot/kernel.old. Отсюда старое ядро при необходимости может быть загружено (например, если новое оказалось неработоспособным).

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

Старая схема сборки требует некоторых дополнительных телодвижений. Для начала, конфигурирование целесообразно выполнять непосредственно из каталога /usr/src/sys/i386/conf. По завершении его требуется команда

$ config MYKERNEL

которой будет, в частности, создан каталог /usr/src/sys/i386/compile/MYKERNEL - в нем-то и будут происходить дальнейшие действа. Первое - переход:

$ cd ../compile/MYKERNEL

Второе - построение зависимостей:

$ make depend

Третье - собственно сборка:

$ make all

Хотя можно ограничиться и просто командой make. Четвертое - инсталляция:

$ make install

которая точно также создаст каталог /boot/kernel.old со старым ядром и каталог /boot/kernel - с новым (включая модули). Далее - аналогично, перезагрузка и радости от новых функций.

Отличие старой и новой схем - не только в командах. По старой схеме, промежуточные продукты компиляции располагаются в каталоге /usr/src/sys/i386/compile/MYKERNEL, а не в /usr/obj, каковой сделать отдельной файловой системой несколько сложнее. В итоге после нескольких последовательных пересборок ядра можно получить несколько каталогов вида MYKERNEL01, MYKERNEL02 и т.д., абсолютно зря занимающих место (повторно они использоваться не будут никогда).

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

Продолжение следует