.. ARU (c) 2018 - 2023, Pavel Priluckiy, Vasiliy Stelmachenok and contributors

   ARU is licensed under a
   Creative Commons Attribution-ShareAlike 4.0 International License.

   You should have received a copy of the license along with this
   work. If not, see <https://creativecommons.org/licenses/by-sa/4.0/>.

.. _custom-kernels:

*****************
Кастомные ядра
*****************

Прежде чем мы начнем, хотелось бы прояснить такой вопрос: "А зачем
вообще нужны эти кастомные ядра?". Чтобы дать ответ на данный вопрос,
стоит понимать, что ядро Linux является определенным универсальным
стандартом в мире операционных систем, который одинаково подходит как
для домашнего ПК, ноутбука, телефона, так и для сервера, роутера,
микро-контроллера. То есть, ядро по умолчанию является швейцарским
ножом, позволяющим применять себя в разных задачах, но при этом не
быть лучшим в чём-то конкретном. Нет, это не значит, что на ванильном
ядре вы не сможете запустить какую-то игру, скажем через Wine или
Proton, но такой опыт не будет самым лучшим, т.к. за такую многопрофильность
ядру приходится платить меньшей производительностью в определенных
задачах. Кастомное же ядро подразумевает определенную заточенность под
что-то конкретное, делая упор на что-то одно. В нашем случае это
производительность и игры, а также улучшение опыта использования Linux
на домашнем ПК или ноутбуке. В этом нам и помогут нижеперечисленные
ядра вместе с их правильной настройкой.

И ещё просим вас заранее установить стабильное ``linux-lts`` ядро. В
случае возникновения проблем вы всегда сможете откатиться на эту
версию ядра.

Проверка ядра используемого в данный момент осуществляется следующей
командой: ``uname -r``.

.. index:: kernel
.. _kernel_choose:

=============
О выборе ядра
=============

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


===================
Достойные внимания 
===================


.. index:: kernel, zen, native-compilation
.. _linux-zen:

----------
linux-zen
----------

Zen ядро - это плод коллективных усилий по объединению патчей
улучшающих опыт домашнего использования Linux, но при этом работающих
стабильно и не ломающих совместимость с теми или иными вещами.

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

Из основных улучшений:

- Улучшено поведение планировщика EEVDF для значительного снижения
  задержек в несколько раз.
- Поддержка модулей NTSync
- Поддержка алгоритма BBRv3
- Применение оптимальных настроек для сохранения отзывчивости системы

**I. Установка** ::

  sudo pacman -S linux-zen linux-zen-headers

  # Если у вас не GRUB - используйте команду обновления вашего загрузчика
  sudo grub-mkconfig -o /boot/grub/grub.cfg

**II. Установка (нативная компиляция)** ::

  git clone https://aur.archlinux.org/linux-zen-git.git
  cd linux-zen-git
  makepkg -sric
  sudo grub-mkconfig -o /boot/grub/grub.cfg


.. index:: kernel, linux-tkg, native-compilation
.. _linux-tkg:

------------
linux-tkg
------------

Ядро с высокой степенью гибкости, благодаря возможности собрать ядро с
разного рода патчами - с набором множества патчей на улучшение
производительности в игрушках. Предоставляет выбор в сборке ядра с
разными планировщиками. Грубо говоря, это ядро сборная солянка из всех
остальных ядер с большим набором патчей.

**I. Установка и настройка**::

  git clone https://github.com/Frogging-Family/linux-tkg.git
  cd linux-tkg

Есть две возможности предварительной настройки linux-tkg: либо через
редактирование файла *customization.cfg*, либо через терминал по ходу
процесса установки. Мы выбираем первое и отредактируем
*customization.cfg*::

  nano customization.cfg

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

``_version="6.11"`` - Здесь выбираем версию ядра которую мы хотим
установить. Выбирайте самую последнюю из доступных.

``_modprobeddb="false"`` - Опция отвечающая за сборку мини-ядра.
Подробнее о нем вы можете узнать в соответствующем разделе. Если
хотите собрать мини-ядро - пишите *"true"*, если нет - *"false"*.

