Операционные системы
Теория: Архитектура операционной системы
Операционная система — это посредник между человеком и аппаратной частью компьютера. Она управляет ресурсами, обеспечивает работу программ и делает взаимодействие с техникой удобным и безопасным. ОС состоит из нескольких частей: ядра, драйверов, оболочки и пользовательского пространства. Каждый слой выполняет свою функцию, но все они работают согласованно.
Ядро — основа операционной системы
В центре любой ОС находится ядро. Это главный компонент, управляющий процессором, памятью и устройствами. Ядро распределяет ресурсы, запускает процессы, контролирует доступ и обеспечивает безопасность. Оно работает в привилегированном режиме (режиме ядра), где ему доступны все возможности оборудования напрямую.
Существует несколько типов ядер.
- Монолитное ядро (например, в 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:
Действие через GUI и через CLI
CLI делает то же, что пользователь при двойном клике по файлу:
Копирование файла — аналог перетаскивания мышкой в папку:
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управляют ими: показывают, загружают и удаляют модули.
Пример:
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:
-
I/O Kit создаёт объект
IOUSBDevice; -
macOS ищет подходящий драйвер-класс, например
IOUSBMassStorageDriver; -
Затем запускает вспомогательный демон, который связывает драйвер с Finder и системой монтирования томов.
Пользовательское пространство
Всё, что работает поверх ядра и оболочки, называют пользовательским пространством (userland). Это приложения, утилиты и сервисы, которые запускает человек. Они не обращаются к железу напрямую, а используют системные вызовы, предоставляемые ядром. Такой подход обеспечивает безопасность и изоляцию — сбой одной программы не влияет на другие и не нарушает работу системы.
Как система «видит» флешку
Давайте вставим флешку в USB-порт. Внутри компьютера разворачивается целая цепочка действий — от сигнала железа до появления значка на экране.
- Сначала контроллер USB на материнской плате фиксирует, что к разъёму подключено новое устройство, и посылает ядру сигнал прерывания.
- Диспетчер прерываний в ядре получает уведомление и передаёт его в подсистему USB.
- Ядро опрашивает устройство, считывает его идентификатор и определяет, какой драйвер подойдёт.
Затем в систему загружается соответствующий драйвер.
- В 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 обновляют интерфейс и показывают значок подключённого тома.
Снаружи это выглядит просто, но за действием «вставить флешку» стоит взаимодействие всех уровней операционной системы — от контроллера и драйвера до ядра, подсистемы хранения и оболочки.
Итог
- Операционная система — это многоуровневая структура.
- На нижнем уровне — железо, над ним — ядро, которое управляет ресурсами и процессами.
- С ядром взаимодействуют драйверы, обеспечивая связь с устройствами.
- Выше располагается оболочка, которая переводит действия пользователя в команды.
- Наконец, на самом верху находится пользовательское пространство, где работают программы.
Эти уровни создают замкнутый цикл взаимодействия: человек ↔ оболочка ↔ ядро ↔ драйверы ↔ железо. Именно такая архитектура делает возможной работу любого компьютера — от смартфона до суперкомпьютера.

