Learning Platform
Глоссарий Troubleshooting
Урок 03.04 · 18 мин
Начальный
ArchitectureMicrokernelMonolithicLinuxWindowsmacOS

Архитектуры ОС — monolithic, microkernel, hybrid

ОС бывают разными. Не только в смысле «Linux vs Windows», но и в более глубоком: как организована работа ядра. Сколько кода живёт в kernel mode? Что коммуницирует через syscalls, а что — через message passing? Кто отвечает за драйверы?

Эти решения определяют производительность, надёжность, безопасность системы. В этом уроке — три основных подхода: monolithic, microkernel, hybrid. Сравним Linux, Windows NT, macOS XNU, и микроядерные системы вроде L4 и QNX.


Главный вопрос: что в kernel mode, что в user mode

Помните, мы говорили про ring 0 и ring 3. Архитектура ОС — это в первую очередь про то, что мы помещаем в ring 0 (kernel space), а что оставляем в ring 3 (user space). Чем больше в ring 0 — тем быстрее (нет переходов между mode’ами), но менее надёжно (баг в одном компоненте крашит всё ядро). Чем меньше — тем надёжнее, но медленнее.

Спектр архитектур ОС -- что в kernel mode
Pure microkernelL4, MINIX 3, QNX, seL4. В kernel mode только самое необходимое: scheduler, IPC, basic memory mgmt. Драйверы, файловая система, сеть -- всё в user space через message passing
HybridWindows NT, macOS XNU. Kernel содержит основные подсистемы (process, memory, файлы), но многие сервисы в user space. Компромисс между microkernel и monolithic
MonolithicLinux, FreeBSD. Всё ядро -- один большой kernel: scheduler, file systems, network, drivers, всё в kernel mode. Самый быстрый, но баг в драйвере -> kernel panic

Никакой подход не «правильный» — все имеют свои применения. Mass-market ОС (Linux, Windows, macOS) — либо монолитные, либо гибридные. Микроядра доминируют в embedded (QNX в автопроме), security-critical системах (seL4), академических исследованиях.


Monolithic kernel: Linux

В монолитном ядре всё — внутри одной большой kernel-программы. Когда Linux загружается, в память загружается один файл vmlinuz — это и есть ядро. Внутри него: scheduler, memory manager, VFS, файловые системы (ext4, xfs), сетевой стек (TCP/IP), драйверы устройств.

Архитектура Linux: монолитное ядро
bashОбычный user-процесс. Видит абстракции: процессы, файлы, сокеты. Не знает деталей реализации
firefoxБольшое приложение в user space. Использует X11/Wayland для GUI, libc для I/O
systemdInit и менеджер сервисов. Тоже user-процесс, хоть и привилегированный (PID=1)
...Десятки и сотни user-процессов
System call interfaceГраница между user и kernel. Сюда приходят все syscalls
Process mgmtВнутри kernel mode: процессы, scheduler (CFS), fork, exec, signal
Memory mgmtВнутри kernel mode: virtual memory, page tables, swap, OOM killer
VFS + FSVFS + ext4/xfs/btrfs/tmpfs. Всё в kernel mode для производительности
Network stackTCP/IP, sockets, routing. Всё в kernel. iptables/nftables тоже kernel module
DriversДрайверы устройств: NIC, GPU, USB, disk controllers. Всё в kernel space, либо встроено в ядро, либо loadable modules
...Тысячи подсистем: cgroups, namespaces, security modules (SELinux, AppArmor), audit, и т.д.

Плюсы монолитного подхода:

  1. Производительность. Внутри ядра компоненты общаются через прямые вызовы функций. Никаких message passing, нет переключений контекста между компонентами. Когда драйвер сетевой карты получает пакет — он напрямую кладёт его в TCP/IP стек, тот — в сокет процесса. Всё в одном address space.

  2. Простота для разработчиков ядра. Один проект, одна сборка. Если нужна функция — просто вызывай. Не нужно проектировать межкомпонентные интерфейсы.

  3. Эффективность памяти. Все структуры данных в одном address space, можно делиться без копирования.

Минусы:

  1. Баг в любом месте — kernel panic. Driver памяти SD-карт с ошибкой? Вся система может упасть. Это знакомо тем, кто видел kernel panic после установки кривого драйвера.

  2. Жёсткие требования к качеству кода. Каждая строка должна быть тщательно проверена. Code review в Linux строгий, мейнтейнеры (Linus, Greg KH) известны жёсткими отказами от плохого кода.

  3. Сложность масштабирования. 30 миллионов строк — управлять трудно. Linux держится благодаря строгому процессу: subsystem maintainers, lkml (linux kernel mailing list), merge windows.