``_menunconfig="2"`` - Выбор настройки ядра через
menuconfg/xconfig/nconfig. Рекомендуется выбрать *"2"* чтобы перед
сборкой можно было выполнить непосредственную настройку ядра через
menunconfig.

``_cpusched="bore"`` - Выбор CPU планировщика ядра. К выбору
предоставляется довольно много планировщиков, но мы советуем обратить
ваше внимание только на некоторых из них: "bore", "cfs"
(планировщик по умолчанию до 6.6), "eevdf"(по умолчанию с 6.6).

.. warning:: Автор рекомендует использовать только EEVDF-based
   планировщики, то есть BORE или sched-ext. PDS и BMQ могут вызывать
   множественные регрессии, например приводить к полному зависанию
   системы на определенных конфигурациях. Последние версии PDS также
   не имеют полноценной поддержки NUMA и PSI.

   См.:
   https://github.com/Frogging-Family/linux-tkg/issues/722
   https://github.com/Frogging-Family/linux-tkg/issues/701
   https://github.com/Frogging-Family/linux-tkg/issues/695
   https://gitlab.com/alfredchen/linux-prjc/-/issues/67
   https://gitlab.com/alfredchen/linux-prjc/-/issues/71
   https://gitlab.com/alfredchen/linux-prjc/-/issues/80
   https://gitlab.com/alfredchen/linux-prjc/-/issues/62
   https://codeberg.org/ventureo/ARU/pulls/91
   

``_aggressive_ondemand="false"`` - Задает агрессивное применение
динамического управления частотой процессора по необходимости в
выполняемой задаче, обеспечивая тем самым энергоэффективность. Но т.к.
выше мы уже закрепили режим масштабирования "performance", то мы
должны отключить этот параметр. Однако пользователи ноутбуков могут
оставить этот параметр включенным.

``_ntsync="true"`` - Включает сборку специального модуля NTSync,
который отвечает за реализацию примитивов синхронизации как в Windows.
Должно использоваться в связке со специально собранным Wine, подробнее
см. :ref:`wine-tkg-git`.

``_ftracedisable="true"`` - Отключает лишние трекеры для отладки ядра.

``_acs_override="true"`` - Включает патч на разделение сгруппированных
PCI устройств в IOMMU, которые могут понадобиться вам отдельно. По
умолчанию есть в linux-zen. Подробнее читайте - `здесь
<https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Bypassing_the_IOMMU_groups_.28ACS_override_patch.29>`_.
Советуем включить если в будущем вы хотите выполнить операцию проброса
вашей видеокарты в виртуальную машину.

Вот и все. Остальные настройки *customization.cfg* вы можете выбрать
по собственному предпочтению. После того как мы закончили с
настройкой, можно перейти непосредственно к сборке и установке ядра:::

  makepkg -sric # Сборка и установка linux-tkg

.. index:: kernel, linux-cachyos, native-compilation
.. _linux-cachyos:

--------------
linux-cachyos
--------------

`linux-cachyos <https://github.com/CachyOS/linux-cachyos>`__ -
добротная альтернатива всем остальным ядрам, также нацеленная на
максимальную производительность вашей системы. По субъективным
ощущениям автора работает лучше чем TKG. Предлагает на выбор
множество планировщиков CPU. Сочетает в себе патчи которые уже были
описаны для других ядер. А именно:
 
- Использует планировщик BORE, заточенный для повышения
  производительности в условиях большой нагрузки на CPU

- Заточен для сборки через LLVM/Clang

- Алгоритм для обработки сетевых пакетов BBRv3

- Поддержка модуля NTSync

- Набор патчей от Clear Linux

- Свежая встроенная в ядро версия библиотеки сжатия zstd

Отдельным плюсом является быстрая обновляемость и оперативные
исправления ошибок, чем к сожалению не всегда может похвастаться
linux-tkg.

**Установка I.**

