---
description: 'Эта глава рассказывает о настройке ядра FreeBSD. Когда стоит собирать собственное ядро, как провести инвентаризацию оборудования, как настроить конфигурационный файл ядра и т. д.'
next: books/handbook/printing
params:
  path: /books/handbook/kernelconfig/
part: 'Часть II. Стандартные задачи'
prev: books/handbook/multimedia
showBookMenu: 'true'
tags: ["configuring", "kernel", "custom kernel", "hardware requirements", "pciconf"]
title: 'Глава 10. Настройка ядра FreeBSD'
weight: 13
---

[[kernelconfig]]
= Настройка ядра FreeBSD
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 10
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/kernelconfig/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[kernelconfig-synopsis]]
== Обзор

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

Прочтите эту главу, чтобы узнать:

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

Все команды, приведённые в примерах этой главы, должны выполняться от имени пользователя `root`.

[[kernelconfig-custom-kernel]]
== Зачем собирать собственное ядро?

Традиционно FreeBSD использовала монолитное ядро. Ядро представляло собой одну большую программу, поддерживало фиксированный список устройств, и для изменения его поведения необходимо было скомпилировать новое ядро, а затем перезагрузиться в него.

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

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

Сборка собственного ядра часто является своего рода обрядом посвящения для опытных пользователей BSD. Этот процесс, хотя и отнимает много времени, может принести пользу системе FreeBSD. В отличие от ядра [.filename]#GENERIC#, которое должно поддерживать широкий спектр оборудования, собственное ядро можно сократить до поддержки только аппаратного обеспечения данного компьютера. Это даёт ряд преимуществ, таких как:

* Более быстрая загрузка. Поскольку ядро будет проверять только оборудование, установленное в системе, время загрузки системы может сократиться.
* Снижение использования памяти. Собственное ядро часто потребляет меньше памяти, чем ядро [.filename]#GENERIC#, за счёт исключения неиспользуемых функций и драйверов устройств. Это важно, поскольку код ядра постоянно находится в физической памяти, не позволяя использовать эту память приложениям. По этой причине собственное ядро полезно на системах с небольшим объёмом оперативной памяти.
* Дополнительная поддержка оборудования. Собственное ядро может добавить поддержку устройств, которые отсутствуют в ядре [.filename]#GENERIC#.

[WARNING]
====
При сборке собственного ядра важно учитывать, что нестандартные конфигурации тестируются менее тщательно, чем конфигурация GENERIC. Хотя настройка ядра может дать определённые преимущества, она также увеличивает риск возникновения проблем при сборке или во время работы. Пользовательские конфигурации ядра рекомендуются только опытным пользователям, у которых есть веская причина для внесения изменений и которые готовы при необходимости участвовать в процессе отладки.
====

Прежде чем собирать собственное ядро, стоит подумать о причине этого. Если требуется поддержка определённого оборудования, она может уже существовать в виде модуля.

Модули ядра находятся в [.filename]#/boot/kernel# и могут быть динамически загружены в работающее ядро с помощью man:kldload[8]. Большинство драйверов ядра имеют загружаемый модуль и страницу руководства. Например, драйвер беспроводной сети man:ath[4] содержит следующую информацию на своей странице руководства:

[source, shell, subs="macros"]
....
В качестве альтернативы, для загрузки драйвера в виде модуля при старте системы,
поместите следующую строку в man:loader.conf[5]:

    if_ath_load="YES"
....

Добавление `if_ath_load="YES"` в [.filename]#/boot/loader.conf# позволит динамически загрузить этот модуль во время загрузки системы.

В некоторых случаях связанный модуль отсутствует в [.filename]#/boot/kernel#. Это в основном относится к определённым подсистемам.

[[kernelconfig-devices]]
== Поиск информации об оборудовании системы

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

[NOTE]
====
Некоторые версии Microsoft(R) Windows(R) имеют значок "Система", который можно использовать для доступа к диспетчеру устройств.
====

Если FreeBSD — единственная установленная операционная система, используйте man:dmesg[8] для определения оборудования, обнаруженного и перечисленного во время загрузки. Большинство драйверов устройств в FreeBSD имеют справочную страницу, в которой перечислено поддерживаемое оборудование. Например, следующие строки указывают, что драйвер man:psm[4] обнаружил мышь:

[source, shell]
....
psm0: <PS/2 Mouse> irq 12 on atkbdc0
psm0: [GIANT-LOCKED]
psm0: [ITHREAD]
psm0: model Generic PS/2 mouse, device ID 0
....

Поскольку данное оборудование существует, этот драйвер не следует удалять из файла конфигурации собственного ядра.

Если вывод команды `dmesg` не отображает результаты загрузочного probing, вместо этого прочитайте содержимое файла [.filename]#/var/run/dmesg.boot#.

Еще один инструмент для поиска оборудования — это man:pciconf[8], который предоставляет более подробный вывод. Например:

[source, shell]
....
% pciconf -lv
ath0@pci0:3:0:0:        class=0x020000 card=0x058a1014 chip=0x1014168c rev=0x01 hdr=0x00
    vendor     = 'Atheros Communications Inc.'
    device     = 'AR5212 Atheros AR5212 802.11abg wireless'
    class      = network
    subclass   = ethernet
