В 2026 году написать операционную систему с нуля — это либо академическое упражнение, либо попытка решить реальную проблему. OptimaOS — второе: проект исследует, можно ли построить одно ядро, которое без форкинга и переписывания обслуживало бы десктоп, сервер, Edge и AI-устройство одновременно. В этой статье — мотивация, архитектурные решения и статус проекта.

Почему в 2026 году кто-то пишет новую ОС
Ядра, на которых работает большинство современного железа, — Linux (1991), Windows NT (1993), Darwin (2001) — написаны в эпоху, когда о memory safety никто особо не думал, а слова «edge computing» и «AI accelerator» звучали как научная фантастика. Эти системы решают свои задачи хорошо — но несут 30+ лет технического долга и архитектурных решений, принятых в совершенно других условиях.
Конкретная проблема, которая меня беспокоила: фрагментация через форкинг.
Android — это форк Linux с тысячами кастомных патчей, которые upstream годами не принимает
Embedded Linux — ещё один набор форков под конкретные SoC-и от каждого вендора
RTOS для IoT/Edge — как правило, отдельные кодовые базы с несовместимыми API
AI-ускорители живут под своими специализированными стеками с минимальной совместимостью
Итог: вместо одной хорошо проверенной, аудированной кодовой базы — зоопарк форков с разным уровнем безопасности, разными системными вызовами и разным поведением в граничных случаях. Каждый форк — это отдельный security-аудит, отдельная команда, отдельный регресс.
Гипотеза OptimaOS: можно построить одно ядро, которое через механизм runtime-профилей обслуживает принципиально разные сценарии — без форкинга исходного кода.
Механизм vs политика: ключевое архитектурное решение
В операционных системах есть классический принцип, сформулированный ещё в работах UNIX: ядро должно предоставлять механизмы, но не диктовать политику. На практике большинство ядер этот принцип нарушают — туда просачиваются решения, которые правильнее было бы оставить userspace’у.
В OptimaOS это разграничение проведено жёстко и зафиксировано в архитектурном решении ADR-0002:
Что живёт в ядре (механизмы, неизменны для всех конфигураций):
Управление памятью (регионы, mmap/munmap/protect)
Планировщик процессов и потоков
IPC-шина с типизированными endpoint’ами
Capability-граф (права доступа к ресурсам)
Syscall ABI (
optima_syscall_v0)
Что живёт в профилях (политика, меняется runtime):
Правила политик (какой процесс что может делать)
Конфигурация userspace-сервисов (запускать ли сетевой стек, с какими параметрами)
Параметры планировщика (latency vs throughput)
Разрешённые syscall-паттерны
Практически это выглядит так: бинарный образ ядра один и тот же для десктопного home-профиля и серверного server-профиля. При старте загружается соответствующий policy-файл, и policy-service применяет его поверх ядра через runtime API. Никакой пересборки ядра, никакого форкинга.