Loadable kernel modules (LKM)

Linux — монолитное ядро, но НЕ полностью статическое.

tar: основы архивирования Драйверы и подсистемы могут быть loadable kernel modules (LKM): .ko файлы, которые подгружаются в работающее ядро. Это компромисс: код всё ещё работает в kernel mode, но не нужно перезагружаться для добавления драйвера.

# Список загруженных модулей:
lsmod | head -10

# Подробно про модуль:
modinfo nvme | head

# Подгрузить модуль:
sudo modprobe ext4

# Выгрузить:
sudo modprobe -r ext4

LKM позволяет ядру быть «модульным» при сохранении производительности монолитного дизайна. Драйвер вашей видеокарты загружается как .ko после bootloader’а.


Microkernel: L4 family

Микроядро — противоположный подход. В kernel mode только минимум: scheduler, IPC, базовый memory manager. Всё остальное — драйверы, файловая система, сеть — работает как user-space процессы и общается с ядром (и между собой) через message passing.

Архитектура микроядра: L4 / QNX / MINIX 3
App 1Обычное приложение. Хочет файл? Шлёт сообщение FS-серверу через IPC. FS-сервер шлёт block-driver-серверу. Driver шлёт сообщение в kernel для DMA
FS serverФайловая система как user-процесс. ext4 driver -- отдельный процесс. Если падает -- ядро запускает заново, остальная система работает
Disk driverДрайвер диска как обычный процесс. Если глючит и крашится -- система не падает, можно перезапустить
Network stackTCP/IP, sockets -- всё в user space. Если стек глючит, OS не падает
GUIWindow manager как user-сервис. Сообщения от клавиатуры/мыши идут через IPC
Other...Десятки специализированных сервисов
IPC + scheduler + mem mgmtВсё, что осталось в kernel mode. Десятки тысяч строк, не миллионы. Можно формально верифицировать (seL4 имеет proof корректности)

Плюсы микроядра:

  1. Надёжность. Драйвер с багом — крашится один процесс, не вся система. Ядро запускает его заново. QNX этим живёт в автомобилях — если падает CD-плеер, машина не теряет управление.

  2. Безопасность. Меньше кода в kernel mode = меньше атакующая поверхность. seL4 имеет формальное доказательство отсутствия багов в ядре (это уникальное достижение — L4 microkernel формально верифицирован).

  3. Модульность. Можно поменять файловую систему или сетевой стек на лету — перезапустить сервис.

  4. Преемственность. Один и тот же микрокернел можно использовать для разных систем (десктоп, embedded, real-time).

Минусы:

  1. Производительность. Каждый file read проходит через несколько IPC: app -> FS server -> driver server -> kernel for DMA -> back. Несколько syscalls вместо одного. На современных CPU это всё равно быстро, но на 10-30% медленнее монолитного.

  2. Сложность IPC. Нужно проектировать протоколы взаимодействия. С каждой подсистемой — свой message format.

  3. Сложность отладки. Когда баг проявляется на границе двух сервисов, надо смотреть оба + IPC между ними. В монолитной системе всё в одной отладочной сессии.

Примеры микроядерных систем

  • QNX — коммерческое микроядро от BlackBerry. Используется в автопроме (Mercedes, BMW), Cisco routers, медицинском оборудовании. Hard real-time.
  • L4 family (L4Linux, OKL4, seL4) — исследовательские/коммерческие. seL4 формально верифицирован, используется в военной авионике и в Apple Secure Enclave (по слухам).
  • MINIX 3 — учебное микроядро от Andrew Tanenbaum. Интересно для образования. Иронично, что Intel Management Engine использует MINIX (а не Linux).
  • Symbian, BeOS, Amiga, Plan 9 — разные исторические попытки. Большинство не выжило в mass market.

Hybrid kernel: Windows NT и macOS XNU

Hybrid — компромисс. Берут идеи микроядра (модульность, message passing), но в kernel mode оставляют больше, чем чистый microkernel. Это даёт лучшую производительность при сохранении модульности.

Windows NT

Windows NT kernel (на котором стоят все Windows от NT 3.1 до Windows 11) задуман как hybrid. У него есть Executive layer (process mgmt, memory, I/O), но основные сервисы (UI, security, file caching) частично выведены в user-space сервисы.