....

Этот вывод показывает, что драйвер [.filename]#ath# обнаружил беспроводное Ethernet-устройство.

Флаг `-k` утилиты man:man[1] может быть полезен для получения информации. Например, с его помощью можно вывести список страниц руководства, содержащих определённое название или марку устройства:

[source, shell]
....
# man -k Atheros
ath(4)                   - Atheros IEEE 802.11 wireless network driver
ath_hal(4)               - Atheros Hardware Access Layer (HAL)
....

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

[[kernelconfig-config]]
== Файл конфигурации

Для создания файла конфигурации собственного ядра и сборки кастомного ядра необходимо сначала установить полное дерево исходных кодов FreeBSD.

Если [.filename]#/usr/src/# не существует или пуст, исходный код не установлен. Исходный код можно установить с помощью Git, следуя инструкциям в crossref:mirrors[git,“Использование Git”].

После установки исходного кода ознакомьтесь с содержимым каталога [.filename]#/usr/src/sys#. Этот каталог содержит несколько подкаталогов, включая те, которые соответствуют следующим поддерживаемым архитектурам: [.filename]#amd64#, [.filename]#i386#, [.filename]#powerpc# и [.filename]#sparc64#. Всё содержимое каталога конкретной архитектуры относится только к этой архитектуре, а остальной код является машинонезависимым и общим для всех платформ. Каждая поддерживаемая архитектура имеет подкаталог [.filename]#conf#, который содержит файл конфигурации ядра [.filename]#GENERIC# для данной архитектуры.

Не вносите изменения в файл [.filename]#GENERIC#. Вместо этого скопируйте его под другим именем и редактируйте копию. По сложившейся практике имя файла должно состоять из заглавных букв. Если вы обслуживаете несколько машин FreeBSD с разным оборудованием, разумно назвать файл по имени хоста соответствующей машины. В следующем примере создаётся копия файла конфигурации [.filename]#GENERIC# для архитектуры `amd64` с именем [.filename]#MYKERNEL#:

[source, shell]
....
# cd /usr/src/sys/amd64/conf
# cp GENERIC MYKERNEL
....

[.filename]#MYKERNEL# теперь можно настроить с помощью любого текстового редактора, поддерживающего `ASCII`. Редактор по умолчанию — vi, но для новичков также установлен более простой редактор под названием ee.

Формат файла конфигурации ядра прост. Каждая строка содержит ключевое слово, представляющее устройство или подсистему, аргумент и краткое описание. Любой текст после `+#+` считается комментарием и игнорируется. Чтобы удалить поддержку устройства или подсистемы в ядре, поставьте `+#+` в начале строки, соответствующей этому устройству или подсистеме. Не добавляйте и не удаляйте `+#+` для строк, которые не понятны.

[WARNING]
====
Легко удалить поддержку устройства или опции и получить нерабочее ядро. Например, если драйвер man:ata[4] удалён из конфигурационного файла ядра, система, использующая драйверы дисков `ATA`, может не загрузиться. Если сомневаетесь — оставьте поддержку в ядре.
====

В дополнение к кратким описаниям, приведённым в этом файле, дополнительные описания содержатся в [.filename]#NOTES#, которые можно найти в том же каталоге, что и [.filename]#GENERIC# для данной архитектуры. Для архитектурно-независимых параметров обратитесь к [.filename]#/usr/src/sys/conf/NOTES#.

[TIP]
====
После завершения настройки конфигурационного файла ядра сохраните резервную копию в расположении за пределами [.filename]#/usr/src#.

Или можно сохранить файл конфигурации ядра в другом месте и создать символическую ссылку на него:

[source, shell]
....
# cd /usr/src/sys/amd64/conf
# mkdir /root/kernels
# cp GENERIC /root/kernels/MYKERNEL
# ln -s /root/kernels/MYKERNEL
....

====

В конфигурационных файлах доступна директива `include`, которая позволяет включать содержимое другого конфигурационного файла в текущий. Это упрощает поддержку небольших изменений относительно существующего файла. Если требуется лишь несколько дополнительных параметров или драйверов, можно сохранять разницу относительно [.filename]#GENERIC#, как показано в примере:

[.programlisting]
....
include GENERIC
ident MYKERNEL

options         IPFIREWALL
options         DUMMYNET
options         IPFIREWALL_DEFAULT_TO_ACCEPT
options         IPDIVERT
....

При использовании этого метода локальный конфигурационный файл отражает локальные отличия от ядра [.filename]#GENERIC#. При выполнении обновлений новые функции, добавленные в [.filename]#GENERIC#, также будут добавлены в локальное ядро, если они не запрещены явно с помощью `nooptions` или `nodevice`. Полный список директив конфигурации и их описания можно найти в man:config[5].

[NOTE]
====
Чтобы создать файл, содержащий все доступные параметры, выполните следующую команду от имени `root`:

[source, shell]
....
# cd /usr/src/sys/arch/conf && make LINT
....

