Глава 28. Компиляция ядра

Русский перевод: Вадим Лопатюк

Содержание

28.1. Установка исходных текстов ядра
28.2. Требования и процедура
28.3. Создание конфигурационного файла ядра
28.4. Ручное конфигурирование ядра
28.5. Генерация зависимостей и ручная компиляция
28.6. Использование build.sh
28.7. Если что-то не так

У большинства пользователей NetBSD раньше или позже возникает желание скомпилировать собственное ядро, что предоставит Вам следующие плюсы:

  • Вы можете значительно уменьшить размер ядра и, тем самым, занимаемую память (например, с 2.5 МБ до 1.2 МВ). В NetBSD 2.0, компиляция собственного ядра уменьшает размер с 7.5 МБ до 3.5 МБ.
  • Вы можете улучшить производительность.
  • Вы можете более тонко настроить систему.
  • Вы можете решить проблемы определения/конфликтов периферийных устройств.
  • Вы можете изменить некоторые опции (например, раскладку клавиатуры, смещение часов BIOS, …)
  • Вы можете получить более глубокие познания о системе.

28.1. Установка исходных текстов ядра

Вы можете получить исходные тексты ядра с анонимного CVS (см. Глава 26, Obtaining sources by CVS), или из архива syssrc.tgz расположенного в каталоге source/sets/ используемой Вами версии системы. Если Вы используете второй способ, Вы можете распаковать архив из корня файловой системы:

# cd /
# tar zxf /path/to/syssrc.tgz

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

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

28.2. Требования и процедура

Для компиляции Вам необходимо иметь установленный набор компиляторов (comp.tgz).

Главные шаги для компиляции:

  1. Создание/изменение файла конфигурации ядра
  2. Конфигурирование ядра
  3. Создание зависимостей
  4. Компиляция ядра
  5. Установка ядра

Эти шаги могут выполняться как вручную, так и с использованием новой команды build.sh, которая описана в главе Глава 27, Использование утилиты build.sh. Данная же глава сначала объясняет как собрать собственное ядро вручную, а затем описывает, как можно сделать тоже самое с помощью build.sh.

28.3. Создание конфигурационного файла ядра

Каталоги, описанные в данном разделе характерны для архитектуры i386. Пользователям других архитектур необходимо заменить названия зависящих каталогов, см. список в подкаталоге src/sys/arch.

Файл конфигурации ядра определяет типы, номера и характеристики поддерживаемых ядром устройств, так же как и множество опций конфигурации ядра. Для архитектуры i386, файлы конфигурации ядра лежат в каталоге /usr/src/sys/arch/i386/conf.

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

$ cd /usr/src/sys/arch/i386/conf/
$ ls
CARDBUS                 GENERIC_PS2TINY         NET4501
CVS                     GENERIC_TINY            SWINGER
DELPHI                  GENERIC_VERIEXEC        SWINGER.MP
DISKLESS                INSTALL                 VIRTUALPC
GENERIC                 INSTALL.MP              files.i386
GENERIC.FAST_IPSEC      INSTALL_LAPTOP          kern.ldscript
GENERIC.MP              INSTALL_PS2             kern.ldscript.4MB
GENERIC.MPDEBUG         INSTALL_SMALL           largepages.inc
GENERIC.local           INSTALL_TINY            majors.i386
GENERIC_DIAGNOSTIC      IOPENER                 std.i386
GENERIC_ISDN            LAMB
GENERIC_LAPTOP          Makefile.i386

Самый простой способ создания нового файла — это скопировать и отредактировать существующий. Обычно самым удачным выбором для большинства платформ становится конфигурация GENERIC, так как содержит большинство драйверов и опций. Более детальное описание опций вы найдете на странице помощи options(4). Так, стандартной процедурой будет:

$ cp GENERIC MYKERNEL
$ vi MYKERNEL

Модификация файла конфигурации ядра в основном состоит из трех операций:

  1. подключение/отключение поддержки аппаратных устройств в ядре (например, поддержка SCSI может быть удалена, если в ней нет необходимости.)
  2. подключение/отключение поддержки дополнительных опций ядра (например, подключение поддержки клиента NFS, подключение совместимости с Linux, …)
  3. настройка параметров ядра.

Строки, начинающиеся с «#», являются комментариями; стоки отключаются комментированием и подключаются удалением символа комментария. Лучше комментировать строки, чем удалять их, так как всегда остается возможность раскомментировать их позже.

