Product SiteDocumentation Site

8.10. Компиляция Ядра

Включаемые в дистибутивы Debian ядра содержат в себе максимально количество функциональных возможностей, а также максимум драйверов. В результате этого становится возможным с помощью ядра настроить как можно больше аппаратных устройств уже на стадии установки, загрузки и дальнейшей эксплуатации системы (которые могут быть установлены на компьютерах пользователей. Большинство их такая ситуация устраивает - максимально опознаются аппаратные средства, а расточительное использование ресурсов компьютера для них не критично). Но некоторые предпочитают перекомпилировать (пересобрать) ядро, включив в них только то, что им действительно нужно. Для такого подхода имеются две причины. Первая - возможность оптимизации использования физической памяти (RAM) поскольку код ядра постоянно находится в ней (и никогда не “выгружается”, даже часть его, на файл подкачки). Избыточное использование ядром физической памяти (а она недёшева, и её часто не хватает на компьютерах пользователей) может уменьшить общую производительность системы. Вторая причина - локально скомпилированные ядра помогут снизить риск проблем безопасности. За счёт исключения ненужного (только незначительное количество кода ядра будет включено в состав ядра, скомпилировано и в дальнейшем выполняться) в конечном итоге повысится защищённость и производительность системы.
Перекомпиляция ядра необходима также, если вы хотите использовать некоторые особенности, которые доступны только как заплатки (и не включены в стандартную версию ядра).

8.10.1. Введение и предпосылки

Неудивительно, что в Debian управление ядром организовано в виде готового пакета, а не как ранее - традиционная компиляция и устанавка вручную. Поскольку ядро (в составе пакета) всегда остается под контролем системы управления пакетами, то удаление или установка ядра на одной, или на нескольких машинах сразу, выполняется чисто. Кроме того, в пакетах кроме ядра имеются ещё и сценарии, автоматизирующие процесс подключения устанавливаемого ядра в загрузчик и создающие образ initrd для загрузки.
Скачиваемый из хранилища Debian пакет с исходным кодом ядра Linux содержит в себе всё необходимое для построения Debian пакета, включающего в себя скомпилированное вами ядро. Но кроме этого, рекомендуется проверить установлены ли у вас пакеты вспомогательного назначения (которые необходимо доустановить, если они отсутствуют в вашей системе). К ним относятся: 1) пакет build-essential. 2) Для этапа конфигурирования ядра нужен пакет libncurses5-dev. 3) С помощью пакета fakeroot создаются условия сборки Debian пакета не прибегая к правам администратора.

8.10.2. Получение исходного кода

Как и все остальные програмы, что используются для установки в Debian систему, исходные коды ядра Linux доступны в форме созданного пакета. Для получения его из хранилища, установите пакет linux-source-version (после "тире" дополните нужной вам версией, из числа имеющихся в хранилищах). Команда apt-cache search ^linux-source выполнит поиск по регулярному выражению пакетов Debian с различными версиями ядра. Последняя версия доступна в дистибутиве Unstable: вы можете получить её без большого риска (особенно, если ваш APT настроен в соответствии с инструкциями в разделе Раздел 6.2.6, «Работа с отдельными дистрибутивами»). Обратите внимание, что исходные коды, включённые в пакет Debian, не являются точной копией ядра, публикуемого авторами - разработчиками Линусом Торвальдсом и другими. Подобно и другим дистибутивам, Debian также применяет некоторое количество заплаток, которые в дальнейшем могут быть включены (или нет) в следующую (более новую) версию стандартного ядра их оригинальными разработчиками. Изменения, содержащиеся в заплатках, включают в себя части кода из новой версии ядра, касаемые 1) фиксирования исправлений ранее существовавших ошибок, 2) новых или изменённых возможностей, появившихся в ядре, 3) драйверов аппаратной части компьютера, 4) новые возможности, которые ещё не включены (полностью) в вышерасположенный каталог ядра Linux, и 5) иногда ещё кое-какие специфические изменения, касаемые непосредственно изменений дистибутива Debian.
В оставшейся части этого раздела речь пойдёт о версии Linux ядра 3.16, но вы можете их также использовать с той версией ядра, с какой хотите.
Мы полагаем (для целей демонстрациии примеров), что пакет linux-source-3.16 у вас установлен. В составе пакета имеется архив /usr/src/linux-source-3.16.tar.xz, в котором в сжатом виде хранятся коды ядра. Вы должны извлечь эти файлы в новый каталог (но не напрямую в каталог /usr/src/, а в тот каталог, где нет особых требований к правам доступа для компиляции Linux ядра): целесообразно назвать его ~/kernel/.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xaf /usr/src/linux-source-3.16.tar.xz

8.10.3. Настройка ядра

