Мы продолжаем возрождение информационных технологий после "мощнейшей катастрофы". В прошлый раз был показан очень компактный 16-разрядный RISC процессор, нетребовательность которого позволяет как спаять его из простейших микросхем, так и уместить в программируемой микросхеме CPLD среднего размера. Сейчас уже понятно, что бурное развитие программного обеспечения невозможно без таких составляющих, как компилятор высокоуровневого языка и хорошая операционная система (ОС). Если компилятор по счастливому стечению обстоятельств есть, то над конструкцией хорошей операционной системы стоит подумать.
Что значит "хорошая" ОС?
Определение
Операционная система это программный код, предназначенный для управления ресурсами компьютера, кроме того, для организации взаимодействия пользователя с компьютером. Компьютеров разных конструкций большое количество, да условия их функционирования могут отличаться, поэтому насколько хорошо программа управляет ресурсами и работает с пользователем можно сказать только после четкого определения критерия "хорошо". Что для одних хорошо - для других плохо.
Условия работы и выполняемые задачи
Наши конкретные исходные данные следующие: минималистичный 16-битный процессор RISC архитектуры, широкий набор периферийного оборудования: клавиатура, мышь, жесткий диск, интерфейсы ввода-вывода, монитор 640x480 пикселей разрешения минимум. Нужно еще подумать над перечнем задач в период постапокалипсиса. Вырисовываются контуры персонального компьютера, способного к выполнению задач автоматизации чего-либо.
Конструкции ОС
С монолитным ядром
Операционные системы по своей конструкции делятся на 2 крупных лагеря: с монолитным ядром и с микроядром.
На рисунке выше схематично показана особенность устройства ОС с монолитным ядром.
- Application - пользовательское приложение,
- Syscall Handler - обработчик системных вызовов,
- File System - абстракция, представляющая все оборудование компьютера в виде файлов,
- Device Drivers - функции работы с оборудованием компьютера,
- Scheduler - планировщик выполнения задач,
- Memory Manager - функции управления памятью,
- Hardware - оборудование компьютера.
В одной из прошлых статей мы разбирались с понятием системного вызова, оно же программное прерывание. Это переход выполнения программного кода, работающего без привилегий (зеленая область) к программному коду, работающему с привилегиями (фиолетовая область). Граница между этими режимами проведена красной линией. Переход через границу сопровождается сохранением содержимого регистров процессора, затем выполнением программного кода в фиолетовой области. Возврат из системного вызова возвращает содержимое регистров для дальнейшего выполнения программы пользователя. Код пользователя с потенциальными ошибками, поэтому его действия ограничены и контролируются, все общение с оборудованием только через формализованный интерфейс системных вызовов (Syscall). Попытки нарушить эти правила приводят к принудительной остановке приложения.
С микроядром
Отличия от предыдущего варианта видны невооруженным взглядом. Красная линия перехода в зону кода с высокими привилегиями ограничивает лишь некоторое минимальное ядро исполняемого кода с минимумом функций (Minimal Kernel). Остальные функции выполняются также как и обычное приложение пользователя: драйверы устройств (Device Drivers, I/O Device, Display Device), функции работы с файлами и прочее.
Могут ли потенциально некорректные приложения нарушить работу друг друга? Нет, как и в другом случае, адресные пространства всех приложений контролируются аппаратно и в случае попытки обращения к памяти за пределами своих границ приложение будет закрыто.
Каким образом приложение пользователя взаимодействует, например, с файловой системой? При помощи системного вызова, называемого сообщением. Единственное, для чего необходимо ядро в фиолетовой области - обработать системный вызов любого из приложений в зеленой области. Да, еще и периодически менять запущенные задачи по сигналу таймера (многозадачность).
Посылая сообщение какому-либо из процессов, приложение совершает строго формализованный системный вызов, где указывается что за сообщение (кому) и его параметры. Функция ядра (Minimal Kernel) заключается в постановке этого сообщения в очередь к конкретному процессу в зеленой области. Очередь сообщений находится в пределах адресного пространства процесса и обращение к ней это абсолютно корректное действие. Нарушение чужого адресного пространства ядром (занесение сообщения в очередь) при этом допустимо, так как оно имеет привилегии.
Достоинства и недостатки
Теперь настало время говорить о том, что в конструкциях ОС является хорошим, а что плохим. Еще лет 5 назад мировоззрение говорило, что нет ничего совершеннее монолитного ядра. В расчет бралась лишь скорость обработки системных вызовов. Попадая в Syscalls, вызов довольно оперативно добирался до оборудования компьютера или создавал в его памяти нужные структуры данных.
В микроядерной ОС возможна ситуация, когда добраться до оборудования можно лишь пройдя несколько уровней прокладок-приложений. Например, елочная гирлянда подключена по интерфейсу USB, контроллер которого подключен к системной шине. Каждый слой функций расположен в своем приложении.
- Для начала мы должны обратиться к драйверу гирлянды, где указать при помощи структуры данных какими цветами зажечь лампы (отправка сообщения),
- Драйвер гирлянды обращается к драйверу контроллера USB интерфейса с предложением передать конкретный блок данных контроллеру гирлянды (отправка сообщения),
- Драйвер USB запрашивает драйвер системной шины с предложением передать блок данных для USB контроллера (отправка сообщения).
Структура данных для поджига ламп с каждым шагом в каждом драйвере заворачивается в обертку, необходимую для прохождения своего участка в оборудовании (инкапсуляция). Обратите внимание, что системный вызов (отправка сообщения) возникает несколько раз.
Однако! Напоминаю, что процессор 16-разрядный с разрядностью адресной шины 16 бит. Каждый процесс (приложение) способен работать с памятью в своем линейном пространстве 0 - 64 кб. Это очень мало, если посмотреть на перечень задач монолитного ядра, но вполне достаточно, если функции разбиты на группы и расположены в своих предложениях, как в операционных системах с микроядром. Каждое небольшое приложение обладает своим небольшим пространством адресов. Получая время работы на процессоре, приложение достает из своей очереди сообщение и занимается его обработкой.
В нашем мире не все делится на черное и белое. Такое деление на монолиты и микроядра это скорее академические крайности, нужные лишь для демонстрации подходов. Реальные операционные системы это скорее нечно среднее. Windows и BSD системы это гибриды, старающиеся найти баланс и взять все самое лучшее из двух полярных подходов.
Для лучшего понимания лучше прочесть:
- Адресное пространство,
- Программное прерывание (системный вызов),
- Многозадачность.
Поддержите статью лайком если понравилось и подпишитесь чтобы ничего не пропускать.
Также не обойдите вниманием канал на YouTube. Подписки и лайки будут приятным ответом от аудитории.