Блог "Дети ОИТа"
/поиск

Сборка ядра Linux из исходных текстов

Сборка ядра Linux из исходных текстов позволяет настроить функциональность под конкретное оборудование, удалить ненужные модули, применить оптимизации (включая профильную оптимизацию PGO). В этой стат

Сборка ядра Linux из исходных текстов позволяет настроить функциональность под конкретное оборудование, удалить ненужные модули, применить оптимизации (включая профильную оптимизацию PGO). В этой статье описывается процесс получения конфигурации, включения параметров, выбора компилятора (GCC или LLVM/Clang), установки собранного ядра, а также продвинутая техника PGO (Profile‑Guided Optimization) с использованием Clang и AutoFDO.

1.1. Английские сокращения

Сокращение Английское обозначение Русское обозначение
——— —————————————- ——————————————
PGO Profile‑Guided Optimization Профильная оптимизация
AutoFDO Automatic Feedback‑Directed Optimization Автоматическая оптимизация по обратной связи
LLVM Low Level Virtual Machine Низкоуровневая виртуальная машина
GCC GNU Compiler Collection Коллекция компиляторов GNU
CFLAGS Compiler Flags Флаги компилятора
LTO Link‑Time Optimization Оптимизация во время линковки
IR Intermediate Representation Промежуточное представление
perf Performance counters (Linux tool) Счётчики производительности
BTF BPF Type Format Формат типов BPF
ESP EFI System Partition Системный раздел EFI

1.2. Русские сокращения

Сокращение Обозначение
——— ———————–
ПО Профильная оптимизация
СК Счётчики производительности
ИЯ Исходный код ядра
КФГ Конфигурация ядра
КМ Компиляция модулей

2.1. Использование текущей работающей конфигурации

Самый простой способ получить .config для сборки – взять конфиг текущего работающего ядра (если оно скомпилировано с поддержкой `IKCONFIG`).

cp /proc/config.gz .
gzip -d config.gz
mv config .config

Или через zcat:

zcat /proc/config.gz > /usr/src/linux/.config

2.2. Права на исходный код

Для работы с исходниками удобно установить владельца (в примере пользователь `art`, группа `users`).

doas chown -R art:users ../linux-6.18.2-gentoo

3.1. GCC (стандартный)

make -j$(nproc)

3.2. LLVM/Clang (сборка полностью через LLVM)

LLVM=1 make -j$(nproc)

Преимущества LLVM: более быстрая компиляция, поддержка PGO, лучшая интеграция с инструментами статического анализа.

Обычно конфигурирование происходит через make nconfig , команда предоставляет удобный TUI. Но часто, быстрее выполнить настройку через скрипты ядра, если точно знаешь названия параметров.

4.1. Скрипт `scripts/config`

Утилита `scripts/config` позволяет изменять параметры ядра без ручного редактирования .config.

cd /usr/src/linux-7.0.12
./scripts/config --enable CONFIG_IP_NF_TARGET_REJECT    # для включения
./scripts/config --disable CONFIG_NET_ACT_POLICE        # для выключения

Для автоматического отключения параметров по маске

grep -E '^CONFIG\_.\*INTEL' .config \| cut -d= -f1 \| while read opt; do ./scripts/config –disable "\$opt"; done

4.2. Обновление конфигурации

После изменений необходимо запустить `make oldconfig` для разрешения новых зависимостей.

make oldconfig

5.1. Установка модулей

make modules_install

5.2. Установка ядра и загрузчика

make install

Обычно `make install` копирует ядро в `/boot`, обновляет `initramfs` и (при наличии) запускает `update-grub` или `grub-mkconfig`.

6.1. Настройка счётчиков производительности (perf)

Для сбора профиля требуется разрешить пользовательский доступ к счётчикам.

doas sh -c "echo 0 > /proc/sys/kernel/kptr_restrict"
doas sh -c "echo 0 > /proc/sys/kernel/perf_event_paranoid"

6.2. Сбор профиля во время компиляции ядра

Запускаем сборку ядра под управлением `perf record` для захвата ветвлений.

