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

Все остальные более высокоуровневые функции ядра оформляются в; виде приложений, работающих в пользовательском режиме. Однозначного решения о том, какие из системных функ¬ций нужно оставить в привилегированном режиме, а какие перене¬сти в пользовательский, не существует. В общем случае многие ме¬неджеры ресурсов, являющиеся неотъемлемыми частями обычного ядра — файловая система, подсистемы управления виртуальной памятью и процессами, менеджер безопасности и т. п., — стано¬вятся «периферийными» модулями, работающими в пользователь¬ском режиме.
Работающие в пользовательском режиме менеджеры ресур¬сов имеют принципиальные отличия от традиционных утилит и обрабатывающих программ операционной системы, хотя при мик¬роядерной архитектуре все эти программные компоненты также оформлены в виде приложений. Утилиты и обрабатывающие про¬граммы вызываются в основном пользователями. Ситуации, когда одному приложению требуется выполнение функции (процедуры) другого приложения, возникают крайне редко. Поэтому в операци¬онных системах с классической архитектурой отсутствует меха¬низм, с помощью которого одно приложение могло бы вызвать функции другого.
Совсем другая ситуация возникает, когда в форме приложе¬ния оформляется часть операционной системы. По определению, основным назначением такого приложения является обслуживание запросов других приложений, например создание процесса, выде¬ление памяти, проверка прав доступа к ресурсу и т. д. Именно по¬этому менеджеры ресурсов, вынесенные в пользовательский ре¬жим, называются серверами ОС, то есть модулями, основным назначением которых является об¬служивание запросов локальных приложений и других модулей ОС. Очевидно, что для реализации микроядерной архитектуры необходимым условием является нали¬чие в операционной системе удобного и эффективного способа вы¬зова процедур одного процесса из другого. Поддержка такого ме¬ханизма и является одной из главных задач микроядра.
Схематично механизм обращения к функциям ОС, оформ¬ленным в виде серверов, выглядит следующим образом (рис. 27). Клиент, которым может быть либо прикладная программа, либо другой компонент ОС, запрашивает выполнение некоторой функ¬ции у соответствующего сервера, посылая ему сообщение. Непо¬средственная передача сообщений между приложениями невоз¬можна, так как их адресные пространства изолированы друг от друга. Микроядро, выполняющееся в привилегированном режиме, имеет доступ к адресным пространствам каждого из этих приложе¬ний и поэтому может работать в качестве посредника. Микроядро сначала передает сообщение, содержащее имя и параметры вызы¬ваемой процедуры нужному серверу, затем сервер выполняет за¬прошенную операцию, после чего ядро возвращает результаты кли¬енту с помощью другого сообщения. Таким образом, работа микро¬ядерной операционной системы соответствует известной модели клиент-сервер, в которой роль транспортных средств выполняет микроядро.

