---
tags: [linux, tooling]
verified: 2026-09-02
---

# Linux — ядро: сборка, модули, параметры

## Обзор

Linux — монолитное ядро с поддержкой загружаемых модулей. Это компромисс: ядро работает в едином адресном пространстве (быстрые вызовы, нет IPC-overhead как в микроядрах), но модули позволяют расширять функциональность без перекомпиляции и перезагрузки. На практике большинство пользователей никогда не собирают ядро сами — дистрибутивы поставляют generic-ядра с сотнями модулей. Но понимание архитектуры сборки, модульной системы и runtime-параметров необходимо для отладки, performance-тюнинга и работы с нестандартным оборудованием.

Ядро Linux развивается в модели rolling release: новый релиз каждые 9-10 недель, LTS-ветки поддерживаются от трёх до шести лет. Нумерация не отражает масштаба изменений — за 6.19 (февраль 2026) последовала 7.0 (апрель 2026), это обычная смена счётчика, а не смена поколения. Действующие LTS-ветки — 6.18, 6.12, 6.6 и 6.1, плюс 5.15 и 5.10, у которых EOL намечен на декабрь 2026. Дистрибутивы обычно берут LTS-ядро и бэкпортят фиксы, создавая свою ветку (например, Debian 13 использует 6.12, RHEL 9 — 5.14 с массивным бэкпортингом).

## Архитектура: Kconfig / Kbuild

### Конфигурация: Kconfig

Ядро содержит ~18000+ конфигурационных символов (CONFIG_*), определённых в файлах Kconfig по всему дереву исходников. Каждый символ имеет тип (bool, tristate, int, string), зависимости (depends on), значения по умолчанию, и help-текст. Kconfig — это язык, а make menuconfig / xconfig / nconfig — фронтенды, парсящие Kconfig-файлы и генерирующие .config.

Тип tristate — ключевая абстракция модульности: y (built-in, линкуется в vmlinuz), m (module, компилируется как .ko), n (отключено). Bool — только y/n (не может быть модулем). Зависимости определяют видимость: если CONFIG_NET=n, все сетевые опции скрыты в menuconfig.

```text
# Пример Kconfig-записи (drivers/net/ethernet/intel/Kconfig)
config E1000E
    tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
    depends on PCI
    select CRC32
    help
      This driver supports Intel PRO/1000 PCI-Express Ethernet adapters.
```

`depends on PCI` — опция видна только если PCI включён. `select CRC32` — при включении E1000E автоматически включается CRC32. select — мощный, но опасный: он форсирует включение зависимости, игнорируя её собственные depends on. Это частый источник ошибок конфигурации в ядре.

### Сборка: Kbuild

Kbuild — make-based система сборки. Каждый каталог содержит Makefile с записями вида:

```makefile
obj-$(CONFIG_E1000E) += e1000e/
obj-y += core.o          # всегда линкуется
obj-m += mydriver.o      # всегда модуль (редко, обычно через CONFIG_*)
```

Когда CONFIG_E1000E=y, obj-y включает каталог — код линкуется в ядро. Когда =m, obj-m — код компилируется в e1000e.ko. Когда =n, строка превращается в obj-= и игнорируется.

