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

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

Category:

- Kernel (Русский)