Gentoo - ручная конфигурация и сборка ядра. Делаем идельное ядро под свою систему
1. Выбор ядра
2. Загрузка исходников ядра
3. Конфигурация ядра
4. Сборка и установка ядра
5. Обновление ядра
6. Удаление ненужных ядер
При установке Gentoo вы скорее всего пошли по пути полностью автоматической установки ядра - Distribution Kernel. Это ядро по умолчанию включает в себя поддержку большинства аппаратных компонентов, initramfs и требует минимального участия пользователя в последующих обновлениях, поэтому идеально подходит для новичков.
Со временем вы можете захотеть собрать ядро вручную, со своей конфигурацией. В основном это делается для:
- Создания идеального ядра под свое железо, которое будет включать в себя поддержку только нужных технологий
- Повышения уровня знаний о Linux
- Сокращения времени сборки
Когда вы будете вручную конфигурировать свое ядро, у вас будет возможность выбрать поддерживаемые технологии. Например, если вы не используете bluetooth, то можете не добавлять его поддержку в ядро. Тоже самое касается любых других сетевых протоколов, файловых систем и прочего. Вы будете сами решать, что ваше ядро поддерживает, а что нет. И в любой момент вы сможете внести изменения в конфигурационный файл и пересобрать ядро с новыми параметрами конфигурации.
В данной статье я постараюсь максимально подробно описать процесс конфигурации и сборки ядра: покажу как выполняется загрузка исходников, конфигурация, компиляция и последующие обновления ядра. Полностью ручная сборка - это самый сложный процесс, но он обеспечивает максимальный контроль над процессом обновления ядра, в отличии использования Distribution Kernel или Genkernel.
Процесс сборки ядра можно разделить на несколько шагов:
После того, как вы соберете ядро и установите его в систему, вам нужно будет периодически выполнять обновление ядра, чтобы получать исправления ошибок и безопасности. Процесс обновления тоже можно разделить на несколько шагов:
Следует учитывать, что данная статья расчитана на пользователей, которые используют архитектуру процессора AMD64.
Выбор ядра
В первую очередь вам нужно выбрать какое ядро вы хотите использовать. Далее вы будете вносить правки в конфигурацию этого ядра и соберете его для своей системы.
На данной странице описаны все пакеты исходников ядер, которые Gentoo предоставляет в основном ebuild-репозитории:
https://wiki.gentoo.org/wiki/Kernel/Overview/ru
Для большинства пользователей рекомендуется sys-kernel/gentoo-sources. Этот пакет включает в себя ядро с патчами для исправления безопасности и ошибок, а также повышает совместимость с не очень распространенными системными архитектурами. Данное ядро отлично подойдет для домашних систем. Именно его мы будем использовать в рамках данной статьи.
Установка исходников ядра
Далее я буду использовать среду chroot, но вы можете тоже самое делать и напрямую из Gentoo. Следующая команда установит исходники ядра sys-kernel/gentoo-sources в директорию /usr/src/
:emerge --ask sys-kernel/gentoo-sources
Обратите внимание, что это только установит исходники ядра, но процесс компиляции не будет запущен. Компилировать ядро мы будем сами с помощью make, после того как создадим свою конфигурацию.
Проверьте наличие исходников:ls /usr/src
Да, в моей системе ранее было установлено ядро Distribution Kernel. Вы можете хранить несколько ядер в своей системе, если это необходимо. Чтобы посмотреть какое ядро используется на данный момент, воспользуйтесь eselect:eselect kernel list
Эта команда выводит список всех ядер в системе и отображает ядро, используемое в данный момент с помощью символа *
. С помощью команды eselect kernel set 1
вы можете заставить Gentoo использовать ядро под номером 1 (в нашем случае linux-6.12.31-gentoo
). На самом деле данная команда просто автоматизирует процесс создания ссылки /usr/src/linux
на исходники ядра:
Символьная ссылка /usr/src/linux
всегда должна указывать на исходный код используемого в настоящий момент ядра:
Более подробно про создание ссылки вы можете почитать здесь:
https://wiki.gentoo.org/wiki/Kernel/Configuration#Set_symlink
Создание ссылки на исходный код ядра не означает, что теперь система использует именно это ядро. Во-первых, это ядро еще нужно собрать, а во-вторых, вам нужно обновить конфигурацую загрузчика, чтобы указать новый образ ядра для загрузки. Пока что не вдавайтесь в подробности и просто создайте символьную ссылку, как показано выше. После того как мы соберем ядро я покажу как обновить конфигурацию Grub и заставить систему использовать новое ядро.
Конфигурация ядра
Настало время внести правки в конфигурацию ядра. Gentoo предоставляет два способа настройки конфигурационного файла, установки и обновления ядра: автоматический (с помощью genkernel или Dracut) и вручную. Мы будем рассматривать ручной вариант, т.к. он наиболее гибкий и предоставляет больше возможностей.
Существует множество пользовательских утилит для создания собственной конфигурации, которые описаны далее.
make config - конфигурация на базе текста. Варианты предлагаются один за другим. На все варианты должны быть пользовательские ответы, и неупорядоченный доступ к бывшим вариантам невозможен.
make menuconfig - конфигурация на базе псевдографического меню ncursed.
make defconfig - генерация новой конфигурации с настройками по умолчанию из ARCH, предоставленного файлом defconfig. Используется для возвращения конфигурации по умолчанию.
make nconfig - псевдо-графическое меню на базе ncurses. Требуется установка пакета sys-libs/ncurses.
make xconfig - графическое меню на Qt5. Подойдет для тех, кто хочет использовать GUI. Требуется установка пакета dev-qt/qtwidgets.
make gconfig - графическое меню на GTK. Требуется установка пакетов x11-libs/gtk+, dev-libs/glib и gnome-base/libglade.
make oldconfig - просмотр изменений между версиями ядра и обновлением, чтобы создать новый .config
для ядра.
make olddefconfig - генерация новой конфигурации со значениями по умолчанию из файла ARCH, но с сохранением всех предыдущих параметров, установленных в файле .config
, находящемся по адресу /usr/src/linux/.config
. Это быстрый и безопасный способ обновления файла конфигурации, который имеет все параметры конфигурации, необходимые для аппаратной поддержки, исправления ошибок и безопасности.
make localmodconfig - создание конфигурации на основе текущей конфигурации и загруженных в настоящее время модулей, видимых с помощью lsmod
.
make allyesconfig - включение всех параметров конфигурации в ядре. Убедитесь, что вы создали резервную копию текущей конфигурации ядра перед использованием этой утилиты!
make allmodconfig - включает все модули в ядре. Обратите внимание, что это займет много места на диске.
Список утилит был взят отсюда:
https://wiki.gentoo.org/wiki/Kernel/Configuration#Tools
Наиболее популярной утилитой считается make menuconfig. Именно ее мы будем использовать далее для настройки ядра. Ядро включает конфигурацию по умолчанию, которая активирует отдельные части исходного кода ядра во время первого запуска menuconfig. В целом, предлагается широкий выбор разумных значений по умолчанию, что означает, что большинству пользователей потребуется внести лишь небольшое количество изменений. Если вы хотите отключить какой-то параметр, убедитесь что точно понимаете, что этот параметр делает и каковы будут последствии его отключения. При конфигурации ядра Linux в первый раз, следует придерживаться умеренных настроек и вносить минимум изменений. В то же время, следует учитывать, что существуют определенные настройки, которые необходимо изменить, чтобы система действительно смогла загрузиться.
Большинство параметров конфигурации поддерживают три вида состояния: отключены вовсе (N)
, встроены прямо в ядро (Y)
, или собраны в качестве модулей (M)
. Модули хранятся вне ядра в виде отдельных файлов, в то время как встроенные параметры являются частью ядра. Модули можно включить или отключить в любой момент, а встроенные параметры вы никак не отключите, пока не измените конфигурацию ядра и не пересоберете его. Очень важно понимать когда требуется встроенная поддержка параметра, а когда поддержка в виде модуля. Например, если раздел root расположен на файловой системе btrfs, система не загрузится, если поддержка btrfs была реализована в качестве модуля.
Утилита конфигурации может определить архитектуру системы, но она не определяет используемое аппаратное обеспечение: видеокарту, центральный процессор и прочее. Пользователю придется самостоятельно выбрать нужные параметры для поддержки своего аппаратного обеспечения. Доступны несколько вспомогательных утилит, которые помогут пользователям определить, какие варианты конфигурации ядра лучше использовать:
- lspci (часть пакета sys-apps/pciutils) - определяет аппаратное обеспечение, основанное на PCI и AGP, включая компоненты, встроенные в материнскую плату.
- lsusb (из пакета sys-apps/usbutils) - определяет различные устройства, подсоединенные к USB портам.
Установка выполняется с помощью двух команд:emerge --ask sys-apps/pciutils
emerge --ask sys-apps/usbutils
Приступаем к конфигурации. Переходим в каталог /usr/src/linux
(убедитесь, что вы создали символьную ссылку!) и вводим команду make localmodconfig
. Эта команда обнаруживает все работающие модули в настоящее время (например из установочного носителя или среды chroot) и записывает информацию в конфигурационный файл .config
. Таким образом мы снижаем риск отстутствия необходимых модулей в ядре. Посмотреть список изменений в конфиге можно с помощью скрипта diffconfig
, который сравнивает 2 файла: старый конфиг и новый:/usr/src/linux/scripts/diffconfig .config.old .config
Теперь запускаем make menuconfig
. На экране отобразится псевдографический интерфейс:
Прочитайте раздел про использование меню, если хотите больше узнать о том, как им пользоваться.
Если вы используете ядро sys-kernel/gentoo-sources, то настоятельно рекомендуется включить специфичные для Gentoo параметры, которые гарантируют наличие минимальных настроек ядра, необходимых для функционирования:
Gentoo Linux ---> [*] Gentoo Linux support [*] Linux dynamic and persistent device naming (userspace devfs) support [*] Select options required by Portage features Support for init systems, system and service managers ---> [*] OpenRC, runit and other script based systems and managers [*] systemd
Обратите внимание, что вы можете выбрать только OpenRC или systemd в зависимости от того, какая система инициализации используется в вашей системе. У меня установлен OpenRC, поэтому я выбираю его:
Теперь добавим поддержку файловых систем. Раздел root у меня работает на файловой системе ext4. Также нужно добавить поддержку vfat для загрузочного раздела и XFS, Btrfs, MSDOS и exFAT, которые теоритически могут быть на съемных накопителях:
File systems ---> -*- The Extended 4 (ext4) filesystem [*] Use ext4 for ext2 file systems -*- Ext4 POSIX Access Control Lists -*- Ext4 Security Labels <*> XFS filesystem support [*] Support deprecated V4 (crc=0) format (NEW) [*] Support deprecated case-insensitive ascii (ascii-ci=1) format (NEW) <*> Btrfs filesystem support [*] Btrfs POSIX Access Control Lists DOS/FAT/EXFAT/NT Filesystems ---> <*> MSDOS fs support <*> VFAT (Windows-95) fs support <*> exFAT filesystem support
Обязательно добавляем поддержку /proc и virtual memory file system:
Pseudo Filesystems ---> [*] /proc file system support [*] Tmpfs virtual memory file system support (former shm fs)
Также добавляем поддержку файловой системы devtmpfs для монтирования в /dev
, чтобы критические файлы устройств уже были доступны на ранней стадии процесса загрузки:
Device Drivers ---> Generic Driver Options ---> [*] Maintain a devtmpfs filesystem to mount at /dev [*] Automount devtmpfs at /dev, after the kernel mounted the rootfs
В моем ноутбуке присутствует 2 SSD-диска и есть слот под HDD, поэтому добавляем поддержку SATA и NVMe-дисков. Поддержка SATA в Linux реализована через слой, называемый libata, который располагается уровнем ниже подсистемы SCSI. По этой причине, драйвера SATA находятся в разделе конфигурации с драйверами SCSI. Кроме того, устройства хранения данных могут обрабатываться как SCSI-устройства, а это значит, что необходима поддержка SCSI диска или cdrom.
Device Drivers ---> NVME Support ---> <*> NVM Express block device SCSI device support ---> <*> SCSI device support <*> SCSI disk support <*> SCSI CDROM support <*> Serial ATA and Parallel ATA drivers (libata) --->
Не помешает включить следующую дополнительную поддержку NVMe:
[*] NVMe multipath support [*] NVMe hardware monitoring <M> NVM Express over Fabrics FC host driver <M> NVM Express over Fabrics TCP host driver
Включаем поддержку GPT, если требуется:
-*- Enable the block layer ---> Partition Types ---> [*] Advanced partition selection [*] EFI GUID Partition support
Включите поддержку EFI, если UEFI используется для загрузки системы:
Processor type and features ---> [*] EFI runtime service support [*] EFI stub support [*] EFI mixed-mode support Device Drivers Graphics support ---> Frame buffer Devices ---> <*> Support for frame buffer devices ---> [*] EFI-based Framebuffer Support File Systems Pseudo filesystems ---> <*> EFI Variable filesystem
Следующим шагом будет настройка поддержки центрального процессора. Рекомендуется включить MCE features, чтобы можно было получать уведомления о проблемах с аппаратной частью, если таковы имеются. На некоторых архитектурах (например, x86_64) эти ошибки печатаются не для dmesg, а для /dev/mcelog
. Для этого требуется пакет app-admin/mcelog. Вы можете установить этот пакет следующей командой:emerge --ask app-admin/mcelog
Включаем поддержку MCE features:
Processor type and features ---> [*] Intel MCE features [*] AMD MCE features
Разумеется, вы можете выбрать поддержку MCE только для Intel или только для AMD. Я оставил только для Intel, т.к. у меня процессор Intel i5-11400H:
Далее я убираю поддержку процессоров AMD. То есть выключаю AMD MCE features, AMD ACPI2Platform devices Support и т.п.
Множество компьютеров основаны на многоядерных процессорах и практически все современные процессоры поддерживают SMT, поэтому стоило бы включить некоторые параметры, которые могут улучшить производительность:
Processor type and features ---> [*] Symmetric multi-processing support [*] SMT (Hyperthreading) aware nice priority and policy support [*] Multi-core scheduler support (NEW)
Следующая опция предназначена не только для управления питанием, но также может быть необходима для определения всех процессоров, доступных в системе:
Power management and ACPI options ---> [*] ACPI (Advanced Configuration and Power Interface) Support
Разберемся с USB хост-контроллерами. устройства хост-контроллера USB немного различаются. В основном используются два вида:
EHCI
- Extended Host Controller Interface (усовершенствованный интерфейс хост-контроллера). Это единственный распространенный интерфейс хост-контроллера, поддерживающий USB 2.0 и обычно присутствующий на любом компьютере с поддержкой USB 2.0.XHCI
- eXtensible Host Controller Interface (расширяемый интерфейс хост-контроллера). Это хост-контроллер интерфейс для USB 3.0, который совместим с USB 1.0, 1.1, 2.0, 3.0 и будущими версиями.
Для использования USB-устройств не нужно выбирать оба варианта, так как XHCI совместим с более медленными контроллерами USB, но что бы "обезопасить" себя, пользователь может включить поддержку EHCI; это не причинит вреда, если USB 2.0 контроллер отсутствует в системе.
Следующая команда покажет какие устройства HCD присутствуют в системе:lspci -v | grep HCI
Выберите HCD присутствующий в системе. В общем случае, можно выбрать все три варианта для максимальной поддержки, если правильный вариант неизвестен:
Device Drivers ---> USB support ---> <*> Support for Host-side USB --- USB Host Controller Drivers <*> xHCI HCD (USB 3.0) support <*> EHCI HCD (USB 2.0) support < > OHCI HCD (USB 1.1) support < > UHCI HCD (most Intel and VIA) support
В ядре Linux версии 3.12.13 и новее OHCI support for PCI-bus USB controllers
(CONFIG_USB_OHCI_HCD_PCI
) стоит включить, если USB-контроллер - это OHCI и используется USB клавиатура или мышь.
Начиная с версии ядра 3.18.x (и выше) возможно сжатие модулей ядра. Важно установить sys-apps/kmod с нужными USE-флагами перед компиляцией ядра со сжатыми модулями:lzma zlib
Перекомпилируйте sys-apps/kmod:emerge --ask --oneshot --changed-use sys-apps/kmod
Включите сжатие модулей и выберите предпочитаемый метод сжатия:
[*] Enable loadable module support ---> Module compression mode () ---> ( ) None (X) GZIP ( ) XZ ( ) ZSTD
Если PPPoE используется для подключения к Интернету или модему dial-up, включите следующие параметры (CONFIG_PPP, CONFIG_PP_ASYNC и CONFIG_PP_SYNC_TTY):
Device Drivers ---> Network device support ---> <*> PPP (point-to-point protocol) support <*> PPP over Ethernet <*> PPP support for async serial ports <*> PPP support for sync tty ports
Обязательно выберите IA32 Emulation и 32-разрядные программы, если следует поддерживать 32-разрядные программы. Если не используется профиль no-multilib, то эти параметры требуются:
Binary Emulations ---> [*] IA32 Emulation General architecture-dependent options ---> [*] Provide system calls for 32-bit time_t
Далее добавляем поддержку видеокарты NVIDIA. У меня NVIDIA GeForce RTX 3050 Ti Mobile, поэтому мне подойдет пакет nvidia-drivers. Настраиваем ядро в соответствии с этой инструкцией:
NVIDIA/nvidia-drivers - Gentoo wiki
Сборка и установка ядра
После того, как мы успешно создали свою конфигурацию, можно приступить к сборке (модули будут скопированы в подкаталог /lib/modules
):make && make modules_install
Если вы использовали Dracut во время установки Gentoo для автоматической генерации initramfs, то рекомендуется запустить следующую команду:emerge --ask @module-rebuild
Когда ядро успешно скомпилировано, его образ можно скопировать в /boot
:make install
Далее нужно обновить конфигурацию загрузчика. Например, если вы используете GRUB:grub-mkconfig -o /boot/grub/grub.cfg
Хотя, если установлен пакет sys-kernel/installkernel и используется USE-флаг grub
, то после каждой установки ядра GRUB будет сам обновлять конфигурацию. Все же, ручное обновление конфигурации может быть неким профилактическим шагом, если вы не уверены, что конфигурация обновилась.
Перезагрузитесь и проверьте работоспособность системы. Убедитесь, что используете нужное ядро, например с помощью neofetch:
-/oyddmdhs+:. root@arch -odNMMMMMMMMNNmhy+-` --------- -yNMMMMMMMMMMMNNNmmdhy+- OS: Gentoo Linux x86_64 `omMMMMMMMMMMMMNmdmmmmddhhy/` Host: Nitro AN515-57 V1.17 omMMMMMMMMMMMNhhyyyohmdddhhhdo` Kernel: 6.12.31-gentoo .ydMMMMMMMMMMdhs++so/smdddhhhhdm+` Uptime: 3 mins oyhdmNMMMMMMMNdyooydmddddhhhhyhNd. Packages: 690 (emerge) :oyhhdNNMMMMMMMNNNmmdddhhhhhyymMh Shell: bash 5.2.37 .:+sydNMMMMMNNNmmmdddhhhhhhmMmy CPU: 11th Gen Intel i5-11400H (12) @ 4.500GHz /mMMMMMMNNNmmmdddhhhhhmMNhs: GPU: NVIDIA GeForce RTX 3050 Ti Mobile `oNMMMMMMMNNNmmmddddhhdmMNhs+` GPU: Intel TigerLake-H GT1 [UHD Graphics] `sNMMMMMMMMNNNmmmdddddmNMmhs/. Memory: 1475MiB / 15764MiB /NMMMMMMMMNNNNmmmdddmNMNdso:` +MMMMMMMNNNNNmmmmdmNMNdso/- yMMNNNNNNNmmmmmNNMmhs+/-` /hMMNNNNNNNNMNdhs++/-` `/ohdmmddhys+++/:.` `-//////:--.
Обратите внимание, что если у вас установлено несколько ядер, то может быть необходимо вручную выбрать нужное ядро для загрузки. Это делается через меню Grub. Нажмите Advanced Options в загрузочном меню Grub и выберите нужное ядро.
Обновление ядра
Периодически может возникать необходимость обновить ядро, например для получения исправлений ошибок и безопасности. Сейчас мы рассмотрим процесс обновления ядра.
В новой версии ядра могут быть опции или возможности, которых нет в старом ядре, или наоборот, из нового ядра могут быть убраны некоторые из опций, которые были в старом ядре. Сейчас вы узнаете как обращаться с такими изменениями файла конфигурации.
Для обновление ядра в начале нужно установить новый исходный код ядра. Этот исходный код иногда устанавливается в результате обновления системы при запуске следующей команды:emerge --ask --update --deep --with-bdeps=y --newuse @world
Конечно, исходный код ядра можно установить напрямую, используя команду (замените gentoo-sources на любую версию ядра, которую используете):emerge --ask --update --deep --with-bdeps=y --newuse sys-kernel/gentoo-sources
Далее нужно установить символьную ссылку на новый исходный код ядра. Смотрим список доступных ядер:eselect kernel list
Выбираем новое ядро:eselect kernel set 2
В качестве альтернативы вы можете использовать USE-флаг symlink
. Это заставит /usr/src/linux
ссылаться на свежеустановленный исходный код ядра.
После того, как была изменена символьная ссылка, смените рабочую директорию на каталог с новым ядром:cd /usr/src/linux
Теперь нам нужно скопировать предыдущую конфигурацию ядра:cp /usr/src/linux-*-gentoo/.config /usr/src/linux/
Новое ядро обычно требует новый файл .config
для поддержки новых опций ядра. Файл .config
с предыдущего ядра может быть сконвертирован для использования новым ядром. Конвертация может быть выполнена несколькими способами, например с помощью команд make oldconfig
или make olddefconfig
. make oldconfig
предоставляет пользователю возможность выбрать значения для новых опций. Например:make oldconfig
Anticipatory I/O scheduler (IOSCHED_AS) [Y/n/m/?] (NEW)
Надпись (NEW) в конце строки означает, что это новая опция. В левой части, в квадратных скобках, указаны возможные ответы. Рекомендуемый ответ (т.е. по умолчанию) написан большими буквами (здесь Y
). В справке дано пояснение к опции или драйверу. Справку можно вывести с помощью ?
.
К сожалению, make oldconfig
не дает исчерпывающей информации для каждой опции, так что иногда трудно выбрать правильный ответ. В этом случае, лучше запомнить название параметра и найти его позже с помощью одного из инструментов конфигурации ядра. Для просмотра списка новых опций, используйте make listnewconfig
перед make oldconfig
.
make olddeconfig
оставит все настройки со старого файла .config
и установит новые настройки в их рекомендуемое значение (то есть в значение по умолчанию):make olddefconfig
При необходимости вы можете внести изменения в конфигурацию вручную:make menuconfig
Далее выполняется сборка ядра. Если на вашей системе установлены внешние модули ядра (такие как nvidia или zf), они должны быть перестроены для нового скомпилированного ядра для обеспечения совместимости:make modules_prepare
make
emerge --ask @module-rebuild
Далее выполняется установка ядра:make modules_install
make install
И не забудьте обновить конфигурацию загрузчика:grub-mkconfig -o /boot/grub/grub.cfg
Удаление ненужных ядер
После успешного обновления ядра вы можете удалить старую версию, чтобы освободить место на диске. В первую очередь удалите исходный код ядра. Убедитесь, что вы удаляете исходники старого ядра, а не нового!emerge --ask --depclean gentoo-sources:xx.yy.zzz
Далее удалите файлы, созданные во время компиляции:rm -r /usr/src/linux-X.Y.Z
Модули:rm -r /lib/modules/X.Y.Z
Файлы в /boot
:rm /boot/vmlinuz-X.Y.Z
rm /boot/System.map-X.Y.Z
rm /boot/config-X.Y.Z
rm /boot/initramfs-X.Y.Z
И наконец, обновите конфигурацию загрузчика.
Использованные источники
Kernel - Gentoo wiki
Kernel/Configuration - Gentoo wiki
Kernel/Gentoo Kernel Configuration Guide - Gentoo wiki
Kernel/Upgrade - Gentoo wiki
Kernel/Removal - Gentoo wiki