Операционные системы

Теория: Архитектура операционной системы

Операционная система — это посредник между человеком и аппаратной частью компьютера. Она управляет ресурсами, обеспечивает работу программ и делает взаимодействие с техникой удобным и безопасным. ОС состоит из нескольких частей: ядра, драйверов, оболочки и пользовательского пространства. Каждый слой выполняет свою функцию, но все они работают согласованно.

Ядро — основа операционной системы

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

Существует несколько типов ядер.

  • Монолитное ядро (например, в Linux) включает все подсистемы — планировщик, драйверы, файловые системы, сетевые стеки — в едином пространстве. Оно быстрое, но ошибка в одном модуле может привести к сбою всей системы.
  • Микроядро (Minix, QNX) оставляет внутри только базовые механизмы — управление процессами, памятью и межпроцессным взаимодействием. Остальные службы работают как отдельные процессы в пользовательском пространстве. Такой подход безопаснее, но требует больше обменов между процессами.
  • Гибридные ядра (Windows, macOS) совмещают оба подхода, оставляя внутри только критически важные части, а остальное выносят наружу ради производительности и стабильности.

Ядро выполняет несколько ключевых функций:

  • Планирование процессов: решает, какая программа получит процессор в следующий момент.
  • Управление памятью: выделяет и освобождает память, защищает процессы друг от друга и создаёт виртуальное адресное пространство.
  • Работа с устройствами ввода-вывода: принимает сигналы от дисков, клавиатур, сетевых карт, экранов и передаёт их нужным процессам.
  • Обработка системных вызовов: обеспечивает контролируемый доступ приложений к ресурсам, чтобы они не могли повредить систему.

Ядра пишут на языках низкого уровня — чаще всего на C, а самые критичные участки — на ассемблере. Это позволяет точно управлять памятью и регистрами процессора, обеспечивая стабильность и скорость.

Драйверы — связь между ядром и устройствами

Чтобы ядро могло взаимодействовать с внешним оборудованием, используются драйверы. Драйвер — это программа, которая знает, как управлять конкретным устройством: клавиатурой, видеокартой, диском или принтером.

Когда пользователь вставляет флешку, контроллер шины USB посылает сигнал ядру. Ядро передаёт его драйверу, драйвер распознаёт устройство, сообщает параметры и подготавливает файловую систему. После этого ОС «монтирует» носитель, и пользователь видит его в проводнике.

Драйверы бывают двух типов:

  • Встроенные, поставляемые с ОС — обеспечивают работу стандартных устройств (клавиатура, сетевая карта, диск).
  • Внешние, разработанные производителями оборудования и устанавливаемые отдельно- -хитектура драйверов зависит от типа ядра:
  • В монолитных системах (Linux) драйверы могут быть частью ядра. Это ускоряет работу, но ошибка в драйвере может вызвать сбой всей системы.
  • В модульных системах драйвер загружается отдельно как kernel module и может быть заменён без перезагрузки.
  • В микроядерных системах драйверы работают в пользовательском пространстве. Это безопаснее, но немного медленнее.

Драйверы взаимодействуют с ядром через различные подсистемы и API, которые обеспечивают единые правила работы с устройствами. У каждого класса оборудования есть своя инфраструктура:

  • VFS (Virtual File System) — не интерфейс драйвера, а слой абстракции файловых систем. Он позволяет ядру работать с разными типами файловых систем (ext4, XFS, FAT, NTFS и др.) через единый набор операций.
  • Netlink — это канал связи между ядром и пользовательским пространством, который используется для управления сетевыми интерфейсами, маршрутизацией и другими низкоуровневыми параметрами.
  • ALSA (Advanced Linux Sound Architecture)подсистема звука, включающая и драйверы в ядре, и пользовательские библиотеки для приложений. Она обеспечивает доступ к аудиоустройствам и обработку потоков звука.

Таким образом, драйверы не обращаются к «универсальному интерфейсу», а работают через соответствующие подсистемы ядра, каждая из которых отвечает за свой тип устройств.

Кроме аппаратных, существуют и виртуальные драйверы — они не управляют реальным устройством, а эмулируют его работу. Например, виртуальный сетевой адаптер в гипервизоре или драйвер, монтирующий образ диска.

Основной язык разработки драйверов — C. Он позволяет напрямую работать с памятью и регистрами устройств. В критических местах используют ассемблер, а для высокоуровневых частей иногда — ограниченный C++ (например, в macOS через IOKit). В Linux активно развиваются драйверы на Rust — для повышения безопасности и защиты от типичных ошибок C.

Без драйверов операционная система не может взаимодействовать с оборудованием. Они превращают электрические сигналы и машинные коды в понятные данные и делают возможным работу всех устройств.