Вывод команды dmesg(8) может быть использован для определения строк, которые можно отключить. Для каждой строки содержащей:

XXX at YYY

оба XXX и YYY должны быть активны в файле конфигурации ядра. Вам, возможно, понадобится поэкспериментировать, пока Вы не достигните минимальной конфигурации, но для настольных систем без SCSI и PCMCIA Вы сможете уменьшить размер ядра наполовину.

Вам также необходимо изучить опции в конфигурационном файле и отключить те, что Вам не нужны. Каждая опция имеет короткий комментарий ее описывающий, которого, обычно, достаточно для понимания выполняемых опцией функций. Множество опций имеет более длинное и детальное описание на странице помощи options(4). Пока Вы здесь, Вам необходимо верно назначить опцию для локального времени часов CMOS. Например:

options RTC_OFFSET=-60

Perl сценарий adjustkernel, доступный через pkgsrc, анализирует вывод dmesg(8) и автоматически генерирует минимальный конфигурационный файл. Установка пакетов подробно описана в главе Глава 30, Коллекция пакетов, но быстро установить adjustkernel можно следующим образом:

$ cd /usr/pkgsrc/sysutils/adjustkernel
$ make install

Теперь Вы можете запустить сценарий:

$ cd /usr/src/sys/arch/i386/conf
$ adjustkernel GENERIC > MYKERNEL

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

28.4. Ручное конфигурирование ядра

Когда Вы завершите редактирование конфигурационного файла ядра (который мы назвали MYKERNEL), Вам необходимо выполнить следующую команду:

$ config MYKERNEL

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

28.5. Генерация зависимостей и ручная компиляция

Генерация зависимостей и компиляция ядра производятся следующими командами:

$ cd ../compile/MYKERNEL
$ make depend
$ make

Может случиться, что компиляция остановится по ошибке, что может произойти из-за множества причин, но самый распространенный случай — это ошибка в конфигурационном файле, которую не выявила программа config(8). Иногда ошибка происходит из-за аппаратных проблем (часто это ошибки чипов RAM): компиляция является большим стрессом для системы, чем большинство других операций. Еще одна типичная ошибка: активная опция B требует опции A, которая не активна. Полная компиляция ядра может занять от нескольких минут до нескольких часов, в зависимости от аппаратного обеспечения.

Вывод команды make помещается в файл netbsd в каталоге компиляции: этот файл должен быть скопирован в корневой каталог, после сохранения предыдущей версии.

# mv /netbsd /netbsd.old
# mv netbsd /

Настройка может значительно уменьшить размеры ядра. В следующем примере netbsd.old это установленное ядро,а netbsd это новое ядро.

-rwxr-xr-x  3 root  wheel  3523098 Dec 10 00:13 /netbsd
-rwxr-xr-x  3 root  wheel  3523098 Dec 10 00:13 /netbsd.old

Новое ядро активируется после перезагрузки:

# shutdown -r now

28.6. Использование build.sh

После создания и, возможно, редактирования конфигурационного файла ядра, выполняемые вручную действия по конфигурированию ядра, генерации зависимостей и компиляции могут быть выполнены с использованием сценария src/build.sh, все сразу выполняется одной командой:

$ cd /usr/src
$ ./build.sh kernel=MYKERNEL

Это выполнит все вышеуказанные шаги, за одним маленьким различием: перед компиляцией все старые объектные файлы будут удалены, чтобы начать новую сборку. Обычно это слишком и лучше оставить старые файлы и пересобрать лишь те зависимости, которые были изменены. Чтобы это сделать добавьте опцию -u к build.sh:

$ cd /usr/src
$ ./build.sh -u kernel=MYKERNEL

После окончания работы build.sh выведет информацию о том, где можно найти новое ядро. Это тот же путь, что и описанный выше в разделе Раздел 28.5, «Генерация зависимостей и ручная компиляция».

28.7. Если что-то не так

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

  • Перезагрузите машину
  • Нажмите «пробел» во время загрузочного 5-ти секундного обратного отсчета
    boot:
  • Наберите
    > boot netbsd.old -s
  • Теперь выполните следующие команды, для восстановления предыдущей версии ядра:
    # fsck /
    # mount /
    # mv netbsd.old netbsd
    # reboot

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