Table of Contents
Оптимизированная компиляция ядра Linux
Введение
Ощути силу открытого кода - пользуйся наиболее качественным ПО!
InitRD не нужен
Подготовка
Скачать исходники ядра нужной версии
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.10.194.tar.xz
Распаковать архив
tar -xf linux-5.10.194.tar.xz
Установить необходимые для сборки пакеты (вариант для ALT Linux)
sudo apt-get install -y libssl-devel libelf-devel /usr/bin/x86_64-alt-linux-gcc ncurses-devel /usr/bin/flex /usr/bin/bison /usr/bin/pahole zlib-devel bc openssl
Параметры компилятора
Можно собрать ядро под конкретный процессор, чтобы в машинном коде были сгенерированы наиболее оптимальные алгоритмы, и были задействованы самые быстрые команды для данного процессора. Для этого откройте Makefile и допишите в переменную KBUILD_USERCFLAGS параметры
"-march=native -flto -O3 -s"
При использовании последнего могут быть дефекты, для надежности лучше компилировать с O2.
Как сконфигурировать ядро
На данном этапе можно избавиться от модулей, ненужных на вашем оборудовании, и вкомпилировать в само ядро только те модули, которые точно нужны.
Если вы уверены, что все модули, которые могут вам когда-либо пригодиться, на данный момент подгружены ядром, выполните
Перед выполнением команды lsmod выполните следующую команду, чтобы ядро точно подгрузило модули, отвечающие за работу с жёстким диском
badblocks -v /dev/sda -o /tmp/bad_sectors.txt
Способ 1 (рабочий)
Используя этот способ можно отказаться от initrd
Взять за основу конфигурацию изначального ядра
sudo cp /boot/config-5.10.194-std-def-alt1 .config
Включить в само ядро действительно необходимые модули (в том числе драйвер дисковой подсистемы)
lsmod > mylsmod make LSMOD=./mylsmod localyesconfig
Недостатки
Образ ядра получается довольно большим, ведь включённых в него модулей не убавилось, а наоборот. Конфигурация ядра, поставляемого вендорами, которая была взята за основу, в большой степени избыточна, но она покрывает потребности большинства пользователей. Ввиду этого образ ядра в памяти может занимать от десяти (это много) до нескольких десятков мегабайт.
Способ 2
Используя этот способ можно получить в разы более компактный образ ядра и также отказаться от initrd
Взять за основу конфигурацию изначального ядра
sudo cp /boot/config-5.10.194-std-def-alt1 .config
Вынести в модули всё, что можно
make yes2modconfig
Включить в само ядро действительно необходимые модули (в том числе драйвер дисковой подсистемы)
lsmod > mylsmod make LSMOD=./mylsmod localyesconfig
Способ 3
(будет более компактная конфигурация)
Взять за основу минимальную конфигурацию для определённой платформы
make ${PLATFORM}_defconfig
Доступные конфигурации платформ находятся в arch/x86/configs/
make x86_64_defconfig
Вынести в модули всё, что можно. В данной случае, скорее всего ничего не будет вынесено в модули
make yes2modconfig
Включить в само ядро действительно необходимые модули (в том числе драйвер дисковой подсистемы)
make LSMOD=./mylsmod localyesconfig
Интерактивный конфигуратор
С исходниками ядра поставляется несколько консольных и графических утилит для конфигурирования сборки. Одна из таких
make menuconfig
С её помощью вы можете вручную включить нужные модули прямо в ядро (нажать “y”), скомпилировать их отдельными файлами (“m”), вообще не компилировать (“n”), читать справку по каждому пункту (“?”), искать нужные пункты (“/”).
Сборка
Отключение отладочной информации (может на порядоки уменьшить размер ядра)
scripts/config --disable DEBUG_INFO
Мультипоточная компиляция (опция V=1 показывает процесс компиляции в подробном виде)
make -j`nproc` V=1
Установка
sudo make modules_install ls /lib/modules/5.8.18 sudo make install sudo ls -l /boot/initrd.img /boot/vmlinuz
При необходимости исправьте параметры вашего загрузчика
Сравнение нового и обычного ядра
TODO: Сравнить
- размеры ядер в сжатом виде и в памяти (после загрузки)
- скорость загрузки системы после включения
- скорость работы прикладных программ
Проблемы
Ошибка линковки
LD .tmp_vmlinux.kallsyms1 ld: net/ipv6/rpl_iptunnel.o: в функции «rpl_build_state»: rpl_iptunnel.c:(.text+0x218): неопределённая ссылка на «dst_cache_init» ld: net/ipv6/rpl_iptunnel.o: в функции «rpl_input»: rpl_iptunnel.c:(.text+0x658): неопределённая ссылка на «dst_cache_get» ld: rpl_iptunnel.c:(.text+0x770): неопределённая ссылка на «dst_cache_set_ip6» ld: net/ipv6/rpl_iptunnel.o: в функции «rpl_output»: rpl_iptunnel.c:(.text+0x817): неопределённая ссылка на «dst_cache_get» ld: rpl_iptunnel.c:(.text+0x9d5): неопределённая ссылка на «dst_cache_set_ip6» ld: net/ipv6/rpl_iptunnel.o: в функции «rpl_destroy_state»: rpl_iptunnel.c:(.text+0x6a): неопределённая ссылка на «dst_cache_destroy» make: *** [Makefile:1207: vmlinux] Ошибка 1
Компиляция модуля net/ipv6/rpl_iptunnel.o прошла успешно, но по какой-то причине не скомпилировался модуль, в котором описаны функции dst_cache* - это модуль net/core/dst_cache.c. Проблема решается правкой net/core/Makefile, в котором надо явным образом указать, что необходимо получить объектный модуль dst_cache.o.
Параметры, передаваемые ядру для загрузки без initrd
Вариант рабочей конфигурации загрузчика LILO
### LILO global section ###
#large-memory
lba32
boot = /dev/sda
map = /boot/map
install = menu
menu-scheme = Wb:Yr:Wb:Wb
prompt
compact
timeout = 30
vga = ext
image = /boot/vmlinuz-5.10.209
label = "Linux_without_initrd"
read-only
# root = "UUID=16380cb2-f454-444e-ab6e-816470e32fa8"
root = /dev/sda2
По какой-то причине ядро не понимает параметр “root = “UUID=16380cb2-f454-444e-ab6e-816470e32fa8”, однако понимает “root = /dev/sda2”.
Кстати, для загрузки вместе с initrd параметр root можно не указывать.
TODO: Попробовать загрузиться через Grub
Неявным образом пропадает поддержка файловых систем и не монтируются флешки
TODO
Официальная документация по компиляции (статья совсем небольшая)
https://www.kernel.org/doc/readme/Documentation-admin-guide-README.rst
Также может помочь
make help
Другие материалы