Архитектура Windows NT (упрощённо)
Win32 appsОбычные приложения. Видят Win32 API: CreateProcess, ReadFile, WSARecv. Под капотом -- NT native API
ServicesWindows services: лог-сервис, индексация, обновления. user-space процессы
csrss.exeClient/Server Runtime Subsystem. Обслуживает многие Win32 functions. user space, но привилегированный
Subsystem (Win32, Linux)Subsystem layer: Win32 (default), POSIX (старое), WSL (Linux-совместимость). Транслируют API в NT native
ExecutiveОсновные kernel подсистемы: Object Manager, Process Manager, Memory Manager, Cache Manager, Security Reference Monitor. Большая часть kernel-логики тут
KernelНизкоуровневый kernel: scheduler, interrupts, DPC (Deferred Procedure Calls). Меньший, более 'micro' слой
HALHardware Abstraction Layer: абстракция над разными процессорами и платформами. Аналог BIOS/UEFI прослойки
DriversДрайверы -- в kernel mode, как loadable kernel modules. Но могут общаться через IRP (I/O Request Packets) -- стиль микроядра

Windows NT использует множество концепций микроядра внутри, но многое также в kernel mode для производительности. На практике он работает скорее как монолитное ядро с хорошей модульностью.

macOS XNU

macOS (и iOS) использует XNU — «X is Not Unix» — гибрид Mach (микроядро) и BSD (монолитный кусок).

Архитектура XNU (macOS / iOS)
Cocoa appsОбычные приложения macOS. Используют Cocoa API (Objective-C/Swift), который под капотом -- BSD syscalls + Mach messages
launchdInit для macOS. PID 1. Управляет всеми сервисами через property lists
WindowServerGUI server. Отдельный процесс, обрабатывает все события UI. Похож на X11/Wayland
BSD layerPOSIX-совместимый слой: процессы (fork, exec), файловая система (VFS, HFS+/APFS), сеть (sockets). Похоже на FreeBSD
Mach kernelМикроядро Mach: задачи (tasks), потоки, virtual memory, IPC через Mach messages. Это основа архитектуры
I/O KitОбъектно-ориентированный framework для драйверов на C++. Похоже на микроядерный подход, но запускается в kernel mode
libkernC++ runtime для kernel. Стандартная библиотека для kernel-кода

XNU интересен тем, что объединяет два разных подхода: BSD-сервер работает поверх Mach как «персональность», но физически они в одном address space (ring 0). Это даёт скорость монолитного дизайна с архитектурной чистотой микроядра.


Сравнение в одной таблице

Архитектуры в одной картине
LinuxМонолит. Всё в kernel: scheduler, FS, network, drivers. Loadable modules. Самый быстрый. Самый широко используемый
FreeBSDТоже монолит. Похож на Linux, но более интегрированный (kernel + userland в одном дереве)
Windows NTГибрид. Executive в kernel, многие сервисы (csrss, services) в user space. На практике ближе к монолитному
macOS XNUГибрид Mach + BSD. Архитектурно микроядерный, но физически в одном kernel space. На практике быстрый, как монолит
QNXМикроядро. Драйверы в user space. Автопром, медицина, embedded. Hard real-time
seL4Формально верифицированное микроядро. Используется там, где безопасность критична: военка, защита
MINIX 3Учебное микроядро. Полная модульность. Используется внутри Intel Management Engine

Спор Linus vs Tanenbaum: исторический момент

Один из самых знаменитых споров в истории операционных систем — между Линусом Торвальдсом и Эндрю Таненбаумом в 1992 году. Tanenbaum — автор MINIX и сторонник микроядра, Linus — автор Linux и сторонник монолитного дизайна.

Tanenbaum написал на comp.os.minix: «Linux is obsolete», утверждая, что монолитный дизайн уже устарел, и микроядра — будущее. Linus ответил, защищая монолит. Дискуссия продолжалась несколько недель, оба отстаивали свои позиции.

Что произошло на практике:

  • Микроядра не победили в mainstream, как предсказывал Tanenbaum. Linux стал доминирующей серверной ОС.
  • Но идеи микроядра проникли везде: Loadable modules, namespaces, eBPF в Linux — это всё концепции, близкие к microkernel.
  • Микроядра выиграли в нишах: автомобиль, embedded, security-critical.

Современный консенсус: монолитный дизайн оптимален для общего применения. Микроядра — для специфических задач, где надёжность важнее производительности. Гибридный подход (Windows, macOS) — разумный компромисс.