8.2. Преимущества и недостатки микроядерной архитектуры
Операционные системы, основанные на концепции микро¬ядра, в высокой степени удовлетворяют большинству требований, предъявляемых к современным ОС, обладая переносимостью, рас¬ширяемостью, надежностью и создавая хорошие предпосылки для поддержки распределенных приложений. За эти достоинства при¬ходится платить снижением производительности, и это является основным недостатком микроядерной архитектуры.
Высокая степень переносимости обусловлена тем, что весь машинно-зависимый код изолирован в микроядре, поэтому для пе¬реноса системы на новый процессор требуется меньше изменений и все они логически сгруппированы вместе.
Расширяемость присуща микроядерной ОС в очень высо¬кой степени. В традиционных системах даже при наличии много¬слойной структуры нелегко удалить один слой и поменять его на другой по причине множественности и размытости интерфейсов между слоями. Добавление новых функций и изменение существу¬ющих требует хорошего знания операционной системы и больших затрат времени. В то же время ограниченный набор четко опреде¬ленных интерфейсов микроядра открывает путь к упорядоченному росту и эволюции ОС. Добавление новой подсистемы требует раз¬работки нового приложения, что никак не затрагивает целостность микроядра. Микроядерная структура позволяет не только добав¬лять, но и сокращать число компонентов операционной системы, что также бывает очень полезно. Например, не всем пользователям нужны средства безопасности или поддержки распределенных вы¬числений, а удаление их из традиционного ядра чаще всего невоз¬можно. Обычно традиционные операционные системы позволяют динамически добавлять в ядро или удалять из ядра только драй¬веры внешних устройств — ввиду частых изменений в конфигура¬ции подключенных к компьютеру внешних устройств подсистема ввода-вывода ядра допускает загрузку и выгрузку драйверов «на ходу», но для этого она разрабатывается особым образом (напри¬мер, среда STREAMS в UNIX или менеджер ввода-вывода в Windows NT). При микроядерном подходе конфигурируемость ОС не вызывает никаких проблем и не требует особых мер — доста¬точно изменить файл с настройками начальной конфигурации си¬стемы или же остановить не нужные больше серверы в ходе работы обычными для остановки приложений средствами.
Использование микроядерной модели повышает надеж¬ность ОС. Каждый сервер выполняется в виде отдельного процесса в своей собственной области памяти и таким образом защищен от других серверов операционной системы, что не наблюдается в тра¬диционной ОС, где все модули ядра могут влиять друг на друга. И если отдельный сервер терпит крах, то он может быть перезапущен без останова или повреждения остальных серверов ОС. Более того, поскольку серверы выполняются в пользовательском режиме, они не имеют непосредственного доступа к аппаратуре и не могут мо¬дифицировать память, в которой хранится и работает микроядро. Другим потенциальным источником повышения надежности ОС является уменьшенный объем кода микроядра по сравнению с тра¬диционным ядром — это снижает вероятность появления ошибок программиро¬вания.
Модель с микроядром хорошо подходит для поддержки распределенных вычислений, так как использует механизмы, ана¬логичные сетевым: взаимодействие клиентов и серверов путем об¬мена сообщениями. Серверы микроядерной ОС могут работать как на одном, так и на разных компьютерах. В этом случае при получе¬нии сообщения от приложения микроядро может обработать его самостоятельно и передать локальному серверу или же переслать по сети микроядру, работающему на другом компьютере. Переход к распределенной обработке требует минимальных изменений в работе операционной системы — просто локальный транспорт за¬меняется на сетевой.
Производительность. При классической организации ОС (рис. 28, а) выполнение системного вызова сопровождается двумя переключениями режимов, а при микроядерной организации (рис. 28, б) — четырьмя. Таким образом, операционная система на ос¬нове микроядра при прочих равных условиях всегда будет менее производительной, чем ОС с классическим ядром. Именно по этой причине микроядерный подход не получил такого широкого рас¬пространения, которое ему предрекали.