Оболочка — интерфейс между человеком и системой

Оболочка (shell) — это уровень, через который пользователь управляет системой. Она принимает команды, передаёт их ядру и отображает результат. Без оболочки операционная система была бы недоступна: именно она превращает действия человека в системные вызовы.

Существует два типа оболочек:

  • Командная (CLI, Command Line Interface): текстовый интерфейс, где пользователь вводит команды вручную. Примеры: Bash, Zsh, PowerShell.
  • Графическая (GUI, Graphical User Interface): визуальный интерфейс с окнами, иконками и кнопками — как в Windows Explorer, Finder или GNOME.

Командная оболочка работает по принципу цикла REPL (Read-Eval-Print-Loop): она читает ввод, анализирует команду, выполняет программу и выводит результат. Shell также может исполнять сценарии — последовательности команд в виде скриптов. Это делает его мощным инструментом автоматизации.

Графическая оболочка решает те же задачи, что и терминал, но через визуальные элементы. Когда пользователь дважды кликает по файлу, событие сначала обрабатывается средой рабочего стола — она определяет, какое приложение связано с этим типом файла, и запускает его. Уже само приложение вызывает системные функции вроде open() или read() для доступа к данным.

Таким образом, графический интерфейс лишь скрывает технические детали, но под капотом выполняются те же операции, что и при работе через командную строку.

Современные оболочки поддерживают автодополнение, историю команд, фоновые процессы, перенаправление потоков (|, \>, \<) и возможность объединять программы в цепочки. Это делает работу с системой гибкой и эффективной.

Цикл REPL — «чтение → выполнение → вывод результата»

Bash:

# Каждая команда вводится вручную.
# Shell читает ввод (Read), анализирует (Eval), выполняет (Exec) и выводит результат (Print).
pwd            # Показать текущий каталог
date           # Показать текущие дату и время
echo "Hello"   # Напечатать строку в стандартный вывод

PowerShell:

