Kernel (Русский)/Traditional compilation (Русский)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Состояние перевода: На этой странице представлен перевод статьи Kernel/Traditional compilation. Дата последней синхронизации: 10 июля 2021. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

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

Подготовка

Для подготовки ядра не требуется ни root-аккаунт, ни root-привилегии (например, через sudo).

Установка пакетов

Установите группу пакетов base-devel с набором необходимых инструментов вроде make и gcc. Также рекомендуется установить пакеты, указанные в стандартном PKGBUILD ядра Arch Linux: xmlto, kmod, inetutils, bc, libelf, git, cpio, perl, tar, xz.

Создание каталога сборки

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

$ mkdir ~/kernelbuild

Загрузка исходников

Важно: Для systemd необходимо ядро не старше версии 3.12 (4.2 и выше, если требуется поддержка единой иерархии контрольных групп. Подробнее см. /usr/share/doc/systemd/README.

Выберите версию ядра и загрузите файлы с исходным кодом с сайта https://www.kernel.org. Они будут иметь вид сжатого tar-архива (суффикс tar.xz).

Загрузить можно просто через браузер (правый клик по ссылке с tar.xz и выбрать Save Link As...) или любой другой программой, с графическим интерфейсом или интерфейсом командной строки, работающей через HTTP, TFTP, Rsync или Git.

Примечание: Стоит также проверить PGP-подпись загруженного архива. Этим вы проверите его подлинность и поможете сформировать сеть доверия. Подробнее см. kernel.org/signature.

Например, так выглядит загрузка ядра версии 4.8.6 в каталог ~/kernelbuild утилитой wget:

$ cd ~/kernelbuild
$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.8.6.tar.xz

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

$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.8.6.tar.sign
$ gpg --list-packets linux-4.8.6.tar.sign
$ gpg --recv-keys <отпечаток_из_предыдущего_шага>

Обратите внимание, что подпись создаётся для tar-архива (суффикс .tar), а не для сжатого файла .tar.xz, который был загружен. Необходимо выполнить декомпрессию, но без извлечения архива. Для этого потребуется xz:

$ unxz linux-4.8.6.tar.xz
$ gpg --verify linux-4.8.6.tar.sign linux-4.8.6.tar

К последующим шагам нельзя переходить, если вы не получили вывод в виде "Good signature".

Если wget запускался не из каталога сборки, переместите в него скачанный архив:

$ mv /путь/к/linux-4.8.6.tar.xz ~/kernelbuild/

Распаковка исходников

Распакуйте архив ядра в каталоге сборки:

$ tar -xvf linux-4.8.6.tar

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

$ cd linux-4.8.6/
$ make mrproper
Примечание: mrproper — цель Make. Она зависит от цели clean, поэтому указывать обе цели не обязательно. Подробнее см. [1].

Настройка

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

Примечание: root-аккаунт или root-привилегии на этом этапе не требуются.

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

Конфигурация ядра

Существует два способа создать конфигурацию:

  • A. Использовать стандартные настройки Arch для официального ядра (рекомендуется).
  • B. Сгенерировать файл с настройками ядра, работающего в данный момент (например, если вы желаете подкорректировать текущие настройки).
Примечание: Особенно в случае варианта **B**, вы получите запрос на ручное задание опций ядра инструментами из раздела #Продвинутая конфигурация.

A. Стандартная конфигурация Arch

Этот метод предполагает создание нового файла .config на основе настроек стандартного ядра Arch. Если на вашей машине работает стандартное ядро, выполните следующую команду в каталоге с исходниками нового ядра:

$ zcat /proc/config.gz > .config

В противном случае стандартную конфигурацию можно взять в официальном пакете ядра Arch Linux.

Совет: При обновлении ядер опции иногда могут меняться или даже удаляться. В этом случае при запуске make на этапе #Компиляция вам будут заданы вопросы насчёт каждой изменённой опции. Чтобы применить стандартные настройки и не отвечать на вопросы, выполните make olddefconfig.
Важно: Если вы компилируете ядро с использованием текущего файла .config, не забудьте переименовать вашу версию ядра "CONFIG_LOCALVERSION" в новом .config-файле, или выберите опцию General Setup > Local version - append to kernel release в одном из интерфейсов из раздела #Продвинутая конфигурация. Если вы пропустите этот шаг, то можете случайно перезаписать одно из существующих ядер.

B. Сгенерированная конфигурация

Совет:
  • Подключите все устройства, которые собираетесь использовать на этой системе в будущем.
  • modprobed-db ведёт список ВСЕХ модулей, которые когда-либо появлялись в системе. С его помощью[ссылка недействительна: раздел не найден] можно настроить localmodconfig для установки всех модулей, использовавшихся ранее, в том числе и отсутствующих в системе в данный момент.

С ядра 2.6.32 команда localmodconfig создаёт файл .config для нового ядра, отключив все опции, которые не заданы в работающем здесь и сейчас ядре. Другими словами, включены будут только опции, включённые в данный момент.

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

Примечание: Ещё раз, убедитесь, что вы подключили все устройства (и они были успешно обнаружены) к системе перед запуском следующей команды.
$ make localmodconfig

Продвинутая конфигурация

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

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

Примечание: Эти инструменты перечислены ниже и предоставляют три возможных значения для каждой особенности ядра: y для включения, n для отключения и m для включения в качестве модуля ядра (загружается при необходимости).

Инструменты:

  • make menuconfig: утилита командной строки с интерфейсом ncurses; была заменена nconfig.
  • make nconfig: новый инструмент командной строки с ncurses-интерфейсом.
  • make xconfig: более дружелюбный к пользвателю графический интерфейс, которому требуется пакет packagekit-qt5 в качестве зависимости. Это рекомендуемый метод — особенно для неопытных пользователей — поскольку в нём упрощена навигация, а также выводится справочная информация о каждой опции.
  • make gconfig: графический настройщик, похожий на xconfig, но использующий gtk.

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

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

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

Команда $ lspci -k # в liveCD-окружении выведет список используемых модулей ядра. Важно также не забыть обеспечить поддержку cgroups. Это необходимо для systemd.

Компиляция

Совет: Если вы хотите оптимизировать gcc под набор инструкций вашего процессора, отредактируйте файл arch/x86/Makefile (как для 32-битной архитектуры, так и для 64-битной; см. [2]) в каталоге с исходниками ядра:
  • В параметре Processor type and features > Processor Family выберите архитектуру среди значений: CONFIG_MK8,CONFIG_MPSC,CONFIG_MCORE2,CONFIG_MATOM,CONFIG_GENERIC_CPU.
  • Измените флаг call cc-options со значения -march=native на то, которое вы выбрали в параметре Processor Family, например: cflags-$(CONFIG_MK8) += $(call cc-option,-march=native). Это, возможно, лучший работающий способ копиляции с -march=native.
  • Примечание: для 32-битных ядер необходимо аналогичным образом отредактировать файл arch/x86/Makefile_32.cpu и так же задать -march=native для вашего процессора.

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

$ make
Совет: Для ускорения компиляции можно запустить make с аргументом -jX, где X — целое число, обозначающе количество параллельно работающих процессов. Наилучший результат получается при использовании всех доступных ядер процессора; например, для двухядерной машины выполните make -j2. Подробнее см. makepkg#Сокращение времени компиляции.

Установка

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

Установка модулей

После того, как ядро скомпилировано, то же самое необходимо сделать с модулями. Сначала соберите модули:

$ make modules

Затем установите их:

# make modules_install

Эта команда скопирует откомпилированные модули в каталог /lib/modules/<версия_ядра>-<версия_конфигурации>. Например, для ядра версии 4.8 они будут скопированы в /lib/modules/4.8.6-ARCH. Это позволяет хранить модули разных ядер в отдельных каталогах.

Совет: Если вашему ядру необходимы модули, которые не распространяются со стандартным ядром Linux, необходимо их скомпилировать. Это обычно касается модулей, которые вы устанавливаете явно (вручную) на уже запущенной системе. См. пример в NVIDIA#Собственное ядро.

Копирование ядра в каталог /boot

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

В результате компиляции ядра создаётся bzImage (big zImage, "большой сжатый образ") этого ядра, который необходимо скопировать в каталог /boot и переименовать. Имя должно начинаться с vmlinuz-, окончание можно выбрать любое. В примерах ниже установленное и скомпилированное ядро версии 4.8 копируется и переименуется в vmlinuz-linux48:

  • 32-битное (i686) ядро:
# cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux48
  • 64-битное (x86_64) ядро:
# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-linux48

Создание начального RAM-диска

Примечание: Вы можете выбрать абсолютно любое имя для initramfs-образа. Тем не менее, рекомендуется использовать схему linux<старший_номер><младший_номер>. Например, название 'linux48' означает ядро версии 4.8, где старший номер (ревизии) — '4', а младший — '8'. При таком именовании можно хранить в системе несколько ядер разных версий, регулярно использовать mkinitcpio и собирать сторонние модули.
Совет: Если вы используете загрузчик LILO и ему не удаётся связаться с драйвером device-mapper в ядре, выполните сначала modprobe dm-mod.

Если вы не знаете, что такое создание начального RAM-диска, изучите статьи initrd и mkinitcpio.

Автоматизированный метод

Чтобы initramfs для нового ядра был сгенерирован аналогично официальному ядру, можно скопировать и модифицировать существующий mkinitcpio preset. Это удобно при перекомпиляции ядра (например, после обновления). В примере ниже файл предустановок (preset file) стокового ядра Arch копируется и модифицируется под ядро версии 4.8, установленное выше.

Сначала скопируйте существующий preset-файл, переименовав его с использованием суффикса из /boot/vmlinuz- (в нашем случае — linux48):

# cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux48.preset

Затем отредактируйте файл под новое ядро. В параметре ALL_kver= необходимо указать имя нового ядра, выбранное при копировании bzImage:

/etc/mkinitcpio.d/linux48.preset
...
ALL_kver="/boot/vmlinuz-linux48"
...
default_image="/boot/initramfs-linux48.img"
...
fallback_image="/boot/initramfs-linux48-fallback.img"

Наконец, сгенерируйте initramfs-образ для нового ядра:

# mkinitcpio -p linux48

Ручной метод

Вместо использования файла с предустановками можно сгенерировать initramfs-файл вручную посредством mkinitcpio:

# mkinitcpio -k <версия_ядра> -g /boot/initramfs-<имя_файла>.img
  • -k (--kernel <версия_ядра>): указывает модули, которые будут использованы при генерации образа. Имя <версия_ядра> совпадает с именем каталога с исходниками нового ядра (и каталога с модулями для него, расположенного в /usr/lib/modules/).
  • -g (--generate <имя_файла>): указывается имя initramfs-файла, который будет создан в каталоге /boot. Ещё раз — рекомендуется использовать стандартную схему именования, упомянутую выше.

Например, команда для ядра версии 4.8:

# mkinitcpio -k linux-4.8.6 -g /boot/initramfs-linux48.img

Копирование System.map

Файл System.map не требуется для загрузки Linux. Это что-то вроде "телефонной книги" со списком функций для конкретной сборки ядра. System.map содержит список символов ядра (т.е. имён функций, переменных и т.п.) и соответсвующих им адресов. Это отображение имён символов на адреса используется:

  • Некоторыми процессами вроде klogd, ksymoops и т.д.
  • Обработчиком OOPS, когда во время падения ядра на экран выводится информация (например, о том, какая именно функция вызывала падение).
Совет: UEFI-разделы используют файловую систему FAT32, которая не поддерживает символические ссылки.

Если ваш каталог /boot использует файловую систему с поддержкой символических ссылок (т.е. не FAT32), скопируйте System.map в /boot, добавив название ядра к итоговому файлу. Затем создайте символическую ссылку /boot/System.map на /boot/System.map-<название_ядра>:

# cp System.map /boot/System.map-<название_ядра>
# ln -sf /boot/System.map-<название_ядра> /boot/System.map

В итоге в /boot должно быть 3 файла и 1 символическая ссылка (не считая любых других файлов, находившихся там до этого):

  • Ядро: vmlinuz-<название_ядра>
  • Initramfs: Initramfs-<название_ядра>.img
  • System Map: System.map-<название_ядра>
  • Символическая ссылка на System Map.

Настройка загрузчика

Добавьте в файл настроек загрузчика пункт с новым ядром. В статье Процесс загрузки Arch#Сравнение возможностей приведено сравнение доступных загрузчиков; также изучите соответствующие статьи.

Совет: Среди исходников ядра есть сценарий для автоматизации настройки LILO: $ arch/x86/boot/install.sh. В конце выполните lilo с правами root, чтобы изменения вступили в силу.

Смотрите также

  • https://cateee.net/lkddb/web-lkddb/ — подробный отсортированный список строк конфигурации ядра и с пояснениями.