Серьезность этого недостатка хорошо иллюстрирует исто¬рия развития Windows NT. В версиях 3.1 и 3.5 диспетчер окон, гра¬фическая библиотека и высокоуровневые драйверы графических устройств входили в состав сервера пользовательского режима, и вызов функций этих модулей осуществлялся в соответствии с мик¬роядерной схемой. Однако очень скоро разработчики Windows NT поняли, что такой механизм обращений к часто используемым функциям графического интерфейса существенно замедляет работу приложений и делает данную операционную систему уязвимой в условиях острой конкуренции. В результате в версию Windows NT 4.0 были внесены существенные изменения — все перечисленные выше модули были перенесены в ядро, что отдалило эту ОС от иде¬альной микроядерной архитектуры, но зато резко повысило ее про¬изводительность.
Этот пример иллюстрирует главную проблему, с которой сталкиваются разработчики операционной системы, решившие применить микроядерный подход, — что включать в микроядро, а что выносить в пользовательское пространство. В идеальном слу¬чае микроядро может состоять только из средств передачи сообще¬ний, средств взаимодействия с аппаратурой, в том числе средств доступа к механизмам привилегированной защиты. Однако многие разработчики не всегда жестко придерживаются принципа миними¬зации функций ядра, часто жертвуя этим ради повышения произво¬дительности. В результате реализации ОС образуют некоторый спектр, на одном краю которого находятся системы с минимально возможным микроядром, а на другом — системы, подобные Windows NT, в которых микроядро выполняет достаточно большой объем функций.
8.3. Совместимость ОС
В то время как многие архитектурные особенности опера¬ционных систем непосредственно касаются только системных про¬граммистов, концепция множественных прикладных сред непо¬средственно связана с нуждами конечных пользователей — воз¬можностью операционной системы выполнять приложения, напи¬санные для других операционных систем. Такое свойство операци¬онной системы называется совместимостью.
Двоичная совместимость и совместимость исходных текстов
Необходимо различать совместимость на двоичном уровне и совместимость на уровне исходных текстов. Приложения обычно хранятся в ОС в виде исполняемых файлов, содержащих двоичные образы кодов и данных. Двоичная совместимость достигается в том случае, когда можно взять исполняемую программу и запустить ее на выполнение в среде другой ОС.
Совместимость на уровне исходных текстов требует нали¬чия соответствующего компилятора в составе программного обеспечения компьютера, на котором предполагается выполнять данное приложение, а также совместимости на уровне библиотек и системных вызовов. При этом необходима перекомпиляция имею¬щихся исходных текстов в новый исполняемый модуль.
Совместимость на уровне исходных текстов важна в основ¬ном для разработчиков приложений, в распоряжении которых эти исходные тексты всегда имеются. Но для конечных пользователей практическое значение имеет только двоичная совместимость, так как только в этом случае они могут использовать один и тот же коммерческий продукт, поставляемый в виде двоичного исполняе¬мого кода, в различных операционных средах и на различных ма¬шинах. Для пользователя, купившего в свое время пакет (например, Lotus 1-2-3) для MS-DOS, важно, чтобы он мог запускать этот полюбившийся ему пакет без каких-либо изменений и на своей но¬вой машине, работающей под управлением, например, Windows NT.
Обладает ли новая ОС двоичной совместимостью или сов-местимостью исходных текстов с существующими операционными системами, зависит от многих факторов. Самый главный из них — архитектура процессора, на котором работает новая ОС. Если про¬цессор использует тот же набор команд (возможно, с некоторыми добавлениями) и тот же диапазон адресов, тогда двоичная совме¬стимость может быть достигнута довольно просто. Для этого доста¬точно соблюдения следующих условий:
• вызовы функций API, которые содержит приложение, должны поддерживаться данной ОС;
• внутренняя структура исполняемого файла приложения должна соответствовать структуре исполняемых файлов данной ОС.
Гораздо сложнее достичь двоичной совместимости опера¬ционным системам, предназначенным для выполнения на процес¬сорах, имеющих разные архитектуры. Помимо соблюдения приве¬денных выше условий необходимо организовать эмуляцию двоич¬ного кода.
Пусть, например, требуется выполнить DOS-программу для IBM PC-совместимого компьютера на компьютере Macintosh. Ком¬пьютер Macintosh построен на основе процессора Motorola 680×0, а компьютер IBM PC — на основе процессора Intel 80×86. Процессор Motorola имеет архитектуру (систему команд, состав регистров и т. п.), отличную от архитектуры процессора Intel, поэтому ему непо¬нятен двоичный код DOS-программы, содержащей инструкции этого процессора. Для того чтобы компьютер Macintosh смог ин¬терпретировать машинные инструкции, которые ему изначально непонятны, на нем должно быть установлено специальное про¬граммное обеспечение — эмулятор.
Эмулятор должен последовательно выбирать каждую дво¬ичную инструкцию процессора Intel, программным способом де¬шифрировать ее, чтобы определить, какие действия она задает, а затем выполнять эквивалентную подпрограмму, написанную в ин¬струкциях процессора Motorola. Так как к тому же у процессора Motorola нет в точности таких же регистров, флагов и внутреннего арифметико-логического устройства, как в Intel, он должен также имитировать (эмулировать) все эти элементы с использованием своих регистров или памяти. Состояние эмулируемых регистров и флагов после выполнения каждой команды должно быть абсолютно таким же, как и в реальном процессоре Intel.
Это простая, но очень медленная работа, так как одна ко¬манда процессора Intel исполняется значительно быстрее, чем эму¬лирующая его последовательность команд процессора Motorola.
Трансляция библиотек
Выходом в таких случаях является использование так назы¬ваемых прикладных программных сред. Одной из составляющих, формирующих прикладную программную среду, является набор функций интерфейса прикладного программирования API, которые операционная система предоставляет своим приложениям. Для со¬кращения времени на выполнение чужих программ прикладные среды имитируют обращения к библиотечным функциям.
Эффективность этого подхода связана с тем, что большин¬ство сегодняшних программ работают под управлением GUI (гра¬фических интерфейсов пользователя) типа Windows, Mac или UNIX Motif, при этом приложения тратят большую часть времени, произ¬водя некоторые хорошо предсказуемые действия. Они непрерывно выполняют вызовы библиотек GUI для манипулирования окнами и для других связанных с GUI действий. Сегодня в типичных про¬граммах 60-80 % времени тратится на выполнение функций GUI и других библиотечных вызовов ОС. Именно это свойство приложе¬ний позволяет прикладным средам компенсировать большие за¬траты времени, потраченные на покомандное эмулирование про¬граммы. Тщательно спроектированная программная прикладная среда имеет в своем составе библиотеки, имитирующие внутренние библиотеки GUI, но написанные на «родном» коде. Таким образом достигается существенное ускорение выполнения программ с API другой операционной системы. Иногда такой подход называют трансляцией для того, чтобы отличать его от более медленного процесса эмулирования кода по одной команде за раз.
Например, для Windows-программы, работающей на Macintosh, при интерпретации команд процессора Intel 80×86 про¬изводительность может быть очень низкой. Но когда производится вызов функции GUI открытия окна, модуль ОС, реализующий при¬кладную среду Windows, может перехватить этот вызов и перена¬править его на перекомпилированную для процессора Motorola 680×0 подпрограмму открытия окна. В результате на таких участ¬ках кода скорость работы программы может достичь (а возможно, и превзойти) скорость работы на своем «родном» процессоре.
Чтобы программа, написанная для одной ОС, могла быть выполнена в рамках другой ОС, недостаточно лишь обеспечить совместимость API. Концепции, положенные в основу разных ОС, могут входить в противоречие друг с другом. Например, в одной операционной системе приложению может быть разрешено непо¬средственно управлять устройствами ввода-вывода, в другой — эти действия являются прерогативой ОС. Каждая операционная си¬стема имеет свои собственные механизмы защиты ресурсов, свои алгоритмы обработки ошибок и исключительных ситуаций, особую структуру процесса и схему управления памятью, свою семантику доступа к файлам и графический пользовательский интерфейс. Для обеспечения совместимости необходимо организовать бескон¬фликтное сосуществование в рамках одной ОС нескольких спосо¬бов управления ресурсами компьютера.
Способы реализации прикладных программных сред
Создание полноценной прикладной среды, полностью сов¬местимой со средой другой операционной системы, является доста¬точно сложной задачей, тесно связанной со структурой операцион¬ной системы. Существуют различные варианты построения множе¬ственных прикладных сред, отличающиеся как особенностями ар¬хитектурных решений, так и функциональными возможностями, обеспечивающими различную степень переносимости приложений.
Во многих версиях ОС UNIX транслятор прикладных сред реализуется в виде обычного приложения. В операционных систе¬мах, построенных с использованием микроядерной концепции, та¬ких как, например, Windows NT или Workplace OS, прикладные среды выполняются в виде серверов пользовательского режима. А в OS/2 с ее более простой архитектурой средства организации при¬кладных сред встроены глубоко в операционную систему.
Один из наиболее очевидных вариантов реализации множе¬ственных прикладных сред основывается на стандартной много¬уровневой структуре ОС. На рис. 29 операционная система OS1 поддерживает кроме своих «родных» приложений приложения операционных систем OS2 и OS3. Для этого в ее составе имеются специальные приложения — прикладные программные среды, — которые транс¬лируют интерфейсы «чужих» операционных систем API OS2 и API OS3 в интерфейс своей «родной» операционной си¬стемы — API OS1. Так, например, в случае, если бы в качестве OS2 выступала операционная система UNIX, а в качестве OS1 — OS/2, для выполнения системного вызова создания процесса forkO в UNIX-приложении программная среда должна обратиться к ядру операционной системы OS/2 с системным вызовом DosExecPgm().