Результат сборки: сжатый образ ядра (на x86 это `arch/x86/boot/bzImage`, в /boot он попадает под именем `vmlinuz-*`), modules/*.ko (загружаемые модули), System.map (таблица символов для отладки), .config (сохранённая конфигурация).

С 6.1 в дереве живёт вторая тулчейн-ветка: `CONFIG_RUST` включает поддержку Rust, и тогда сборке помимо компилятора C нужны rustc, bindgen и libclang. Требования к версиям жёсткие и растут от релиза к релизу (в дереве 7.x — rustc 1.85.0 и bindgen 0.71.1), поэтому Kconfig прячет опцию, пока не выполнено `RUST_IS_AVAILABLE`; проверить тулчейн вручную можно целью `make LLVM=1 rustavailable`.

### Процесс сборки

```bash
# 1. Получить исходники
# Из git:
git clone --depth=1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
# Или tarball с kernel.org

# 2. Конфигурация
# Начать с конфига текущего ядра:
cp /boot/config-$(uname -r) .config
make olddefconfig          # применить defaults для новых символов

# Или начать с дефолтов архитектуры:
make defconfig

# Интерактивная настройка:
make menuconfig            # ncurses TUI
make nconfig               # улучшенная ncurses версия
make xconfig               # Qt GUI

# 3. Сборка
make -j$(nproc)            # ядро + модули
make modules_install       # установить модули в /lib/modules/<version>
make install               # установить vmlinuz + System.map + обновить bootloader

# 4. Обновить initramfs (если нужно)
# Debian/Ubuntu:
update-initramfs -c -k <version>
# Fedora/RHEL:
dracut --force /boot/initramfs-<version>.img <version>
```

## Загружаемые модули

### Жизненный цикл модуля

Модуль (.ko — kernel object) — ELF-файл с дополнительными секциями метаданных. При загрузке ядро: верифицирует подпись (если CONFIG_MODULE_SIG_FORCE=y), разрешает символы (функции/данные, экспортированные другими модулями или ядром через EXPORT_SYMBOL), выделяет память и загружает код, вызывает init-функцию модуля.

Модули могут устанавливаться сжатыми: `CONFIG_MODULE_COMPRESS_ZSTD` даёт суффикс `.ko.zst`, `CONFIG_MODULE_COMPRESS_XZ` — `.ko.xz`, `CONFIG_MODULE_COMPRESS_GZIP` — `.ko.gz`. Разжимает их kmod, а при `CONFIG_MODULE_DECOMPRESS` — само ядро. Отсюда маска `*.ko*` в примерах поиска модулей по дереву: одного `*.ko` уже недостаточно.

```bash
# Загрузка/выгрузка
modprobe e1000e              # загрузить + зависимости (из /lib/modules/...)
modprobe -r e1000e           # выгрузить + неиспользуемые зависимости
insmod ./mydriver.ko         # загрузить по пути (без dependency resolution)
rmmod mydriver               # выгрузить (без dependency resolution)

# Информация
lsmod                        # список загруженных модулей + refcount
modinfo e1000e               # метаданные: version, license, depends, params
modprobe -c                  # вся конфигурация modprobe

# Поиск и зависимости
depmod -a                    # перестроить modules.dep (после установки новых модулей)
modprobe --show-depends e1000e  # показать дерево зависимостей
```

### modprobe vs insmod

insmod — низкоуровневый: загружает один .ko файл по абсолютному пути, не разрешает зависимости. modprobe — высокоуровневый: ищет модуль по имени в /lib/modules/$(uname -r)/, автоматически загружает зависимости из modules.dep, читает конфигурацию из /etc/modprobe.d/. Аналогия: insmod ~ dpkg, modprobe ~ apt.

### Конфигурация модулей

/etc/modprobe.d/*.conf — конфигурация загрузки модулей:

```bash
# Передача параметров модулю
options snd-hda-intel power_save=1 power_save_controller=Y

# Blacklist — запретить автозагрузку модуля
blacklist nouveau             # отключить nouveau (для установки NVIDIA driver)
install nouveau /bin/false    # жёстче: при попытке загрузить — ничего не делать

# Alias — маппинг имён
alias net-pf-10 ipv6          # при запросе "net-pf-10" загрузить ipv6
```

Параметры модулей можно также задать через строку загрузки ядра (kernel command line): `e1000e.InterruptThrottleRate=3000`.

### DKMS: Dynamic Kernel Module Support

DKMS решает проблему out-of-tree модулей (NVIDIA, VirtualBox, ZFS): при обновлении ядра модули нужно пересобрать. DKMS автоматизирует это — хранит исходники модуля и пересобирает его для каждого нового ядра при установке. Конфигурация в /usr/src/<module>-<version>/dkms.conf.

### Подпись модулей

Secure Boot требует подписи ядра и модулей. При CONFIG_MODULE_SIG_FORCE=y ядро отказывается загружать неподписанные модули. Дистрибутивные ядра подписаны ключом дистрибутива. Для загрузки сторонних модулей (NVIDIA, DKMS) необходимо: либо зарегистрировать свой MOK (Machine Owner Key) через mokutil, либо отключить Secure Boot.

## Параметры ядра: sysctl и /proc/sys

### Архитектура

sysctl — интерфейс для runtime-модификации параметров ядра через виртуальную файловую систему /proc/sys/ (см. статью 1). Маппинг прямой: `net.ipv4.ip_forward` ↔ `/proc/sys/net/ipv4/ip_forward`. Чтение: `sysctl net.ipv4.ip_forward` или `cat /proc/sys/net/ipv4/ip_forward`. Запись: `sysctl -w net.ipv4.ip_forward=1` или `echo 1 > /proc/sys/net/ipv4/ip_forward`.

Параметры организованы в подсистемы: kernel.* (общие: panic, hostname, pid_max, shmmax), vm.* (виртуальная память: swappiness, dirty_ratio, overcommit), net.* (сеть — подробно в статье 3), fs.* (файловые системы: file-max, inotify limits), dev.* (устройства).

### Постоянная конфигурация

Файлы в /etc/sysctl.d/*.conf загружаются при загрузке системы (systemd-sysctl.service). Порядок: /usr/lib/sysctl.d/ (дефолты пакетов) → /etc/sysctl.d/ (администраторские override'ы) → /etc/sysctl.conf (legacy, но всё ещё работает). Приоритет — алфавитный порядок файлов, последний выигрывает.

```bash
# /etc/sysctl.d/99-custom.conf
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
kernel.panic = 10
fs.file-max = 2097152
fs.inotify.max_user_watches = 524288

# Применить без перезагрузки
sysctl --system                    # перечитать все файлы
sysctl -p /etc/sysctl.d/99-custom.conf  # конкретный файл
```

### Ключевые параметры по категориям

**Виртуальная память:**

`vm.swappiness` (0-200, default 60) — агрессивность вытеснения anonymous pages в swap. 0 — swap используется только при крайней необходимости. 10 — типичная рекомендация для серверов с достаточным RAM. Для database-серверов важно держать низким, чтобы предотвратить swap'ование кэша БД.

`vm.overcommit_memory` — стратегия выделения памяти: 0 (default, эвристика), 1 (всегда разрешать — опасно, но нужно для Redis/fork-heavy workloads), 2 (строгий: не более swap + overcommit_ratio% от RAM).

`vm.dirty_ratio` / `vm.dirty_background_ratio` — при каком проценте «грязных» страниц начинать запись на диск. dirty_background_ratio (default 10%) — фоновая запись. dirty_ratio (default 20%) — синхронная блокировка (процесс ждёт). Снижение уменьшает burst latency, но увеличивает количество I/O-операций.

**Ядро:**

`kernel.panic` — секунды до перезагрузки после kernel panic (0 = не перезагружаться). Для серверов обычно 10-60.

`kernel.pid_max` — значение, на котором нумерация PID заворачивается обратно к минимуму. По умолчанию это 32768 независимо от разрядности (`PID_MAX_DEFAULT`); 4194304 — не дефолт, а верхняя граница, до которой параметр разрешено поднять на 64-bit (`PID_MAX_LIMIT`, на 32-bit потолок совпадает с дефолтом). На серверах с множеством контейнеров упереться в 32768 несложно.

`kernel.core_pattern` — путь для core dump'ов. Можно направить в программу (pipe): `|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h` (systemd-coredump собирает и хранит дампы, доступные через `coredumpctl`).

**Файловые системы:**

`fs.file-max` — системный лимит на количество открытых файлов (не путать с ulimit -n — per-process лимит). На нагруженных серверах может потребоваться 1-2M.

`fs.inotify.max_user_watches` — максимум inotify-watches на пользователя. Фиксированные 8192 остались в прошлом: начиная с 5.11 ядро считает значение при инициализации как ~1% адресуемой памяти, делённый на стоимость одного watch, и зажимает результат в диапазон [8192, 1048576] — на машине с несколькими гигабайтами RAM дефолт получается шестизначным. IDE (VS Code, IntelliJ), файловые синхронизаторы и контейнерные рантаймы всё равно способны его исчерпать; 524288 — типичная рекомендация для developer workstation.

## Kernel command line

Параметры, передаваемые ядру при загрузке через bootloader (GRUB: в /etc/default/grub, переменная GRUB_CMDLINE_LINUX). Текущие параметры: `cat /proc/cmdline`.

Важные параметры:

`quiet` — подавить сообщения ядра при загрузке. `root=` — корневое устройство. `init=` — путь к init (по умолчанию /sbin/init → systemd). `systemd.unit=` — target для systemd (rescue.target для однопользовательского режима). `nomodeset` — отключить kernel mode setting (отладка видео). `iommu=pt` — passthrough IOMMU (для виртуализации). `mitigations=off` — отключить все CPU vulnerability mitigations (performance, но небезопасно). `crashkernel=` — резервировать память для kdump. `module_blacklist=nouveau` — blacklist модуля через cmdline.

## initramfs: начальный RAM-диск

initramfs (initial RAM filesystem) — cpio-архив, загружаемый в память вместе с ядром. Содержит минимальный userspace: busybox/systemd, модули для корневой ФС (файловая система, контроллер диска, LVM, LUKS), udev-правила для обнаружения устройств.

Зачем нужен: ядро не может содержать драйверы для всех возможных конфигураций хранилища. initramfs позволяет generic-ядру загрузиться на любом оборудовании: загрузить нужные модули, собрать RAID/LVM, расшифровать LUKS, смонтировать root ФС, выполнить pivot_root и передать управление реальному init.

```bash
# Просмотр содержимого
lsinitramfs /boot/initrd.img-$(uname -r)   # Debian/Ubuntu
lsinitrd /boot/initramfs-$(uname -r).img   # Fedora/RHEL

# Пересоздание
update-initramfs -u -k $(uname -r)         # Debian/Ubuntu
dracut --force                              # Fedora/RHEL
mkinitcpio -P                               # Arch
```

dracut (Fedora/RHEL) vs initramfs-tools (Debian) vs mkinitcpio (Arch) — три разных генератора с разной философией. dracut строит initramfs по hostonly (только модули для текущего hardware) или generic принципу. initramfs-tools Debian использует hook-систему. mkinitcpio Arch — конфигурация через /etc/mkinitcpio.conf с hooks-массивом.

## Практика

```bash
# Текущее ядро и его параметры
uname -r                                    # версия
uname -a                                    # полная информация
cat /proc/version                           # версия + компилятор
cat /proc/cmdline                           # command line параметры

# Конфигурация текущего ядра
cat /boot/config-$(uname -r) | grep CONFIG_EXT4  # проверить конкретную опцию
zcat /proc/config.gz                        # если CONFIG_IKCONFIG_PROC=y

# Модули
lsmod | head -20                            # загруженные модули
find /lib/modules/$(uname -r) -name '*.ko*' | wc -l  # доступных модулей
modinfo -p e1000e                           # параметры модуля

# sysctl
sysctl -a 2>/dev/null | wc -l              # количество параметров
sysctl -a --pattern 'net.ipv4.tcp'         # фильтрация по паттерну

# Hardware info (через ядро)
lspci -k                                    # PCI-устройства и их модули
lsusb                                       # USB-устройства
cat /proc/interrupts                        # распределение прерываний
cat /proc/iomem                             # карта памяти устройств
```

## Нюансы и trade-off'ы

**Built-in vs module.** Built-in (=y) — код всегда доступен, нет overhead загрузки, нет зависимости от /lib/modules. Module (=m) — загружается по требованию, может быть выгружен, обновлён без перекомпиляции ядра. Правило: драйверы, необходимые для загрузки (root FS, disk controller), должны быть built-in или в initramfs. Всё остальное — модули. Generic-ядра дистрибутивов делают почти всё модулями и используют initramfs.

**Generic vs custom kernel.** Generic-ядра дистрибутивов содержат ~5000+ модулей для поддержки максимально широкого набора оборудования. Custom kernel с CONFIG только для конкретной машины: быстрее загружается (меньше initramfs или его отсутствие), потенциально меньше attack surface. Trade-off: ручное обслуживание, потеря обновлений безопасности от дистрибутива. На практике оправдано для embedded, high-security или extreme performance сценариев.

**sysctl: vm.overcommit_memory для Redis.** Redis fork'ает процесс для background save (BGSAVE). При overcommit_memory=0 ядро может отказать в fork() если текущее потребление памяти велико, даже если copy-on-write реально использует мало памяти. Redis требует overcommit_memory=1. Это безопасно при правильном мониторинге, но на multi-tenant системе может привести к OOM.

**Transparent Huge Pages (THP).** `CONFIG_TRANSPARENT_HUGEPAGE` (enabled по умолчанию) — ядро автоматически объединяет 4KB страницы в 2MB huge pages. Хорошо для HPC, плохо для database workloads (latency spikes от compaction). MongoDB, Redis, Oracle рекомендуют отключать THP: `echo madvise > /sys/kernel/mm/transparent_hugepage/enabled`.

**Mitigations trade-off.** Spectre/Meltdown и последующие CPU-уязвимости потребовали mitigation'ов в ядре (retpoline, KPTI, SSBD и т.д.), каждый из которых стоит 1-30% производительности в зависимости от workload. `mitigations=off` в cmdline отключает все. Это может быть оправдано для изолированных систем (dedicated server без untrusted code), но неприемлемо для multi-tenant или cloud-среды.

**Module signing и Secure Boot.** Строгая цепочка доверия: UEFI → shim (подписан Microsoft) → GRUB (подписан дистрибутивом) → ядро (подписано) → модули (подписаны). Любой разрыв (загрузка неподписанного модуля) нарушает цепочку. На практике это основная проблема с NVIDIA-драйверами и ZFS (CDDL-лицензия → нет в mainline → нет подписи дистрибутива → нужен MOK).

## Сравнение с FreeBSD

FreeBSD ядро — также монолитное с модулями (kld — kernel loadable module). Принципиальная разница в процессе конфигурации и обновления.

**Конфигурация.** FreeBSD ядро конфигурируется текстовым файлом (/usr/src/sys/amd64/conf/MYKERNEL), который include'ит GENERIC и добавляет/удаляет опции. Нет Kconfig/menuconfig — конфигурация проще, но менее интерактивна. `make buildkernel KERNCONF=MYKERNEL && make installkernel` — сборка и установка.

**Обновление.** FreeBSD обновляет ядро и base system как единое целое через freebsd-update (бинарно) или make buildworld/buildkernel (из исходников). В Linux ядро — отдельный пакет (linux-image-*, kernel-core), обновляемый пакетным менеджером независимо от userspace.

**Модули.** kldload/kldunload вместо modprobe/rmmod. Конфигурация автозагрузки: /boot/loader.conf (ранняя загрузка) и kld_list в /etc/rc.conf (поздняя загрузка). Нет эквивалента DKMS — out-of-tree модули (drm-kmod, virtualbox-ose-kmod) пересобираются пакетным менеджером при обновлении ядра.

**sysctl.** FreeBSD sysctl — не только /proc/sys аналог, но и primary API для информации о системе (hw.physmem, kern.osrelease). В Linux часть этой информации в /proc, часть в /sys, часть в sysctl — менее унифицировано. FreeBSD sysctl доступен без procfs/sysfs — через sysctl(2) syscall. Параметры задаются в /etc/sysctl.conf и /boot/loader.conf (для параметров, требующих ранней установки).

**Securelevel.** FreeBSD имеет kern.securelevel — глобальный уровень безопасности, ограничивающий операции ядра (нельзя загружать модули, менять флаги файлов, писать в /dev/mem). Securelevel можно только повышать во время работы. В Linux аналогом являются LSM (AppArmor, SELinux — см. статью 7) и Lockdown LSM (с ядра 5.4), который ограничивает модификацию ядра из userspace.

## Источники

- [Kernel Build System (Kbuild)](https://docs.kernel.org/kbuild/index.html) — официальная документация Kbuild
- [Kconfig Language](https://docs.kernel.org/kbuild/kconfig-language.html) — спецификация языка Kconfig
- [The Linux Kernel Module Programming Guide](https://sysprog21.github.io/lkmpg/) — практическое руководство по модулям
- [Documentation for /proc/sys/kernel/](https://docs.kernel.org/admin-guide/sysctl/kernel.html) — sysctl параметры ядра
- [Documentation for /proc/sys/vm/](https://docs.kernel.org/admin-guide/sysctl/vm.html) — sysctl параметры виртуальной памяти
- [Documentation for /proc/sys/net/](https://docs.kernel.org/admin-guide/sysctl/net.html) — sysctl сетевые параметры
- [Kernel parameters](https://docs.kernel.org/admin-guide/kernel-parameters.html) — полный список параметров command line
- [dracut](https://man7.org/linux/man-pages/man8/dracut.8.html) — генератор initramfs (Fedora/RHEL)
- [Exploring Kconfig/kbuild — Opensource.com](https://opensource.com/article/18/10/kbuild-and-kconfig) — обзор build system
- FreeBSD Handbook: [Configuring the FreeBSD Kernel](https://docs.freebsd.org/en/books/handbook/kernelconfig/) — для сравнения

---

## Связанные заметки

- [Linux — обновление и управление загрузкой](./linux-boot-management.md) — initramfs, параметры загрузки, смена ядра
- [Linux — мониторинг и отладка](./linux-monitoring-debugging.md) — наблюдение за ядром через perf и eBPF
- [Linux — справочник команд: фреймворки трассировки](./linux-tldr-tracing.md) — ftrace, kprobes, BPF-инструменты
- [FreeBSD — sysctl и конфигурация ядра](./freebsd-sysctl-and-kernel.md) — сборка ядра и sysctl во FreeBSD, для сравнения
- [Linux — сводный cheatsheet](./linux-map-cheatsheet.md) — быстрая справка по модулям и sysctl
- [Магия как метафора: язык и культура Unix](./unix-magic-culture.md) — язык комментариев и имён в исходниках ядра; «You are not expected to understand this»
- [Локальный инференс LLM](./llm-local-inference.md) — параметры модулей amdgpu и TTM, которыми задаётся объём памяти для GPU и APU
- [Устройство ОС — план цикла статей](./os-knowledge-base-plan.md) — цикл о внутреннем устройстве ядра: карта памяти, стеки, вход в ядро
- [Страничная трансляция: таблицы, TLB, разрядность](./os-paging-and-tlb.md) — механизм, которым управляют параметры загрузки про уровни трансляции и большие страницы
- [Ядро как программа: freestanding, компоновка, ABI, выбор языка](./os-kernel-as-program.md) — то же ядро изнутри: freestanding-окружение, скрипт компоновки, ABI
- [Карта памяти ядра: половины, прямое отображение, KASLR](./os-kernel-memory-map.md) — что стоит за параметрами `nopti`, `nokaslr` и `rodata` и почему модули лежат там, где лежат
- [Загрузка: от питания до первой инструкции ядра](./os-boot-sequence.md) — что происходит до первой инструкции ядра и зачем нужен initramfs
- [Структура ядра: монолит, микроядро и что между](./os-kernel-structure.md) — почему загружаемый модуль не даёт изоляции и чем модульность отличается от микроядерности
