Требования к ОС и подходы к реализации
Вступление
Когда говорят "нужна операционная система", редко уточняют — какая именно и зачем. Серверу важны стабильность и учёт ресурсов; игровому ПК — драйверы GPU и низкая задержка ввода; встраиваемому контроллеру — предсказуемость в миллисекундах и малый размер образа.
Требования к ОС — это список того, что система обязана делать (функции) и как хорошо (качество). Подход к реализации — как архитекторы раскладывают эти требования по ядру, драйверам и пользовательским сервисам.
Эта статья связывает классический взгляд на требования с материалами энциклопедии: определение ОС, архитектура ядра, история.
Функциональные требования
Функциональные требования отвечают на вопрос: что ОС должна уметь?
| Область | Примеры требований | Где раскрыто в энциклопедии |
|---|---|---|
| Управление процессором | Многозадачность, планирование, приоритеты | Управление процессами в Linux, Планирование процессора — классические алгоритмы |
| Управление памятью | Виртуальная память, защита, разделяемые сегменты | Механизмы распределения памяти в ОС, Управление памятью в Linux |
| Файлы и хранение | Иерархия каталогов, права, журналирование | Устройство файловой системы Windows, Операционные системы |
| Ввод-вывод | Драйверы, унифицированный API | Подсистема ввода-вывода в ОС, Ядро операционной системы |
| Безопасность | Пользователи, группы, изоляция | Управление процессами в Linux, Ядро операционной системы |
| Сеть | Стек протоколов, сокеты | Операционные системы, раздел 2-03 |
| Взаимодействие | IPC: pipe, shm, сигналы | Управление процессами в Linux, Гонки, критические секции и разделяемая память |
Минимальный набор для "универсальной" ОС
- Абстракция процессора — программа не назначает себе ядра вручную; есть планировщик.
- Виртуальная память — каждый процесс в своём адресном пространстве.
- Файловая система — долговременное хранение с именами и правами.
- Доступ к устройствам — через драйверы, а не прямую запись в порты из приложения.
- Защита — режим ядра / пользователя, проверка прав на операции.
Без любого из этих пунктов система либо небезопасна, либо неудобна для переносимых программ.
Нефункциональные требования
Нефункциональные требования описывают качество работы.
Производительность
- Пропускная способность (throughput) — сколько заданий в единицу времени (транзакций, Мб/с).
- Время отклика (response time) — задержка от действия пользователя до реакции.
- Масштабируемость — рост производительности при добавлении CPU/RAM (идеально линейный, на практике — нет из-за NUMA, блокировок).
ОС влияет на все три — планировщик, кэш страниц, алгоритмы I/O. См. планирование, замещение страниц.
Надёжность и доступность
- Отказоустойчивость — сбой приложения не роняет всю систему.
- Восстановление после сбоя — журналы ФС, fsck, откат транзакций.
- Доступность 99.9%+ — кластеры, live patching ядра (см. ядро).
В учебных курсах надёжность часто выделяют отдельно от "сырой" производительности: система должна продолжать работу при сбоях отдельных компонентов и давать предсказуемое восстановление. Монолитное ядро ускоряет вызовы внутри ядра, но сбой в драйвере опаснее. Микроядро изолирует сервисы, ценой накладных расходов на IPC.
Безопасность
- Конфиденциальность — процесс A не читает память B.
- Целостность — нельзя подменить системные файлы без прав.
- Доступность — защита от DoS (лимиты ресурсов, cgroups).
Современные механизмы — ASLR, NX-бит, SELinux/AppArmor, Secure Boot — в ядре и безопасности.
Скрытые каналы (side channels)
Даже при формально корректной политике доступа остаются скрытые каналы — способы передать информацию в обход явных API:
| Тип | Идея | Пример |
|---|---|---|
| Память | Процессы делят ресурс и косвенно "договариваются" | Общий кэш, разделяемая страница, согласованный паттерн записи |
| Время | Один процесс кодирует биты задержками | Наблюдатель по времени ответа узнаёт, занят ли ресурс |
Защита от скрытых каналов сложнее, чем от "открытого" чтения чужого файла: нужны изоляция, квоты и иногда отказ от совместного использования железа. В промышленных ОС это учитывают в сертификации и облачной мультиарендности, а в учебниках — как напоминание, что безопасность ≠ только список прав ACL.
Расширяемость
ОС должна расти без полной пересборки ядра при каждой новой функции:
- Динамические модули ядра (LKM в Linux, подписанные драйверы в Windows) — драйверы и подсистемы подключаются в runtime.
- Объектная модель API — в Windows NT многие ресурсы ядра представлены объектами с унифицированными операциями (
Create*,CloseHandle), что упрощает добавление новых типов без ломки старых программ. - Плагины и подсистемы — сетевые фильтры, FUSE, eBPF-программы в Linux.
Расширяемость связана с архитектурой ядра: модульное монолитное ядро и микроядро решают задачу по-разному.
Переносимость
Переносимость — перенос кода ОС и приложений между платформами:
- Абстракция железа — HAL в Windows, arch-specific код в
arch/в Linux, Device Tree на ARM. - Единый набор системных вызовов внутри семейства (POSIX для Unix, Win32 для Windows).
- Переносимость приложений — пересборка под ABI или бинарная совместимость (x86 эмуляция на ARM в macOS).
Расширяемость отвечает на "как добавить функцию", переносимость — на "как перенести систему на другое железо".
Совместимость
Совместимость — старые и чужие программы продолжают работать:
- Двоичная совместимость — тот же исполняемый файл на разных CPU одного семейства (с оговорками по версии ОС).
- Подсистемы окружения — в Windows NT исторически были подсистемы для POSIX/16-bit; сегодня — WSL для Linux-среды поверх ядра Windows.
- Слои совместимости в Linux —
personality, multilib, Wine для WinAPI.
Совместимость часто конфликтует с безопасностью: чем больше legacy-API, тем шире поверхность атаки.
Удобство сопровождения
- Обновляемость — пакетные менеджеры, откат, LTS-релизы (жизненный цикл в Операционные системы).
- Наблюдаемость — логи,
/proc, eBPF, Performance Monitor.
Стоимость и ресурсы
Для встраиваемых систем критичны размер образа, потребление RAM, энергия. Там часто отказываются от подкачки, выбирают RTOS или урезанный Linux (Buildroot, Yocto).
Требования разных классов систем
| Класс | Приоритеты | Типичная реализация |
|---|---|---|
| Десктоп | Отклик UI, драйверы, совместимость | Windows, macOS, Linux + DE |
| Сервер | Throughput, стабильность, сеть | Linux, Windows Server |
| Мобильная | Энергия, безопасность приложений | Android, iOS |
| Встраиваемая | Детерминизм, малый размер | FreeRTOS, Zephyr, Embedded Linux |
| Критическая инфраструктура | Сертификация, изоляция | QNX, KasperskyOS, отдельные домены на гипервизоре |
Один и тот же Linux настраивается под разные профили: Android — другой набор подсистем и политик power management, чем Ubuntu Server.
Подходы к реализации — архитектура ядра
Требования "изоляция" и "скорость" тянут в разные стороны. Основные архитектурные подходы (подробно в Ядро операционной системы):
| Подход | Суть | Когда выбирают |
|---|---|---|
| Монолитное ядро | Драйверы и FS в адресном пространстве ядра | Максимальная производительность (Linux, Windows NT) |
| Микроядро | В ядре — минимум; драйверы в user space | Безопасность, сертификация (QNX, seL4) |
| Гибридное | Микроядро + "тяжёлые" сервисы в kernel mode | Компромисс (Windows NT, XNU) |
| Экзоядро | Приложения сами строят абстракции поверх ресурсов | Исследования, спецзадачи |
| Unikernel | Одно приложение + минимальная ОС в одном образе | Облако, микросервисы с малым overhead |
Docker не "новая ОС". Это изоляция процессов средствами существующего ядра Linux (namespaces, cgroups). Требование "быстрый старт приложения" решается на уровне замены ядра.
Подходы к реализации подсистем
Планирование CPU
- Статическое — фиксированные приоритеты (RTOS).
- Динамическое — меняется по поведению (интерактив vs batch).
- Справедливое — CFS в Linux (см. Планирование процессора — классические алгоритмы).
Память
- Страничная — доминирует (4 KiB, huge pages).
- Сегментная — исторически x86, сегодня чаще в гибриде с paging.
- Подкачка — файл swap / pagefile; политика swappiness.
Синхронизация
- Примитивы ядра — mutex, semaphore, futex (Linux).
- Примитивы POSIX для приложений; ядро обеспечивает блокировку и пробуждение.
- См. Гонки, критические секции и разделяемая память, Тупики (deadlock) и защита от них.
Ввод-вывод
- Слоистая модель: syscall → VFS / block layer → драйвер → DMA.
- Синхронный и асинхронный I/O; очереди (io_uring).
- См. Подсистема ввода-вывода в ОС.
Как сформулировать требования на практике
Пример чек-листа для выбора ОС под сервис:
- Нужен ли жёсткий дедлайн ответа? → RTOS или tuning GPOS.
- Сколько изоляции между компонентами? → ВМ, контейнеры, отдельные пользователи.
- Какой стек (Java, .NET, Go) и лицензии?
- Есть ли аппаратная поддержка (ARM, x86, GPU, TPM)?
- Кто обновляет ядро и когда допустим reboot?
Для учебного проекта достаточно явно записать — "GPOS, многопользовательская, виртуальная память, TCP/IP, ext4/NTFS" — и сопоставить с классификацией.
Связь с остальным разделом
Рекомендуемый порядок после этой статьи:
- История ОС — откуда взялись требования.
- Ядро — как требования воплощаются в архитектуре.
- Подсистемы: процессы → синхронизация → тупики → память → I/O.
Чек-лист самопроверки — вопросы 104–107 по требованиям и архитектурам ядра.
Практический шаблон требований к ОС
Ниже универсальный шаблон, который помогает уйти от "общих слов" и быстро собрать требования для проекта:
- Нагрузка — сколько пользователей, какой пиковый RPS, какие SLA по задержке.
- Безопасность — требования по шифрованию, журналированию, разграничению прав.
- Надежность — допустимый простой, RTO/RPO, стратегия обновлений и откатов.
- Совместимость — обязательные версии рантаймов, библиотек, драйверов.
- Эксплуатация — кто администрирует, как мониторим, как реагируем на инциденты.
Полезно сверять этот список с материалами о ядре, о процессах, о памяти, о вводе-выводе.