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

From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи 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/ — подробный отсортированный список строк конфигурации ядра и с пояснениями.