Включаемые в дистрибутивы Debian ядра содержат в себе максимально количество функциональных возможностей, а также максимум драйверов. В результате этого становится возможным с помощью ядра настроить как максимум аппаратных устройств уже на стадии установки, загрузки и дальнейшей эксплуатации системы. Но некоторые предпочитают перекомпилировать (пересобрать) ядро, включив только то, что им действительно нужно. Для такого подхода имеются две причины. Первая - возможность оптимизации использования физической памяти (RAM) поскольку код ядра постоянно находится в ней (и никогда не “выгружается”, даже частично, в файл подкачки). Избыточное использование ядром физической памяти (а она недёшева, и её часто не хватает на компьютерах пользователей) может уменьшить общую производительность системы. Вторая причина - локально скомпилированные ядра помогают снизить риск проблем безопасности. За счёт исключения ненужного (только незначительное количество кода ядра будет включено в состав ядра, скомпилировано и в дальнейшем выполняться) в конечном итоге повысится защищённость и производительность системы.
Перекомпиляция ядра необходима также, если вы хотите использовать некоторые особенности, которые доступны только в виде патчей (и не включены в стандартную версию ядра).
8.10.1. Введение и предпосылки
Unsurprisingly, Debian manages the kernel in the form of a package, which is not how kernels have traditionally been compiled and installed. Since the kernel remains under the control of the packaging system, it can then be removed cleanly, or deployed on several machines. Furthermore, the scripts associated with these packages automate the interaction with the bootloader and the initrd generator.
Исходники исходного кода 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-5.10 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-*/
). В большинстве случаев, сопровождающие патчей указывают, для каких версий ядра они предназначены.