К сожалению, поведение почти всех функций, составляю¬щих API одной ОС, как правило, существенно отличается от пове¬дения соответствующих функций другой ОС. Например, чтобы функция создания процесса в OS/2 DosExecPgmO полностью соот¬ветствовала функции создания процесса forkO в UNIX-подобных системах, ее нужно было бы изменить, чтобы она поддерживала возможность копирования адресного пространства родительского процесса в пространство процесса-потомка. (При нормальном же поведении этой функции память процесса-потомка инициализиру¬ется на основе данных нового исполняемого файла.)
В другом варианте реализации множественных прикладных сред операционная система имеет несколько равноправных при¬кладных программных интерфейсов. В приведенном на рис. 30 при¬мере операционная система поддерживает приложения, написанные для OS1, OS2 и OS3. Для этого непосредственно в пространстве ядра системы размещены прикладные программные интерфейсы всех этих ОС: API OS1, API OS2 и API OS3.
В этом варианте функции уровня API обращаются к функ¬циям нижележащего уровня ОС, которые должны поддерживать все три в общем случае несовместимые прикладные среды. В раз¬ных ОС по-разному осуществляется управление системным време¬нем, используется разный формат времени дня, на основании соб¬ственных алгоритмов разделяется процессорное время и т. д. Функ¬ции каждого API реализуются ядром с учетом специфики соответ¬ствующей ОС, даже если они имеют аналогичное назначение. Например, как уже было сказано, функция создания процесса рабо¬тает по-разному для приложения UNIX и приложения OS/2. Анало¬гично при завершении процесса ядру также необходимо опреде¬лять, к какой ОС относится данный процесс. Если этот процесс был создан по запросу UNIX-приложения, то в ходе его завершения ядро должно послать родительскому процессу сигнал, как это дела¬ется в ОС UNIX. А по завершении процесса OS/2, созданного с па-раметром EXEC_SYNC, ядро должно отметить, что идентификатор процесса не может быть повторно использован другим процессом OS/2. Для того чтобы ядро могло выбрать нужный вариант реализации системного вызова, каждый процесс должен передавать в ядро набор идентифицирующих характеристик.

