Включаемые в дистрибутивы Debian ядра содержат в себе максимально количество функциональных возможностей, а также максимум драйверов. В результате этого становится возможным с помощью ядра настроить как максимум аппаратных устройств уже на стадии установки, загрузки и дальнейшей эксплуатации системы. Но некоторые предпочитают перекомпилировать (пересобрать) ядро, включив только то, что им действительно нужно. Для такого подхода имеются две причины. Первая - возможность оптимизации использования физической памяти (RAM) поскольку код ядра постоянно находится в ней (и никогда не “выгружается”, даже частично, в файл подкачки). Избыточное использование ядром физической памяти (а она недёшева, и её часто не хватает на компьютерах пользователей) может уменьшить общую производительность системы. Вторая причина - локально скомпилированные ядра помогают снизить риск проблем безопасности. За счёт исключения ненужного (только незначительное количество кода ядра будет включено в состав ядра, скомпилировано и в дальнейшем выполняться) в конечном итоге повысится защищённость и производительность системы.
Перекомпиляция ядра необходима также, если вы хотите использовать некоторые особенности, которые доступны только в виде патчей (и не включены в стандартную версию ядра).
8.10.1. Введение и предпосылки
Неудивительно, что Debian управляет ядром в виде пакета, а ядра традиционно не компилируются и не устанавливаются. Поскольку ядро остается под контролем пакетного менеджера, его можно затем полностью удалить или развернуть на нескольких машинах. Кроме того, сценарии, связанные с этими пакетами, автоматизируют процесс подключения устанавливаемого ядра в загрузчик и генерацию образа initrd для загрузки.
Исходники исходного кода Linux содержат всё необходимое для сборки пакета ядра Debian. Но вам всё равно необходимо установить build-essential, чтобы убедиться, что у вас есть инструменты, необходимые для сборки пакета Debian. Кроме того, этап настройки ядра требует пакет libncurses-dev (ранее libncurses5-dev который теперь является переходным пакетом). Наконец, пакет fakeroot позволит создать пакет Debian без использования прав администратора.
8.10.2. Получение исходного кода
Как и всё, что может быть полезно в системе Debian, исходные коды ядра Linux доступны в пакете. Чтобы получить их, просто установите пакет
linux-source-version (после "тире" дополните нужной вам версией, из числа имеющихся в репозиториях). Команда
apt search ^linux-source
выполнит поиск по регулярному выражению пакетов Debian с различными версиями ядра. Последняя версия доступна в дистрибутиве
Unstable: вы можете получить её без большого риска (особенно, если ваш APT настроен в соответствии с инструкциями в разделе
Раздел 6.2.6, «Работа с несколькими дистрибутивами»). Обратите внимание, что исходный код, содержащийся в этих пакетах, не совсем соответствует коду, опубликованному Линусом Торвальдсом и разработчиками ядра; Как и все дистрибутивы, Debian применяет ряд исправлений, которые могут (а могут и не попасть) в основную версию Linux. Эти модификации включают в себя резервный перенос исправлений/функций/драйверов из более новых версий ядра, новые функции, которые ещё (полностью) не объединены с исходным деревом Linux, а иногда даже специфичные для Debian изменения.
Оставшаяся часть этого раздела посвящена версии ядра Linux 5.10, но примеры, конечно, можно адаптировать к конкретной версии ядра, которую вы хотите.
We assume the linux-source-6.1 package has been installed. It contains /usr/src/linux-source-6.1.tar.xz
, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/
, since there is no need for special permissions to compile a Linux kernel): ~/kernel/
is appropriate.
$
mkdir ~/kernel; cd ~/kernel
$
tar -xaf /usr/src/linux-source-6.1.tar.xz
Чтобы собрать ядро из чистых исходных кодов, просто загрузите tar-архив выбранной вами версии с сайта
kernel.org
, проверьте целостность после импорта ключа сопровождающего ядра, а затем действуйте, как описано в следующих главах.
8.10.3. Конфигурирование ядра
Следующий шаг заключается в настройке ядра в соответствии с вашими потребностями. Более точный алгоритм работы зависит от ваших целей.
При перекомпиляции более современной версии ядра (возможно с дополнительными заплатками), конфигурация ядра должна быть как можно ближе к тому, что предлагает Debian. В этом случае, вместо того, чтобы перенастраивать все с нуля, достаточно скопировать
/boot/config-version
(узнать версию ядра, работающего сейчас на вашем компьютере, можно командой
uname -r
) в новый файл с именем
.config
, разместив его в каталог, содержащий исходные коды ядра. В этом случае обязательно прочтите врезку
СОВЕТ Отсутствие debian/certs/debian-uefi-certs.pem
.
$
cp /boot/config-6.1.0-21-amd64 ~/kernel/linux-source-6.1/.config
Если вам не нужно изменять конфигурацию ядра, вы можете остановиться здесь и пропустить раздел
Раздел 8.10.4, «Компиляция и Сборка Пакета». В противном случае, если необходимо внести изменения в конфигурацию ядра или вы решили сами всё настроить с нуля, то необходимо выделить достаточно времени на эту работу. В каталоге с исходными кодами ядра присутствуют и различные специальные интерфейсы, которые могут быть использованы посредством вызова команды
make target
, где в качестве
target выступает одно из значений, описанных ниже.
make menuconfig
компилирует и выполняет в псевдографическом интерфейсе (для этого необходимо установить пакет libncurses-dev). В программе можно передвигаться и выбирать опции в иерархической структуре. Нажатие клавиши Space изменение значения выбираемой опции, а нажатие Enter вход внутрь выбранной опции; кнопка интерфейса Select возвращает на выбранное подменю; Exit закрывает настоящий экран и сдвигает позицию курсора назад по иерархии; Help отобразит более детальную информацию о роли выбранной опции. Клавиши со стрелками позволяют передвигаться в списке опций и кнопок. Для выхода из программы выберите Exit из главного меню. В этот момент программа предложит сохранить сделанные изменения - если вы удовлетворены сделанными изменениями, то сохраните их.
Другие интерфейсы имеют похожие функциональные возможности, но они работают в более современных графических оболочках; такие как make xconfig
, которая использует графический интерфейс Qt, и make gconfig
, использующий GTK+. Первый нуждается в пакете qtbase5-dev, в то время как второй зависит от наличия пакетов libglade2-dev и libgtk2.0-dev.
При использовании одного из этих интерфейсов конфигурации всегда полезно начинать с разумной конфигурации по умолчанию. Ядро предоставляет такие конфигурации в arch/arch/configs/*_defconfig
. Вы можете взять выбранную вами оттуда конфигурацию поместив её в новое место командой вроде make x86_64_defconfig
(в случае 64-битного ПК) или make i386_defconfig
(в случае 32-битного ПК). Программа скопирует .config из заготовленных разработчиками оптимальных конфигураций в каталог компиляции ядра.
8.10.4. Компиляция и Сборка Пакета
Как только конфигурация ядра будет готова, можно выполнить команду make deb-pkg
, которая сгенерирует до 5 пакетов Debian:
- linux-image-version
содержит образ ядра и связанные модули,
- linux-headers-version
содержит заголовочные файлы, необходимые для сборки внешних модулей,
- linux-firmware-image-version
содержит файлы прошивки, необходимые некоторым драйверам (этот пакет может отсутствовать при сборке из исходных кодов ядра, предоставленных Debian),
- linux-image-version-dbg
содержит символы отладки для образа ядра и его модулей (создаются только в том случае, еслиCONFIG_DEBUG_INFO=y
), и
- linux-libc-dev
содержит заголовочные файлы, относящиеся к некоторым библиотекам пользовательского пространства, таким как GNU glibc.
Суффикс, добавляемый в конце к названию ядра, version определяется путем объединения исходной версии (как определено переменными VERSION
, PATCHLEVEL
, SUBLEVEL
и EXTRAVERSION
в Makefile
), LOCALVERSION
конфигурационного параметра и переменной окружения LOCALVERSION
. Версия пакета повторно использует одну и ту же строку версии с добавленной ревизией, которая регулярно увеличивается (и сохраняется в .version
), за исключением случаев, когда вы переопределите его с помощью переменной окруженияKDEB_PKGVERSION
.
$
make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$
ls ../*.deb
../linux-headers-5.10.46-falcot_5.10.46-1_amd64.deb
../linux-image-5.10.46-falcot_5.10.46-1_amd64.deb
../linux-image-5.10.46-falcot-dbg_5.10.46-1_amd64.deb
../linux-libc-dev_5.10.46-1_amd64.deb
Весь процесс требует около 20 ГБ свободного места, не менее 8 ГБ ОЗУ и несколько часов компиляции (с использованием одного ядра) для стандартного ядра Debian amd64. Эти требования можно значительно снизить, отключив отладочную информацию с помощью CONFIG_DEBUG_INFO=n
, но это сделает невозможным отслеживание ошибок ядра («oops») с помощью команды gdb
, а также остановит создание пакета linux-image-version-dbg.
8.10.5. Компиляция Внешних Модулей (динамически загружаемые модули ядра)
Некоторые модули, не включённые в официальный проект ядра Linux, поддерживаются за его пределами. Чтобы была возможность их использовать, они должны быть скомпилированы рядом с соответствующим ядром. Определённое количество таких модулей поддерживается Debian путём включения их в специальные пакеты, такие как vpb-driver-source (дополнительные модули для аппаратной Voicetronix телефонии) или leds-alix-source (драйвер PCEngines ALIX 2/3 плат).
Эти пакеты многочисленны и разнообразны, команда apt-cache rdepends module-assistant$
может показать список, предоставленный Debian. Однако полный список не особенно полезен, поскольку нет особой причины для компиляции внешних модулей, за исключением тех случаев, когда вы знаете, что они вам нужны. В таких случаях в документации устройства обычно подробно описывается конкретный модуль(-и), который необходим для работы под Linux.
Для примера, давайте рассмотрим пакет xtables-addons-source: после его установки появится архив исходного кода модуля .tar.bz2
, располагающийся в каталоге /usr/src/
. Далее можно было бы вручную извлечь данные из архива и построить модуль, но на практике предпочтительным способом является использование DKMS (инфраструктура для поддержки динамически загружаемых модулей ядра). Пакеты, название которых оканчивается на суффикс -dkms
, предлагаются для большинства модулей, которым необходима интеграция с ядром через DKMS. В приведённом примере, установка пакета xtables-addons-dkms добавит всё необходимое, что нужно для компиляции внешнего модуля для настоящего ядра. Обратите только внимание, чтобы был установлен и пакет linux-headers-*, соответствующий версии ядра. Например, если вы используете linux-image-amd64, то вам необходимо доустановить и пакет linux-headers-amd64.
$
sudo apt install dahdi-dkms
[...]
Setting up dkms (3.0.10-8+deb12u1) ...
Setting up linux-compiler-gcc-12-x86 (6.1.99-1) ...
Setting up fxload (0.0.20081013-2) ...
Setting up linux-headers-6.1.0-23-common (6.1.99-1) ...
Setting up linux-kbuild-6.1 (6.1.99-1) ...
Setting up dahdi-dkms (1:2.11.1.0.20170917~dfsg-8.4) ...
Loading new dahdi-2.11.1.0.20170917 DKMS files...
Building for 6.1.0-23-amd64
Building initial module for 6.1.0-23-amd64
Done.
dahdi_dummy.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/6.1.0-23-amd64/updates/dkms/
dahdi_dynamic_eth.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/6.1.0-23-amd64/updates/dkms/
[..]
depmod...
Setting up dahdi-linux (1:2.11.1.0.20170917~dfsg-8.4) ...
Setting up linux-headers-6.1.0-23-amd64 (6.1.99-1) ...
/etc/kernel/header_postinst.d/dkms:
dkms: running auto installation service for kernel 6.1.0-23-amd64.
dkms: autoinstall for kernel: 6.1.0-23-amd64.
Setting up linux-headers-amd64 (6.1.99-1) ...
Processing triggers for man-db (2.11.2-2) ...
$
sudo dkms status
dahdi/2.11.1.0.20170917, 6.1.0-23-amd64, x86_64: installed
$
sudo modinfo dahdi_dummy
filename: /lib/modules/6.1.0-23-amd64/updates/dkms/dahdi_dummy.ko
license: GPL v2
author: Robert Pleh <robert.pleh@hermes.si>
description: Timing-Only Driver
depends: dahdi
retpoline: Y
name: dahdi_dummy
vermagic: 6.1.0-23-amd64 SMP preempt mod_unload modversions
sig_id: PKCS#7
signer: DKMS module signing key
sig_key: 69:A6:CA:D5:86:6A:FE:F4:A8:04:6A:31:8B:AB:E1:07:88:BA:45:C7
sig_hashalgo: sha256
signature: 9B:F9:8E:38:4D:06:A6:20:52:33:D9:AE:9D:B9:83:17:BB:5A:18:F1:
F2:5B:F3:12:06:0A:1D:48:C3:BA:89:2C:40:64:1C:2C:52:7C:46:BE:
27:49:F5:55:42:1B:71:38:A2:1B:FA:58:BB:CE:7C:70:2C:EC:37:7B:
65:91:A1:E7:23:6E:B6:92:9D:B9:20:43:F5:39:7F:95:CA:36:DC:C0:
DA:82:49:AC:21:69:65:DF:5D:0F:C5:8F:E5:E6:92:76:F1:DD:18:7E:
91:D2:DC:43:86:CA:5B:66:7C:FF:AE:EA:F9:06:F8:55:4A:1F:C0:56:
8B:F7:6C:9E:77:35:9B:E0:14:9D:C4:68:D8:5E:FD:3F:53:73:F1:B6:
12:67:9E:F4:68:48:C8:A7:80:69:42:01:83:52:D8:EF:54:FE:11:E4:
63:3C:6F:B3:B6:BF:E9:4F:DF:52:C4:A7:6B:35:D6:3B:C9:E2:FD:48:
70:41:D1:D1:68:4C:D4:12:7F:CB:7D:92:E5:E6:79:4A:5B:5E:7C:38:
1D:98:B2:EF:0E:F3:8D:07:1B:51:75:2A:58:2E:F2:53:BA:6A:79:F5:
AD:D1:12:08:E1:15:EC:5C:7A:CF:99:A2:9B:DB:BB:C0:EE:BD:C0:96:
77:92:D7:CC:68:14:A2:61:E0:F2:65:64:54:70:B8:73
parm: debug:int
8.10.6. Наложение патча на ядро
Некоторые особенности не включены в стандартное ядро из-за недостатка завершённости кода или некоторых разногласий с сопровождающими ядро. Они могут быть включены в отдельные патчи и распространяться в таком виде (разработчиками патча). В дальнейшем кто угодно может установить такой патч на исходные коды ядра.
Debian иногда предоставляет некоторые из этих патчей в пакетах linux-patch-*, но они часто не попадают в стабильные выпуски ядра (иногда по тем же причинам, по которым они не объединены в официальные исходные выпуски). Эти пакеты устанавливают файлы в каталог /usr/src/kernel-patches/
.
Чтобы применить один или несколько из этих установленных патчей, используйте команду patch
в каталоге источников, а затем запустите компиляцию ядра, как описано выше. Ниже показан старый пример linux-patch-grsecurity2 и linux-source-4.9.
$
cd ~/kernel/linux-source-4.9
$
make clean
$
zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1
Обратите внимание, что устанавливаемый патч не обязательно будет совместим с каждой версией ядра. Может случиться, что команда patch
, при попытке наложить патч на исходные коды ядра, потерпит неудачу. Возникшие ошибки будут показаны и даны некоторые подробности, касательно возникшего сбоя. В этом случае, руководствуйтесь документацией, доступной в Debian пакете данного патча (в каталоге /usr/share/doc/linux-patch-*/
). В большинстве случаев, сопровождающие патчей указывают, для каких версий ядра они предназначены.