Следующий шаг содержит настройку ядра в соответствии с вашими потребностями. Более точный алгоритм работы зависит от ваших целей.
При перекомпиляции более современной версии ядра (возможно с дополнительными заплатками), конфигурация ядра должна быть как можно ближе к тому, что предлагает Debian. В этом случае достаточно просто скопировать файл /boot/config-version (узнать версию ядра, работающего сейчас на вашем компьютере, можно командой uname -r command) в новый файл с именем .config, разместив его в каталог, содержащий исходные коды ядра. Это будет намного быстрее чем пересобрать ядро с нуля.
$ cp /boot/config-3.16.0-4-amd64 ~/kernel/linux-source-3.16/.config
Если вам не нужно изменять конфигурацию ядра, вы можете остановиться здесь и пропустить раздел Раздел 8.10.4, «Компиляция и Сборка Пакета». В противном случае, если необходимо внести изменения в конфигурацию ядра или вы решили сами всё настроить с нуля, то необходимо выделить достаточно время на эту работу. В каталоге с исходными кодами ядра присутствуют и различные специальные интерфейсы, которые могут быть использованы посредством вызова команды make target, где в качестве target выступает одно из значений, описанных ниже.
make menuconfig компилирует и выполняет в псевдографическом интерфейсе (для этого необходимо установить пакет libncurses5-dev). В программе можно передвигаться и выбирать опции в иерархической структуре. Нажатием клавиши Space изменяется значение выбираемой опции, а нажатием Enter войти внутрь того названия, на котором расположен в тот момент указатель; кнопка интерфейса Select возвращает на выбранное подменю; Exit закрывает настоящий экран и сдвигает позицию курсора назад по иерархии; Help отобразит более детальную информацию о роли выбранной опции. Клавиши навигации позволяют передвигаться в списке опций и кнопок. Для выхода из программы выберете Exit из главного меню. В этот момент программа предложит сохранить сделанные изменения - если вы удовлетворены сделанными изменениями, то сохраните.
Другие интерфейсы имеют похожие функциональные возможности, но они работают в более современных графических оболочках; такие как make xconfig, которая использует графический интерфейс Qt, и make gconfig, использующий GTK+. Первый нуждается в пакете libqt4-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: 1) linux-image-version, который содержит образ ядра и связанные с ними модули, 2) linux-headers-version, который содержит заголовочные файлы, необходимые для сборки внешних модулей, 3) linux-firmware-image-version, который содержит файлы прошивки аппаратной части, нужные некоторым драйверам (эти пакеты могут отсутствовать, если вы строите из исходных кодов ядра, поддерживаемого Debian), 4) linux-image-version-dbg, который содержит символы отладки для образа ядра и его модулей, и 5) 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-3.16.7-ckt4-falcot_3.16.7-1_amd64.deb
../linux-image-3.16.7-ckt4-falcot_3.16.7-1_amd64.deb
../linux-image-3.16.7-ckt4-falcot-dbg_3.16.7-1_amd64.deb
../linux-libc-dev_3.16.7-1_amd64.deb

8.10.5. Компиляция Внешних Модулей (динамически загружаемые модули ядра)

Некоторые модули, не включённые в официальный проект ядра Linux, поддерживаются за его пределами. Чтобы была возможность их использовать, они должны быть скомпилированы рядом с соответствующим ядром. Определённое количество таких модулей поддерживается Debian путём включения их в специальные пакеты, такие как xtables-addons-source (дополнительные модули для iptables) или oss4-source (некоторые альтернативные звуковые драйверы).
Так как этих внешних модулей (и пакетов с ними) имеется великое множество и все они разные, то мы не будем перечислять их здесь все. Помощь вам может сослужить команда apt-cache search source$, которая проведёт поиск только по заголовкам пакетов (установленных и неустановленных в системе). Однако, знание полного перечня врешних модулей не принесёт вам большой пользы, поскольку в большинстве случаев компиляция внешних модулей не нужна, за редким исключением, когда вы сами знаете, что вам надо. В таких случаях, документация на аппаратное устройство, как правило, детально описывает, каким образом данный конкретный модуль функционирует под операционной системой 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 xtables-addons-dkms

[...]
Setting up xtables-addons-dkms (2.6-1) ...
Loading new xtables-addons-2.6 DKMS files...
First Installation: checking all kernels...
Building only for 3.16.0-4-amd64
Building initial module for 3.16.0-4-amd64
Done.

xt_ACCOUNT:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.16.0-4-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
xtables-addons, 2.6, 3.16.0-4-amd64, x86_64: installed
$ sudo modinfo xt_ACCOUNT
filename:       /lib/modules/3.16.0-4-amd64/updates/dkms/xt_ACCOUNT.ko
license:        GPL
alias:          ipt_ACCOUNT
author:         Intra2net AG <opensource@intra2net.com>
description:    Xtables: per-IP accounting for large prefixes
[....]

8.10.6. Установка Заплатки на Ядро

Некоторые особенности не включены в стандартное ядро из-за недостатка завершённости кода или некоторых разногласий с сопровождающими ядро. Они могут быть включены в отдельные заплатки и распространяться в таком виде (разработчиками заплатки). В дальнейшем кто угодно может установить такую заплатку на исходные коды ядра.
В Debian дистибутивах принято размещать такие заплатки в пакеты с наименованиями следующего вида: linux-patch-* или kernel-patch-* (для примера, заплатка linux-patch-grsecurity2 ужесточает политику безопасности в ядре). Эти пакеты устанавливают свои файлы в каталог /usr/src/kernel-patches/.
После установки в систему пакета с заплаткой, наложить её на исходные коды ядра можно следующей командой patch. В этот момент необходимо находиться курсором в каталоге с исходными кодами ядра (а сама заплатка должна находиться на один уровень выше). Пример: "xz -cd ../linux-patch-3.16-rt.patch.xz | patch -p1". Далее, перейдите к этапу конфигурирования нового ядра и его компилиляции, как было описано выше.
$ cd ~/kernel/linux-source-3.16
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.0-3.17.1-201410250027.patch.gz | patch -p1
Обратите внимание, что устанавливаемая заплатка не обязательно будет совместима с каждой версией ядра. Может случиться, что команда patch, при попытке наложить заплатку на исходные коды ядра, потерпит неудачу. Возникшие ошибки будут показаны и даны некоторые подробности, касательно возникшего сбоя. В этом случае, руководствуйтесь документацией, доступной в Debian пакете данной заплатки (в каталоге /usr/share/doc/linux-patch-*/). В большинстве случаев, сопровождающие заплаток указывают, для каких версий ядра они предназначены.