perf record -e ex_ret_brn_tkn:k -a -N -b -c 500009 -o kernel.data -- time make -j12

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

6.3. Проверка количества сэмплов

perf report -i *.data | head -8

6.4. Создание профиля AutoFDO

Используйте утилиту `create<sub>llvm</sub>_prof` (доступна в репозиториях или собирается отдельно).

./create_llvm_prof-x86_64-v0.30.1/create_llvm_prof \
    --binary=/usr/src/linux-6.18.0-gentoo/vmlinux \
    --profile=~/linux-build.data \
    --format=extbinary \
    --out=~/linux-build.afdo

6.5. Пересборка ядра с применением профиля

make clean && make LLVM=1 LLVM_IAS=1 CLANG_AUTOFDO_PROFILE=~/kernel-compilation.afdo -j"$(nproc)"

7.1. Полная очистка

make clean          # очищает объектные файлы, но оставляет .config
make mrproper       # удаляет .config и всё, возвращает в состояние дистрибутива

7.2. Удаление старых модулей

Перед установкой нового ядра можно удалить модули старой версии:

rm -rf /lib/modules/$(uname -r)

Если новое ядро не загружается, можно выбрать предыдущую версию в загрузчике (GRUB, systemd-boot, rEFInd). Если загрузчик не обновил записи автоматически, выполните:

  • Для GRUB: `sudo update-grub`
  • Для systemd-boot: `sudo bootctl update`

Для удаления проблемного ядра:

sudo rm /boot/vmlinuz-<problem_version>
sudo rm -rf /lib/modules/<problem_version>
sudo update-grub

9.1. Флаги компилятора

Можно задать дополнительные CFLAGS через переменную окружения `KCFLAGS`:

KCFLAGS="-march=native -O3" make -j$(nproc)

Это требует тестирования, не стоит применять бездумно. В некоторых случаях может сделать хуже стандартного O2.

9.2. Link‑Time Optimization (LTO)

Для GCC: `make LTO=1`
Для LLVM: `LLVM=1 LLVM<sub>IAS</sub>=1 LTO=thin`

9.3. Ядро с поддержкой BTF (для BPF)

Включите CONFIG_DEBUG_INFO_BTF=y.

10.1. Полный цикл сборки с PGO


cd /usr/src/linux
cp /proc/config.gz . && gunzip config.gz && mv config .config
make olddefconfig


./scripts/config --enable CONFIG_IP_NF_TARGET_REJECT
make oldconfig


sudo sh -c "echo 0 > /proc/sys/kernel/kptr_restrict"
sudo sh -c "echo 0 > /proc/sys/kernel/perf_event_paranoid"


perf record -e ex_ret_brn_tkn:k -a -N -b -c 500009 -o kernel.data -- make -j12


create_llvm_prof --binary=vmlinux --profile=kernel.data --format=extbinary --out=kernel.afdo


make clean && make LLVM=1 LLVM_IAS=1 CLANG_AUTOFDO_PROFILE=kernel.afdo -j$(nproc)


sudo make modules_install
sudo make install

Сборка ядра из исходных текстов даёт полный контроль над конфигурацией и оптимизацией. Использование PGO с Clang позволяет дополнительно ускорить часто выполняемые пути кода за счёт профильной информации. Инструменты `scripts/config`, `perf`, `create<sub>llvm</sub>_prof` автоматизируют процесс. Регулярная пересборка ядра с новыми патчами и оптимизациями – задача для опытных пользователей, желающих выжать максимум из своего оборудования.

Есть возможность собрать ядро без модулей, но тогда необходимо будет интегрировать прошивки для встроенного оборудования в ядро. Модули же переключить в режим yes,
например так:
mod2yesconfig - Change answers from mod to yes if possible
./scripts/config --disable CONFIG_MODULES
make oldconfig

Компилятор Скорость компиляции Поддержка PGO Размер бинарника Производительность
GCC Средняя Ограниченная (AutoFDO экспериментально) Меньше Хорошая (стандарт)
Clang Быстрая Полная (AutoFDO) Может быть больше Выше при LTO и/или PGO, polly