Еще один способ построения множественных прикладных сред основан на микроядерном подходе. При этом очень важно от¬делить базовые, общие для всех прикладных сред, механизмы опе¬рационной системы от специфических для каждой из прикладных сред высокоуровневых функций, решающих стратегические задачи.
В соответствии с микроядерной архитектурой все функции ОС реализуются микроядром и серверами пользовательского ре¬жима. Важно, что каждая прикладная среда оформляется в виде от¬дельного сервера пользовательского режима и не включает базовых механизмов (рис. 31). Приложения, используя API, обращаются с системными вызовами к соответствующей прикладной среде через микроядро. Прикладная среда обрабатывает запрос, выполняет его (возможно, обращаясь для этого за помощью к базовым функциям микроядра) и отсылает приложению результат. В ходе выполнения запроса прикладной среде приходится, в свою очередь, обращаться к базовым механизмам ОС, реализуемым микроядром и другими серверами ОС.
Такому подходу к конструированию множественных при¬кладных сред присущи все достоинства и недостатки микроядерной архитектуры, в частности:
• очень просто можно добавлять и исключать прикладные среды, что является следствием хорошей расширяемости микроядерных ОС;
• надежность и стабильность выражаются в том, что при от¬казе одной из прикладных сред все остальные сохраняют работоспособность;
• низкая производительность микроядерных ОС сказывается на скорости работы прикладных сред, а значит, и на скоро¬сти выполнения приложений.

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

Оставить комментарий