Namespaces и cgroups — фундамент контейнеров

Если хотите прочитать оригинал: «The Tanenbaum-Torvalds Debate» — легко гуглится. Очень показательно про то, как разрабатываются ОС.


А что ещё бывает: exokernel, unikernel

Кратко про более экзотические подходы:

  • Exokernel — идея 90-х из MIT. Ядро ещё меньше микроядра: даёт прямой доступ к ресурсам железа, абстракции (FS, network) — в libOS, которая линкуется в само приложение. Эксперимент, не дошёл до production.

  • Unikernel — специализированная ОС, скомпилированная вместе с приложением. Один процесс, минимум кода. Используется в специализированных серверах (MirageOS, IncludeOS), где безопасность и размер критичны.

  • Library OS — идея, что ОС-сервисы поставляются как библиотеки, а ядро минимально. Близко к unikernel, но проще.

Эти подходы интересны для исследований и специализированных применений. В mass-market производственных системах доминируют три классические архитектуры: monolithic (Linux, BSD), hybrid (Windows, macOS), microkernel (QNX в embedded).


Попробуй сам

# 1. Посмотреть, какая у вас система:
uname -a
# Linux ... -- монолитное (или гибрид, как macOS)

# 2. Сколько модулей загружено в ядро Linux:
lsmod | wc -l
# Обычно 50-200 на типичной системе

# 3. Размер главного ядерного бинаря:
ls -lh /boot/vmlinuz-$(uname -r)
# Несколько MB сжатый, в RAM ~30MB

# 4. Сколько подсистем в ядре (приблизительно):
ls /sys/module/ | wc -l
# Каждая директория -- одна подсистема/модуль

# 5. Что в kernel space прямо сейчас:
sudo cat /proc/modules | head -10
# имя модуля, размер, references, кто использует

# 6. Прямо посмотреть kernel-память (требует CAP_SYS_RAWIO, осторожно):
# Не пытаться writing -- readonly mode!
sudo head -c 64 /dev/kmsg
# Журнал ядра, виден из user space через специальный API

Проверка знанийKnowledge check
Junior спрашивает: 'Если микроядра надёжнее (баг в драйвере не крашит систему), почему Linux не переписали на микроядро за 30 лет? Это же фундаментальный плюс'
ОтветAnswer
Прекрасный вопрос с несколькими слоями ответа. (1) Историческая инерция. Linux начался как монолит в 1991. К 2026 году 30+ миллионов строк кода. Переписать всё на микроядро -- проект на десятилетие. Никто не возьмётся: текущее работает, рынок не требует. Аналог -- Windows NT задумывался как hybrid, но за 30 лет накопил столько монолитного, что разница с Linux небольшая. (2) Производительность реальна. Микроядро добавляет 10-30% overhead на типичные операции (file read через сервер вместо in-kernel). Для серверных нагрузок это огромная разница: означает на 30% меньше rps на том же железе. Бизнес не готов переплачивать. (3) Современные кернельные практики уменьшили проблемы надёжности. LKM позволяют выгружать сбойный драйвер. Kernel preemption уменьшает зависания. Watchdogs и kdump позволяют диагностировать паники. eBPF позволяет дополнять ядро без писания kernel-кода. Эти решения постепенно компенсируют hauptрисованные минусы монолитного дизайна. (4) Микроядра вышли там, где это критично. Автомобили (QNX в Mercedes), военка (seL4), embedded -- там монолита нет. Mainstream использует ту архитектуру, которая оптимальна для general-purpose. Это объективно монолит/гибрид. (5) Альтернативные подходы решают часть проблемы. eBPF позволяет писать 'kernel modules' в user space без риска панить ядро -- это вид микроядра в Linux. Linux namespaces дают изоляцию частей kernel state -- тоже micro-идея. Современный Linux заимствует у микроядра, но остаётся монолитом по форме. (6) Драйверы в Linux -- НЕ главная проблема надёжности. Большинство Linux-крашов сегодня -- железные глюки (битая RAM, перегрев), а не баги драйверов. В этом смысле микроядро не решило бы реальную проблему пользователей. Итог: микроядро -- архитектурно красивый подход, но в mainstream проиграло из-за overhead и инерции. Linux компенсирует свои недостатки модульностью и инструментами, не меняя архитектуры. Это типичный пример, как 'теоретически лучшее' проигрывает 'практичному и хорошо работающему'.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Какая архитектура у Linux?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4