Это не новая идея — похожий подход используется в seL4 и некоторых RTOS. Но в сочетании с Rust и современным toolchain’ом результат получается интересным.
Почему Rust
Выбор Rust для системного программирования в 2026 году уже не требует долгих обоснований — Microsoft, Google, Linux kernel, Android открыто говорят о переходе. Но для нас конкретные причины были следующими:
1. Memory safety без GC. Ядро не может позволить себе garbage collector. Rust даёт compile-time гарантии отсутствия dangling pointers, use-after-free, buffer overflow — без рантайм-оверхеда. Это не просто удобство, это требование к TCB (Trusted Computing Base).
2. #[forbid(unsafe_code)] как политика. В kernel-core это не рекомендация, а запрет на уровне компилятора. Весь unsafe-код изолирован в HAL-слое (hardware/mod.rs) и явно аннотирован. Количество unsafe-строк можно посчитать за минуту.
3. Ownership model отлично ложится на capability-модель. Capabilities в OptimaOS — это токены владения ресурсами. Rust ownership и lifetime semantics естественно выражают те же инварианты на уровне типов.
4. Toolchain и экосистема. cargo test, cargo build --target x86_64-unknown-uefi, встроенная поддержка no_std — инфраструктура для написания ОС из коробки намного лучше, чем была в C 30 лет назад.
Архитектура OptimaOS
Проект организован как Rust workspace с несколькими crate’ами:
kernel-core/ — единственный execution engine, всё ядро здесь linux-compat/ — Linux ABI bridge (L1/L2 staged) policy-service/ — userspace policy manager device-manager/ — userspace device manager filesystem-service/ — userspace filesystem service network-service/ — userspace network service profile-service/ — userspace profile overlay service
Важный момент: policy-service, device-manager и остальные сервисы не зависят от kernel-core как от библиотеки. Они общаются с ядром через typed IPC + capabilities — ровно так, как должно быть в микроядерной архитектуре. Только linux-compat явно зависит от kernel-core, потому что реализует маппинг Linux syscall’ов на optima_syscall_v0.
Ключевые модули и их назначение:
Ключевые модули и их назначение:
Модуль | Назначение |
|---|---|
| |
Syscall ABI ( | |
In-memory queue IPC с типизированными endpoint’ами и owner PID | |
Регионы памяти, mmap/munmap/protect | |
Планировщик процессов и потоков | |
Граф capabilities, grant/revoke/transfer | |
Policy rules, overlays, per-PID overrides | |
Audit trail, экспорт и верификация событий | |
| Transport v1 (UEFI shim ↔ runtime)Console Transport: двухслойная архитектура |
Console Transport: двухслойная архитектура
Это одно из нетривиальных решений, зафиксированных в ADR-0003. UEFI shim и kernel runtime разделены явным транспортным протоколом:
Stage A (UEFI shim): transport + diagnostics только. Пересылает input-события в runtime, рендерит output. Не исполняет команды.
Stage B (kernel-core runtime): единственная точка исполнения команд. Все
sys.*команды обрабатываются здесь.
Жизненный цикл: BootInit → ShimReady → RuntimeAttach → Interactive → Degraded
Смысл такого разделения: UEFI-код работает в привилегированном режиме с доступом к boot services. Если дать ему возможность исполнять команды напрямую, boundary между boot и runtime размывается, и аудировать систему становится сложнее. Строгое разделение позволяет верифицировать каждый слой независимо.
Linux ABI совместимость: зачем и как
Самописная ОС без совместимости с существующим ПО — это интересный эксперимент, но не более. Поэтому linux-compat реализует маппинг Linux syscall’ов на optima_syscall_v0 в несколько этапов:
L1 (реализовано): clone, exit, nanosleep, mmap, munmap, sendmsg, recvmsg, минимальные сигналы, минимальный epoll.
L2-A (реализовано): fd lifecycle (open/close/read/write), dup/dup2, poll/epoll_wait.
L2-B (реализовано): signal masks, pending queue.
L2-C (реализовано): epoll_ctl(DEL/MOD), расширенная epoll-семантика.
Важная оговорка: Linux bridge API помечен как draft — это не стабильный публичный ABI, совместимость не гарантируется между версиями до явного объявления стабильности.
Почему поэтапно, а не всё сразу? Потому что каждый новый syscall — это расширение attack surface. Сначала верифицируем L1, потом L2. Каждый этап закрывается compatibility matrix тестами.
Что дальше
Ближайшие технические задачи в порядке приоритета:
Физическое device bring-up — загрузиться на реальном x86_64, пройти on-device smoke тесты, зафиксировать реальные perf-числа.
Linux L2 completion — завершить L2-C и начать расширенные signals (
signalfd/eventfd).Android L2 — маппинг Android Binder IPC на
optima_syscall_v0(в backlog, после L2).Win32 L3 — самый сложный слой, далёкая перспектива.
Unicode + image rendering в GUI framework.
Глобальная цель — проверить гипотезу: один kernel binary, работающий с разными профилями на десктопе, сервере и Edge-устройстве. Если это реализуемо без деградации производительности — интересно идти дальше.
Заключение
OptimaOS — это рабочий прототип, а не продукт. Но за этим прототипом стоит конкретная архитектурная гипотеза о разделении механизмов и политик, о runtime-конфигурируемости вместо форкинга, о Rust как фундаменте для ядра с верифицируемой memory safety.
Результаты пока обнадёживают: ядро компилируется и тестируется детерминированно, Linux ABI совместимость реализуется поэтапно без нарушения syscall контракта, xHCI драйвер работает под QEMU. Следующий серьёзный рубеж — реальное железо.
Если вам интересна тема проектирования ядер, Rust systems programming или Linux ABI совместимость — буду рад обсудить конкретные технические решения в комментариях. Особенно интересны взгляды тех, кто работал с seL4, Zephyr или L4-микроядрами — есть что сравнить.
Проект находится в активной разработке. Исходный код пока не опубликован — планирую сделать это после достижения вменяемой работоспособности.