А вот тут не все так просто, ибо прежде чем мы начнем, стоит
оговориться, что у этого ядра есть вариации с тремя разными
планировщиками. Это: EEVDF (по умолчанию), BORE, sched-ext. Автор
рекомендует остановиться на BORE и EEVDF, как на наиболее проверенных
решениях. Но вы можете попробовать и другие варианты. Далее я буду
выполнять команды для установки ядра с BORE, но соответственно вы
можете писать вместо bore любой другой. Если вы устанавливаете вариант
с поддержкой sched-ext, то перед сборкой ядра следует также установить
пакет scx-scheds из AUR во избежание проблем с зависимостями после
установки ядра::

 # Устанавливаем scx-scheds
 git clone https://aur.archlinux.org/scx-scheds.git
 cd scx-scheds
 makepkg -sric

 git clone https://github.com/CachyOS/linux-cachyos.git  # Скачиваем исходники
 cd linux-cachyos/linux-cachyos # Если хотите использовать EEVDF, то соответственно пишите cd linux-cachyos-eevdf по аналогии
 makepkg -sric

Данное ядро немного умнее других, поэтому определяет архитектуру
вашего процессора и автоматически указывает компилятору собирать себя
именно под неё. Т.е. нативная компиляция здесь есть по умолчанию, так
что в принципе вы можете не сильно заморачиваться с настройкой ядра
или вовсе пропустить данный шаг. Но все таки, если у вас есть
собственные предпочтения относительно определенных параметров вашего
ядра, то вы всегда можете включить ручную настройку через nconfig
используя переменную окружения ``_makenconfig=y`` перед выполнением
команды makepkg: ``export _makenconfig=y``.

**Установка II (бинарные пакеты)**

Бинарную версию ядра можно получить либо через подключение стороннего
репозитория, либо скачав уже готовый пакет опять с того же
репозитория, но не подключая его. Со вторым всё просто, переходите на
данный сайт: https://mirror.cachyos.org/repo/x86_64/cachyos/ и ищите
версию ядра которая вам по вкусу. Потом устанавливаете через ``sudo
pacman -U`` (в конце пишете путь до скаченного файла).

Первый вариант также позволяет получать последние обновления, поэтому он предпочтительней::

  sudo pacman-key --recv-keys F3B607488DB35A47 --keyserver keyserver.ubuntu.com
  sudo pacman-key --lsign-key F3B607488DB35A47
  sudo pacman -U 'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-keyring-20240331-1-any.pkg.tar.zst' \
               'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-mirrorlist-18-1-any.pkg.tar.zst'    \
               'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-v3-mirrorlist-18-1-any.pkg.tar.zst' \
               'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-v4-mirrorlist-6-1-any.pkg.tar.zst'  \
               'https://mirror.cachyos.org/repo/x86_64/cachyos/pacman-6.1.0-7-x86_64.pkg.tar.zst'

Стоит учитывать, что у данного репозитория есть развилка по
архитектурам. То есть он одновременно поддерживает и x86_64, и
x86_64v3. В чем разница? В том, что x86_64v3 чуть более оптимизирован
для современных процессоров и использует инструкции, которые нельзя
применить к обычной x86_64 в угоду совместимости.

Поэтому сначала проверим, поддерживает ли ваш процессора архитектуру
x86_64v3::

  /lib/ld-linux-x86-64.so.2 --help | grep "x86-64-v3 (supported, searched)"

Если вывод команды НЕ пустой, то ваш процессор поддерживает x86_64_v3.

Пропишем репозиторий в /etc/pacman.conf::

  sudo nano /etc/pacman.conf

.. TODO: Move the cachyos repo installation to a separate section

Теперь, если у вас ЕСТЬ поддержка x86_64v3, то пишем следующее::

  # Спускаемся в самый низ файла и пишем:
  [cachyos-v3]
  Include = /etc/pacman.d/cachyos-v3-mirrorlist

Если же нет, то::

  # Спускаемся в самый низ файла и пишем:
  [cachyos]
  Include = /etc/pacman.d/cachyos-mirrorlist

После этого выполните обновление системы и вы сможете установить
бинарное ядро::

  sudo pacman -Syyuu

После этого тоже ставим пакет в соответствии с желаемым планировщиком:
``sudo pacman -S linux-cachyos``. Или ``sudo pacman -S
linux-cachyos-bore``. И так далее.

.. index:: kernel, configure
.. _manual_kernel_configuration:

================
Настройка ядра
================

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

После начала компиляции через некоторое время перед вами должно
появится меню настройки ядра. Перемещение между пунктами в нем
осуществляется стрелками на клавиатуре, переход в следующий раздел
через клавишу *Enter*, а выход из него через *Esc*.

