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

         

Проект Singularity


Наиболее радикальный подход предложен в Microsoft Research. По существу, этот подход отвергает понятие операционной системы как единой программы, выполняемой в режиме ядра, плюс некоторый набор пользовательских процессов, выполняемых в режиме пользователя, и заменяет его системой, написанной на новом типизированном языке, в котором отсутствуют проблемы с указателями и пр., свойственные C и C++. Подобно двум предыдущим, этот подход существует десятилетия. Он использовался в компьютере Burroughs B5000. Тогда единственным доступным языком был Algol, и защита поддерживалась не устройством управления памятью, а за счет невозможности генерации "опасного" кода компилятором языка Algol.

Система, называемая Singularity (http://research.microsoft.com/os/singularity), пишется почти целиком на новом типизированном языке Sing#. Этот язык основан на C#, но дополнен примитивами передачи сообщений, семантика которых определяется формальными, письменными контрактами. Поскольку безопасность языка строго ограничивает поведение системы и процессов, все процессы выполняются в едином виртуальном адресном пространстве. Эта схема ведет как к безопасности (поскольку компилятор не позволяет процессу обращаться к данным любого другого процесса), так и к эффективности (поскольку устраняется потребность в обращениях к ядру и переключениях контекста).

Кроме того, схема Singularity является гибкой, потому что каждый процесс является замкнутым объектом и потому обладает собственным кодом, структурами данных, распределением памяти, подсистемой времени выполнения, библиотеками и сборщиком мусора. Устройство управления памятью используется только для отображения страниц, а не для образования отдельной защищенной области для каждого процесса. Ключевым принципом организации Singularity является запрещение динамических расширений процессов. В частности, не допускаются загружаемые драйверы и подключаемые модули браузеров, поскольку они могут привнести непроверенный код, который может повредить основной процесс.
Такие расширения должны запускаться, как отдельные процессы, полностью отгороженные и общающиеся на основе стандартного механизма IPC.

Операционная система Singularity состоит из процесса микроядра и набора пользовательских процессов, обычно исполняемых в общем виртуальном адресном пространстве. Микроядро управляет доступом к аппаратуре, выделяет и освобождает память, создает, ликвидирует и планирует потоки управления, управляет синхронизацией потоков управления с помощью мьютексов, межпроцессной синхронизацией с использованием каналов, а также вводом-выводом. Каждый драйвер устройства выполняется в отдельном процессе.

Хотя большая часть микроядра написана на Sing#, небольшая часть написана на C#, C++ и языке ассемблера, и этой части приходится доверять, поскольку верифицировать ее невозможно. Доверенный код включает уровень абстракции аппаратуры и сборщик мусора. Уровень абстракции аппаратуры скрывает от системы низкоуровневые детали аппаратуры, такие как порты ввода-вывода, пути запроса прерываний, каналы прямого доступа к памяти и таймеры. Остальной части операционной системы предоставляется машинно-независимая абстракция.

Пользовательские процессы получают системные услуги путем посылки строго типизированных сообщений в микроядро через двухточечные каналы. В отличие от других систем передачи сообщений, в которых поддерживаются библиотечные функции SEND и RECEIVE, в Sing# полностью поддерживаются каналы на уровне языка, включая формальную типизацию и спецификации протокола.

В Singularity поддерживается совместно используемая процессами "куча" объектов, но в каждый момент времени каждый объект из кучи принадлежит только одному процессу. Однако владение объектом может быть передано другому процессу через канал. Например, когда драйвер диска считывает блок, он помещает этот блок в кучу. Потом система передает дескриптор (handle) этого блока процессу, запросившему данные, поддерживая принцип единственного владельца, но позволяя передавать данные без копирования.



Для всех служб в Singularity поддерживается единое иерархическое пространство имен. Сервер корневого имени управляет верхней частью дерева, но к его узлам могут монтироваться другие серверы имен. В частности, файловая система, которая является всего лишь процессом, монтируется к узлу /fs, так что /fs/users/linda/foo может быть именем пользовательского файла. Файлы реализуются в виде B-деревьев, ключами которых являются номера блоков. При обработке системных вызовов файловая система требует от дискового драйвера поместить в кучу нужные блоки. Затем владение блоком передается по цепочке пользовательскому процессу.

Для каждого компонента системы имеются метаданные, описывающие его зависимости, экспортирование, ресурсы и поведение. Эти метаданные используются для верификации. Образ системы состоит из микроядра, драйверов и приложений, требуемых для выполнения системы, и их метаданных. Внешние верификаторы могут выполнить многочисленные проверки образа до запуска системы; в частности, таким образом можно убедиться в том, что драйверы не конфликтуют по ресурсам. Верификация состоит из трех шагов. Сначала компилятор контролирует типы, владение объектами, протоколы каналов и т.д. Затем компилятор генерирует внутреннее представление на языке MSIL (Microsoft Intermediate Language), переносимый байт-код, который может проверяться верификатором. Наконец, представление системы на MSIL компилируется в командный код x86 компилятором постобработки, который может вставлять в код проверки времени выполнения. Такая избыточная верификация служит для отлавливания ошибок в самих верификаторах.

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


Содержание раздела