====

[[kernelconfig-building]]
== Сборка и установка собственного ядра

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

[.procedure]
====
*Процедура: Сборка ядра*

. Перейдите в этот каталог:
+
[source, shell]
....
# cd /usr/src
....
+
. Соберите новое ядро, указав имя файла конфигурации собственного ядра:
+
[source, shell]
....
# make buildkernel KERNCONF=MYKERNEL
....
+
. Установите новое ядро, связанное с указанным файлом конфигурации ядра. Эта команда скопирует новое ядро в [.filename]#/boot/kernel/kernel#, а старое ядро сохранит в [.filename]#/boot/kernel.old/kernel#:
+
[source, shell]
....
# make installkernel KERNCONF=MYKERNEL
....
+
. Выключите систему и перезагрузитесь с новым ядром. Если возникнут проблемы, обратитесь к разделу crossref:kernelconfig[kernelconfig-noboot, Ядро не загружается].
====

По умолчанию при компиляции собственного ядра все модули ядра пересобираются. Чтобы ускорить обновление ядра или собрать только необходимые модули, отредактируйте [.filename]#/etc/make.conf# перед началом сборки ядра.

Например, эта переменная задаёт список модулей для сборки вместо использования значения по умолчанию (сборка всех модулей):

[.programlisting]
....
MODULES_OVERRIDE = linux acpi
....

Или эта переменная указывает, какие модули исключить из процесса сборки:

[.programlisting]
....
WITHOUT_MODULES = linux acpi sound
....

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

[.programlisting]
....
NO_MODULES = yes
....

Фреймворк портов включает драйверы и другие модули, которые зависят от интерфейсов ядра, например package:graphics/drm-kmod[] или package:emulators/virtualbox-ose-kmod[]. С помощью переменной `PORTS_MODULES` при каждой сборке ядра порты, содержащие модули ядра, пересобираются с учётом обновлённых исходников. Это гарантирует, что модуль ядра остаётся согласованным с самим ядром. Для максимальной совместимости дерево исходников ядра и дерево портов следует обновлять одновременно. Переменную `PORTS_MODULES` можно добавить в [.filename]#/etc/make.conf#, чтобы все собираемые вами ядра также пересобирали эти модули.

[.programlisting]
....
PORTS_MODULES = drm-kmod virtualbox-ose-kmod
....

Доступны дополнительные переменные. Подробности смотрите в man:make.conf[5].

[[kernelconfig-trouble]]
== Если что-то пойдет не так

Существует четыре типа проблем, которые могут возникнуть при сборке собственного ядра:

`config` завершается с ошибкой::
Если `config` завершается с ошибкой, он выводит номер строки, содержащей ошибку. Например, при получении следующего сообщения убедитесь, что строка 17 введена правильно, сравнив её с [.filename]#GENERIC# или [.filename]#NOTES#:
+
[source, shell]
....
config: line 17: syntax error
....

`make` завершается с ошибкой::
Если `make` завершается с ошибкой, обычно это связано с ошибкой в файле конфигурации ядра, которую `config` не смог обнаружить. Проверьте конфигурацию, и если проблема не очевидна, отправьте письмо в список рассылки {freebsd-questions}, приложив файл конфигурации ядра.

[[kernelconfig-noboot]]
Ядро не загружается::
Если новый ядро не загружается или не распознаёт устройства, не паникуйте! К счастью, в FreeBSD есть отличный механизм восстановления после проблем с несовместимыми ядрами. Просто выберите ядро для загрузки в загрузчике FreeBSD. Это можно сделать при появлении меню загрузки системы, выбрав опцию «Escape to a loader prompt». В командной строке введите `boot _kernel.old_` или имя любого другого ядра, которое заведомо загружается правильно.
+
После загрузки с исправным ядром проверьте конфигурационный файл и попробуйте собрать его снова. Полезным ресурсом может быть [.filename]#/var/log/messages#, где записываются сообщения ядра при каждой успешной загрузке. Также man:dmesg[8] выведет сообщения ядра текущей загрузки.
+
[NOTE]
====
При устранении неполадок ядра обязательно сохраняйте копию работоспособного ядра, например, [.filename]#GENERIC#. Это важно, потому что при каждой установке нового ядра файл [.filename]#kernel.old# перезаписывается последним установленным ядром, которое может быть или не быть загружаемым. Как можно скорее переместите рабочее ядро, переименовав каталог, содержащий исправное ядро:

[source, shell]
....
# mv /boot/kernel /boot/kernel.bad
# mv /boot/kernel.good /boot/kernel
....

====

Ядро работает, но man:ps[1] — нет::
Если версия ядра отличается от той, с которой собраны системные утилиты, например, при установке ядра, собранного из исходников -CURRENT, на систему -RELEASE, многие команды для просмотра состояния системы, такие как man:ps[1] и man:vmstat[8], не будут работать. Чтобы исправить это, crossref:cutting-edge[makeworld,пересоберите и установите world], собранный из той же версии исходного дерева, что и ядро. Никогда не рекомендуется использовать версию ядра, отличную от остальной операционной системы.