Далее необходимо следовать графической инструкции.

**1.** Для начала выберем одну из важнейших настроек. Это выбор
архитектуры процессора под которую будет компилироваться ядро. По
умолчанию выбрана *Generic*, то есть такое ядро будет собираться под
абстрактную x86 архитектуру и при этом будет совместимо с любым
процессором, хоть AMD, хоть Intel. Главным же преимуществом именно
нативной компиляции любого ПО состоит в задействовании максимума
производительности конкретно под вашу архитектуру процессора, с
использованием всех доступных ему инструкций. А в случае с ядром это
особенно важно, ибо ядро это сердце операционной системы, и если его
нативно собрать под себя, то мы получаем существенный прирост и
отличный отклик системы. Поэтому начиная с главного окна настройки
перейдите в раздел *"Processor type and features"* и затем в
*"Processor family"*. Здесь выберите либо *"Intel-native
optimizations"* если у вас процессор Intel, либо *"AMD-native
optimizations"* если у вас процессор AMD, как это показано на
скриншотах ниже.

**1.1**

.. image:: images/processor-type-and-features-entry.png

**1.2**

.. image:: images/processor-family.png

**1.3**

.. image:: images/processor-family-choice.png

(**Важно**: автор выбрал здесь Intel-native, но **если у вас процессор от AMD выбирайте только AMD-native** )

**2.** Изменим поведение таймера ядра. У ядра есть настройка режимов
работы таймера прерываний, который отвечает за переключение процессора
(ядра процессора) на выполнение другой задачи (процесса) через каждые
N ГЦ (обычно просто тик), в нашем случае это 1000 Гц (см. ниже).
Уменьшение количества тиков во времени - это то к чему стоит
стремиться если вам важна энергоэффективность, ибо каждое прерывание
является достаточно энергозатратным и не всегда имеет смысл. Поэтому
придумали несколько режимов работы таймера:

1. Переодические тики - таймер прерываний работает всегда и при любых
   условиях, даже если процессор простаивает и ничего не делает.

2. Idle Dynticks (дословно Холостые динамические тики) - таймер
   прерываний срабатывает только тогда, когда процессор чем-то занят,
   но не тогда когда он простаивает. Как следствие это приводит к
   меньшему энергопотреблению и устраняет "холостую" работу таймера.
   Чтобы вы понимали, ядро с переодическими тиками разрядит свою
   батарею очень быстро, в 2-3 раза быстрее, чем то же самое
   устройство, на котором запущено ядро с Idle Dynticks. Однако у
   этого режима есть накладные расходы в виде большего количества
   инструкций, которые выполняются при выходе из режима "ожидания"
   (когда процессор ничем не занят) в режим работы таймера.

В принципе, описание уже этих двух режимов достаточно, но существует
ещё и третий вариант, созданный для узко специализированных задач -
это Full Dynticks (полные динамические тики), который является по сути
тем же Idle, но с одним отличием: прерывания таймера не происходят
если процессор выполняет одну единственную задачу, и нет других задач
для выполнения. Это может быть полезно если вы изолируете определенные
ядра процессора и выделите их для выполнения определенных процессов,
но не имеет смысла на настольных компьютерах и ноутбуках. Работает
только с использованием параметра ``nohz_full``, иначе ведет себя как
Idle.

Оптимальным выбором является Idle Dynticks, но если вы не заботитесь об
энергопотреблении вашего ПК, то можно использовать и переодические
тики.

Подробнее об настройке таймера прерываний вы можете прочитать в
официальной документации ядра:

https://docs.kernel.org/timers/no_hz.html

**2.1**

.. image:: images/general-menu.png

**2.2**

.. image:: images/timer-subsystem-1.png

**2.3**

.. image:: images/timer-subsystem-2.png

**2.4**

.. image:: images/timer-subsystem-3.png

**3.** Просим вас удостовериться в значениях частоты вашего таймера.
Это как раз то самое N через которое происходит тик таймера и
последующее за ним прерывание. Рекомендуемое значение для домашнего
ПК/Ноутбука это 1000. Однако если вы имеете многоядерный процессор (12
и более потоков) или какой-нибудь серверный Intel Xeon, то вы можете
попробовать установить частоту ниже 1000.

