Экзоядро: хорошо забытое новое

30 март, 2005 - 23:00Андрій Кухар Экзо (от греч. exo -- вне, снаружи) -- приставка, означающая: внешний, наружный, указывающая на связь с внешней средой (например, экзосфера).


Мотивы

Ровно десять лет тому назад группой сотрудников всемирно известных лабораторий компьютерных наук Массачусетского технологического института -- Д. Энглером (Dawson R. Engler), Ф. Каашуэком (M. Frans Kaashoek), Дж. О'Тулом мл. (James W. O'Toole Jr.) и др. -- были опубликованы материалы, посвященные архитектуре операционных систем с так называемым экзоядром. Мотивацией для новой разработки послужило слишком свободное толкование канонического понятия ОС, приведшее к полному разброду в индустрии. Напомним, что по определению ОС -- это программное обеспечение, которому предписывается выполнение двух главных задач: абстрагирования и защиты системных ресурсов. Первая заключается в предоставлении в распоряжение пользователя-программиста вместо имеющегося реального физического оборудования его простой и удобной в обращении абстракции, именуемой виртуальной машиной. Вторая же состоит в безопасном распределении системных ресурсов между прикладными программами с обеспечением максимальной эффективности их эксплуатации. Так вот, по мнению авторов новой идеи, глубинные причины практически всех проблем традиционных ОС того времени (низкая надежность, плохая приспособляемость, невысокая производительность, недостаточная гибкость) скрывались именно в абстракциях:

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

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

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

Со всеми вышеперечисленными недугами можно было бы справиться, если бы прикладные программисты могли игнорировать эту прослойку (между аппаратурой и прикладным ПО) и реализовывать собственные специальные абстракции. Увы, из-за преобладания высокоуровневых интерфейсов нынешних ОС это невозможно. Кроме того, не удастся добиться чего-либо действенного (т. е. легкого, быстрого и дешевого) посредством эмуляции приложением собственных абстракций над существующим слоем абстракций ОС".

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


Ломая традиции...

Все эти противоречия и была призвана разрешить экзоядерная архитектура, основанная на нескольких принципах, с которыми стоит познакомиться более подробно.

1. Экзоядро не должно осуществлять абстрагирования физических ресурсов (далее для краткости будем называть их просто "ресурсами"). Для выполнения этой задачи предназначены непривилегированные прикладные библиотеки, в терминологии экзоядерной архитектуры называемые "библиотечной операционной системой" (libOS, library operating system). В рамках каждого конкретного приложения может быть реализована своя libOS -- сугубо в необходимых масштабах.

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

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

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

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


XOK/ExOS

Естественно, сама по себе теория мало чего стоит, поэтому имеет смысл хотя бы кратко познакомиться с реализацией экзоядерной архитектуры на примере XOK/ExOS -- экспериментальной связки собственно экзоядра XOK и библиотечной операционной системы ExOS. Данный тандем, а вместе с ним разнообразные пользовательские программы и инструментальные средства Unix составляют дистрибутив exopc, альфа-релиз которого (около 53 MB) распространяется с исходными текстами на более чем либеральных условиях и доступен для загрузки по адресу amsterdam.lcs.mit.edu/exo. Дистрибутив до сих пор не самодостаточен, и чтобы получить "почти" работающую систему (с учетом текущей стадии проекта), необходимо всего лишь обзавестись одним из вариантов Linux или *BSD для выполнения сборки -- причем, так как в exopc используется бинарный формат, аналогичный OpenBSD, в Linux придется применять кросс-компилятор. Также заранее стоит выяснить и вопросы совместимости аппаратного обеспечения.

Итак, XOK представляет собой небольшой безопасный распределитель ресурсов x86 совместимых машин. В нем применяется механизм "безопасных связей" (secure bindings), отделяющий процедуру получения разрешения на эксплуатации ресурса от фактического его использования, в результате чего также повышается производительность системы. Во-первых, проверки, осуществляемые при связывании, -- это простые и быстрые операции ядра (или даже оборудования при их аппаратной реализации). Во-вторых, при безопасном связывании получение разрешения происходит единожды, а последующее управление выполняется независимо. Поскольку именно прикладное ПО отвечает за многие сложные высокоуровневые объекты (например, файлы, каталоги, сетевые соединения), экзоядро должно "вникать" в их семантику только во время связывания, для реализации же проверок в процессе доступа этого не требуется. Таким образом, экзоядро защищает ресурсы, фактически не имея представления о них.

Библиотечная операционная система ExOS есть не что иное, как "Unix в библиотеке". Реализации Unix-абстракций были вычленены из ядра ОС 4.4BSD, благодаря чему они позволяют запускать без модификации многие приложения, включая достаточно сложные, вроде GCC, Csh, Perl, Vi, Telnet. Для экономии ресурсов используются разделяемые библиотеки. Увы, отсутствуют процессные группы, оконная система и даже механизм подкачки, поскольку низкоуровневый интерфейс XOK предусматривает его прикладную реализацию -- зато подкачка может выполняться с локального диска, по сети или посредством регенерации данных, со всевозможными преобразованиями страниц, как то компрессией, верификацией содержимого с помощью цифровых сигнатур, шифрования.


Применение

В полном соответствии с тезисами Роба Пайка (Rob Pike), высказанными им в лекции "Исследования в области системного ПО нерелевантны", IT-сообщество почти не обратило внимания на очередную академическую разработку. Действительно, более традиционные архитектуры ОС еще не исчерпали своих возможностей, а стремительное повышение их ресурсоемкости пока успешно компенсируется удешевлением и развитием вычислительного оборудования. Однако не исключено, что такая своеобразная игра "в догонялки" когда-нибудь прекратится и специалисты наконец всерьез задумаются о максимально эффективном использовании имеющихся ресурсов. До тех же пор экзоядерной архитектуре суждено оставаться академической игрушкой, хотя, по большому счету, для нее и сегодня нашлась бы своя ниша -- самодостаточные приложения, требующие максимальной производительности, к примеру Web- и NFS-серверы, СУБД, системы автоматического управления, научные расчеты. Компактность и приближенность к оборудованию экзоядра позволяет также надеяться на определенные успехи в сегменте так называемых мобильных вычислений.


К слову

Недавно в MIT был организован курс "Проектирование операционных систем" (6.828: Operating System Engineering), где на лабораторных работах студенты пишут собственные клоны ОС семейства экзо-Unix, JOS. Получив элементарный скелет, они разрабатывают основные составляющие будущей системы: загрузчик, механизмы управления памятью и процессами, системный вызов fork() и механизмы межпроцессного взаимодействия (IPC, Inter-Process Communication), системный вызов exec() и примитивную файловую систему, командную оболочку. Казалось бы, вряд ли можно придумать лучший подход к углубленному изучению языка C, ассемблерного программирования, фундаментальных концепций ОС, однако отечественные вузы почему-то упорно не хотят брать его на свое вооружение.