```powershell
# Тот же REPL: ввод — выполнение — результат.
Get-Location    # Аналог pwd
Get-Date        # Аналог date
"Hello"         # Просто вывод строки

Действие через GUI и через CLI

CLI делает то же, что пользователь при двойном клике по файлу:

xdg-open report.pdf    # Linux: открыть файл программой по умолчанию
open report.pdf        # macOS
start report.pdf       # Windows PowerShell

Копирование файла — аналог перетаскивания мышкой в папку:

cp report.pdf ~/Documents/        # Bash
Copy-Item report.pdf ~/Documents/ # PowerShell

Windows: модель WDM и системные службы

Windows использует Windows Driver Model (WDM) и её наследницу — Windows Driver Framework (WDF). Это мощная, но сложная архитектура, где драйверы работают в нескольких слоях и взаимодействуют с ядром через строго определённые интерфейсы.

  • Ядро Windows (NT Kernel) предоставляет базовые функции — планирование, память, обработку прерываний.
  • Kernel-mode drivers работают в режиме ядра и имеют полный доступ к ресурсам. Это, например, драйверы видеокарты, сетевой карты, файловых систем.
  • User-mode drivers (UMDF) работают в пользовательском пространстве и изолированы от ядра. Они безопаснее, потому что сбой в таком драйвере не приведёт к падению всей системы.

Когда вы вставляете флешку, Windows активирует службу Plug and Play (PnP Manager). Она определяет тип устройства и обращается к каталогу DriverStore — внутреннему хранилищу установленных драйверов. Оттуда выбирается подходящий пакет (файлы .inf, .sys, .cat и др.), и его компоненты устанавливаются в систему.

После этого исполняемый файл драйвера (.sys) копируется в каталог C:\Windows\System32\drivers и загружается в память. Если драйверу нужны дополнительные функции, Windows подключает соответствующие системные службы — например, File System Driver (FSD) или Storage Stack. На завершающем этапе создаётся объект устройства, который связывает приложения с физическим оборудованием через системный интерфейс.

Многие драйверы Windows сопровождаются сервисами (services) — это отдельные процессы, работающие в пользовательском пространстве. Например:

  • spoolsv.exe — служба печати, взаимодействует с драйверами принтеров;
  • audiosrv — аудиосервис, общается с драйверами звуковых карт;
  • nvsvc64.exe — сервис NVIDIA, управляющий настройками GPU.

Таким образом, в Windows драйвер — это не просто файл .sys, а целая экосистема из ядрового модуля, службы и инструментов управления.

Linux: модули ядра и файловая модель устройств

В Linux всё устроено проще и прозрачнее. Драйверы — это модули ядра (kernel modules), которые можно загрузить или выгрузить без перезагрузки системы.

  • Каталог /lib/modules/$(uname -r)/kernel/ содержит все модули для конкретной версии ядра.
  • Команды lsmod, modprobe, rmmod управляют ими: показывают, загружают и удаляют модули.

Пример:

lsmod | grep usb_storage    # посмотреть, загружен ли драйвер USB-хранилища
sudo modprobe usb_storage   # загрузить драйвер
sudo rmmod usb_storage      # выгрузить драйвер

Linux использует концепцию виртуальной файловой системы устройств (/dev). Каждое устройство представлено как файл: /dev/sda — диск, /dev/tty0 — терминал, /dev/null — специальное устройство-пустышка. Когда программа пишет данные в этот «файл», ядро передаёт их драйверу устройства, а тот — дальше в контроллер железа.

Linux-ядро поддерживает горячее подключение устройств через udev. Это фоновый демон, который отслеживает новые устройства и автоматически подгружает нужные драйверы, создавая соответствующие файлы в /dev.

macOS: объектная модель I/O Kit

В macOS драйверная система построена на фреймворке I/O Kit, написанном на ограниченном подмножестве C++. Здесь драйверы реализованы как объекты, которые наследуют базовый класс IOService. Каждый драйвер — это экземпляр класса, который взаимодействует с другими через чётко определённые методы (методы подключения, инициализации, обмена данными).

I/O Kit разделён на уровни:

  • Kernel Extensions (kexts) — модули, работающие в режиме ядра.
  • User-space daemons — службы, которые расширяют функции драйверов и предоставляют интерфейсы приложениям.
  • Frameworks — библиотеки, через которые пользовательские программы взаимодействуют с драйверами.

Например, когда вы подключаете устройство по USB:

  1. I/O Kit создаёт объект IOUSBDevice;

  2. macOS ищет подходящий драйвер-класс, например IOUSBMassStorageDriver;

  3. Затем запускает вспомогательный демон, который связывает драйвер с Finder и системой монтирования томов.

Пользовательское пространство

Всё, что работает поверх ядра и оболочки, называют пользовательским пространством (userland). Это приложения, утилиты и сервисы, которые запускает человек. Они не обращаются к железу напрямую, а используют системные вызовы, предоставляемые ядром. Такой подход обеспечивает безопасность и изоляцию — сбой одной программы не влияет на другие и не нарушает работу системы.

Как система «видит» флешку

Давайте вставим флешку в USB-порт. Внутри компьютера разворачивается целая цепочка действий — от сигнала железа до появления значка на экране.

  1. Сначала контроллер USB на материнской плате фиксирует, что к разъёму подключено новое устройство, и посылает ядру сигнал прерывания.
  2. Диспетчер прерываний в ядре получает уведомление и передаёт его в подсистему USB.
  3. Ядро опрашивает устройство, считывает его идентификатор и определяет, какой драйвер подойдёт.

Затем в систему загружается соответствующий драйвер.

  • В Linux это модуль usb_storage.ko, который подключается через систему udev.
  • В Windows — драйвер USBSTOR.sys, который находится службой Plug and Play.
  • В macOS — объект IOUSBMassStorageDriver из фреймворка I/O Kit. Драйвер сообщает ядру, что в системе появился новый блоковый носитель и готов к работе.

После этого ядро создаёт для него интерфейс.

  • В Linux это файл /dev/sdb или /dev/sdb1, представляющий флешку как устройство хранения данных.
  • В Windows накопителю назначается буква, например E:\.

Затем ядро обращается к подсистеме хранения данных и монтирует файловую систему. Оно считывает заголовок носителя, определяет формат (FAT32, exFAT, NTFS) и делает содержимое доступным для чтения и записи.

Когда всё готово, сигнал о новом устройстве поступает оболочке — графической или текстовой. Finder в macOS, Проводник в Windows или Nautilus в Linux обновляют интерфейс и показывают значок подключённого тома.

Снаружи это выглядит просто, но за действием «вставить флешку» стоит взаимодействие всех уровней операционной системы — от контроллера и драйвера до ядра, подсистемы хранения и оболочки.

Итог

  • Операционная система — это многоуровневая структура.
  • На нижнем уровне — железо, над ним — ядро, которое управляет ресурсами и процессами.
  • С ядром взаимодействуют драйверы, обеспечивая связь с устройствами.
  • Выше располагается оболочка, которая переводит действия пользователя в команды.
  • Наконец, на самом верху находится пользовательское пространство, где работают программы.

Эти уровни создают замкнутый цикл взаимодействия: человек ↔ оболочка ↔ ядро ↔ драйверы ↔ железо. Именно такая архитектура делает возможной работу любого компьютера — от смартфона до суперкомпьютера.

Рекомендуемые программы

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845