**3.1**

.. image:: images/processor-type-and-features-entry.png

**3.2**

.. image:: images/timer-freqency.png

**3.3**

.. image:: images/timer-freqency-choice.png

**4.** Рекомендуем вам отключать отладочные функции ядра. Они тоже
имеют свои накладные расходы и в большинстве случаев вы ими
пользоваться никогда не будете, а на крайний случай у вас должно быть
установлено ядро linux-lts как запасной аэродром. Для их отключения из
главного меню перейдите в *"Kernel Hacking"* и сделайте там все так,
как показано на скриншотах:

.. note:: Обращаем ваше внимание на то, что на некоторых ядрах не все
   возможные отладочные параметры могут быть отключены. Но вы
   можете ими пренебречь.

**4.1**

.. image:: images/kernel-hacking.png

**4.2**

.. image:: images/kernel-debugging.png

**5.** Обладателям видеокарт NVIDIA советуем отключить поддержку
фирменного фреймбуфера, как бы странно это не звучало. Это позволит
вам избежать проблемы конфликта фреймбуфера ядра и фреймбуфера
бинарного драйвера NVIDIA. Сделайте это как показано ниже:

**5.1**

.. image:: images/kernel-device-drivers.png

**5.2**

.. image:: images/kernel-graphics-support.png

**5.3**

.. image:: images/kernel-fb-devices-choice.png

**5.4**

.. image:: images/kernel-fb-devices.png

**5.5**

.. image:: images/kernel-nvidia-fb.png

.. index:: kernel, clang, lto native-compilation
.. _kernel-with-clang-lto:

===================================
Сборка ядра с помощью Clang + LTO
===================================

В разделе `"Общее ускорение системы"
<https://ventureo.codeberg.page/source/generic-system-acceleration.html#clang>`_
мы уже говорили о преимуществах сборки пакетов при помощи компилятора
Clang вместе с LTO оптимизациями. Но ядро требует отдельного
рассмотрения, ибо те параметры которые мы указали ранее в makepkg.conf
не работают для сборки ядра, и потому по прежнему будут применяться
компиляторы GCC.

Чтобы активировать сборку ядра через Clang нужно:

- Для ядра linux-cachyos экспортировать данную переменную окружения
  перед выполнением команды сборки: ``export _use_llvm_lto=thin`` или
  ``export _use_llvm_lto=full``. См. ниже для подробностей.
- Для ядра linux-tkg в конфигурационном файле *customization.cfg*
  включить параметр *_compiler="llvm"* (В том же файле можно настроить
  применение LTO оптимизаций через параметр *_lto_mode*. О режимах LTO
  читайте далее).
- Для всех остальных ядер, устанавливаемых из AUR, нужно просто экспортировать переменные окружения
  *LLVM=1* и *LLVM_IAS=1* перед командой сборки::

    export LLVM=1 LLVM_IAS=1 # Без переменной LLVM_IAS станет невозможным применение LTO оптимизаций
    makepkg -sric            # Сборка и установка желаемого ядра

Теперь перейдем к выбору режима LTO.
Для этого на этапе конфигурации вашего ядра зайдите в *"General architecture-dependent options"* ->
*"Link Time Optimization (LTO)"* как показано на изображениях:

1.

.. image:: images/custom-kernels-17.png

2.

.. image:: images/custom-kernels-18.png

3.

.. image:: images/custom-kernels-19.png

На последнем изображении показано окно выбора режима применения LTO оптимизаций.
Этих режимов всего два:

1. Полный (Full): использует один поток для линковки, во время сборки медленный и использует больше памяти,
   но теоретически имеет больший прирост производительности в работе уже готового ядра.
2. Тонкий (Thin): работает в несколько потоков, во время сборки быстрее и использует меньше памяти, но может иметь более низкую производительность в итоге чем *Полный (Full)* режим.

Мы рекомендуем использовать *"Полный (Full)"* режим чтобы получить в итоге лучшую производительность.

.. attention:: Сборка ядра через Clang работает только с версией ядра 5.12 и выше!

Больше подробностей по теме вы можете найти в данной статье:

https://habr.com/ru/company/ruvds/blog/561286/

.. vim:set textwidth=70:
