В этом параграфе рассмотрим шесть различных использу¬ющихся (или использовавшихся ранее) структур, чтобы получить некоторое представление о спектре их возможностей. Они ни в коем случае не представляют собой исчерпывающую картину, но дают представление о некоторых конструкторских решениях, опро¬бованных на практике. Эти шесть конструкторских решений пред¬ставлены монолитными системами, многоуровневыми системами, микроядрами, клиентсерверными системами, виртуальными маши¬нами и экзоядрами.
6.1. Монолитные системы
Несомненно, такая организация операционной системы яв¬ляется самой распространенной. Здесь вся операционная система работает как единая программа в режиме ядра. Операционная си¬стема написана в виде набора процедур, связанных вместе в одну большую исполняемую программу. При использовании этой техно¬логии каждая процедура может свободно вызвать любую другую процедуру, если та выполняет какое-нибудь полезное действие, в котором нуждается первая процедура. Возможность вызвать любую нужную процедуру приводит к весьма высокой эффективности ра¬боты системы, но наличие нескольких тысяч процедур, которые могут вызывать друг друга сколь угодно часто, нередко делает ее громоздкой и непонятной. Кроме того, отказ в любой из этих про¬цедур приведет к аварии всей операционной системы.
Для построения исполняемого файла монолитной системы необходимо сначала скомпилировать все отдельные процедуры (или файлы, содержащие процедуры), а затем связать их вместе, воспользовавшись системным компоновщиком (модуль системы программирования или самостоятельная программа, которая соби¬рает результирующую программу из объектных модулей и стан¬дартных библиотечных модулей.).
Здесь, по существу полностью отсутствует сокрытие дета¬лей реализации — каждая процедура видна любой другой проце¬дуре (в отличие от структуры, содержащей модули или пакеты, в которых основная часть информации скрыта внутри модулей и за пределами модуля его процедуры можно вызвать только через спе¬циально определяемые точки входа).
Тем не менее даже такие монолитные системы могут иметь некоторую структуру. Службы (системные вызовы), предоставляе¬мые операционной системой, запрашиваются путем помещения па¬раметров в четко определенное место (например, в стек), а затем выполняется инструкция trap. Эта инструкция переключает машину из пользовательского режима в режим ядра и передает управление операционной системе (шаг 6 на рис. 20). Затем операционная си¬стема извлекает параметры и определяет, какой системный вызов должен быть выполнен. После этого она перемещается по индексу в таблице, которая в строке k содержит указатель на процедуру, выполняющую системный вызов k (шаг 7 на рис. 20).

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

В дополнение к основной операционной системе, загружаемой во время запуска компьютера, многие операционные системы поддерживают загружаемые расширения, в числе которых драйверы устройств ввода-вывода и файловые системы. Эти компоненты загружаются по мере надобности. В UNIX они называются библиотеками общего пользования. В Windows они называются DLL-библиотеками (Dynamic-Link Libraries — динамически подключаемые библиотеки). Они находятся в файлах с расширениями имен .dll, и в каталоге C:\Windows\system32 на системе Windows их более 1000.
6.2. Многоуровневые системы
Обобщением подхода, показанного на рис. 21, является организация операционной системы в виде иерархии уровней, каждый из которых является надстройкой над нижележащим уровнем. Первой системой, построенной таким образом, была система THE, созданная в Technische Hogeschool Eindhoven в Голландии Э. Дейкстрой (E. W. Dijkstra и его студентами в 1968 году. Система THE была простой пакетной системой для голландского компьютера Electrologica X8, имевшего память 32 K 27-разрядных слов.
Как показано в табл. 2, у системы было шесть уровней. Уровень 0 занимался распределением ресурса процессора (процессорного времени), переключением между процессами при возникновении прерываний или истечении времени таймера. Над уровнем 0 система состояла из последовательных процессов, каждый из которых мог быть запрограммирован без учета того, что несколько процессов были запущены на одном процессоре. Иными словами, уровень 0 обеспечивал основу многозадачности центрального процессора.
Таблица 2. Структура операционной системы THE
| Уровень | Функция |
| 5 | Оператор |
| 4 | Программы пользователя |
| 3 | Управление вводом-выводом |
| 2 | Связь оператора с процессом |
| 1 | Управление основной памятью и магнитным барабаном |
| 0 | Распределение ресурсов процессора и обеспечение многозадачного режима |
Уровень 1 управлял памятью. Он выделял процессам пространство в основной памяти и на магнитном барабане емкостью 512 К слов, который использовался для хранения частей процесса (страниц), не умещавшихся в оперативной памяти. На уровнях выше первого процессы не должны были беспокоиться о том, где именно они находятся, в памяти или на барабане. Программное обеспечение уровня 1 обеспечивает помещение страниц в память в то время, когда они необходимы, и удаление их из памяти, когда они не нужны.
Уровень 2 управлял связью каждого процесса с консолью оператора (то есть с пользователем). Над этим уровнем каждый процесс фактически имел собственную консоль оператора.
Уровень 3 управлял устройствами ввода-вывода и буферизацией информационных потоков в обоих направлениях. Над третьим уровнем каждый процесс мог работать с абстрактными устройствами ввода-вывода, имеющими определенные свойства. На уровне
На уровне 4 работали пользовательские программы, которым не надо было заботиться о процессах, памяти, консоли или управлении вводом-выводом. Процесс системного оператора размещался на уровне 5.
Дальнейшее обобщение многоуровневой концепции было сделано в системе MULTICS.
Вместо уровней для описания MULTICS использовались серии концентрических колец, где внутренние кольца обладали более высокими привилегиями по отношению к внешним (что, собственно, не меняло сути многоуровневой системы). Когда процедуре из внешнего кольца требовалось вызвать процедуру внутреннего кольца, ей нужно было создать эквивалент системного вызова, то есть выполнить инструкцию TRAP параметры которой тщательно проверялись на допустимость перед тем, как разрешить продолжение вызова. Хотя вся операционная система в MULTICS являлась частью адресного пространства каждого пользовательского процесса, аппаратура позволяла определять отдельные процедуры (а фактически — сегменты памяти) как защищенные от чтения, записи или выполнения.
Следует отметить, что система уровней в конструкции THE играла лишь вспомогательную роль, поскольку все части системы в конечном счете компоновались в единую исполняемую программу, а в MULTICS кольцеобразный механизм существовал главным образом в процессе выполнения и реализовывался за счет аппаратного обеспечения.
Преимущества кольцеобразного механизма проявлялись в том, что он мог быть легко расширен и на структуру пользовательских подсистем. Например, профессор может написать программу для тестирования и оценки студенческих программ и запустить ее в кольце n, а студенческие программы будут выполняться в кольце n + 1, так что студенты не смогут изменить свои оценки.
6.3. Микроядра
При использовании многоуровневого подхода разработчикам необходимо выбрать, где провести границу между режимами ядра и пользователя. Традиционно все уровни входили в ядро, но это было не обязательно. Существуют очень весомые аргументы в пользу того, чтобы в режиме ядра выполнялось как можно меньше процессов, поскольку ошибки в ядре могут вызвать немедленный сбой системы. Для сравнения: пользовательские процессы могут быть настроены на обладание меньшими полномочиями, чтобы их ошибки не носили фатального характера.
Различные исследователи неоднократно определяли количество ошибок на 1000 строк кода (например, Basilli and Perricone, 1984; Ostrand and Weyuker, 2002). Плотность ошибок зависит от размера модуля, его возраста и других факторов, но приблизительная цифра для солидных промышленных систем — 10 ошибок на 1000 строк кода.
Следовательно, монолитная операционная система, состоящая из 5 000 000 строк кода, скорее всего, содержит от 10 000 до 50000 ошибок ядра. Разумеется, не все они имеют фатальный характер, некоторые ошибки могут представлять собой просто выдачу неправильного сообщения об ошибке в той ситуации, которая складывается крайне редко. Тем не менее операционные системы содержат столько ошибок, что производители компьютеров снабдили свою продукцию кнопкой перезапуска (которая зачастую находится на передней панели), чего не делают производители телевизоров, стереосистем и автомобилей, несмотря на большой объем программного обеспечения, имеющийся в этих устройствах.
Замысел, положенный в основу конструкции микроядра, направлен на достижение высокой надежности за счет разбиения операционной системы на небольшие, вполне определенные модули. Только один из них — микроядро — запускается в режиме ядра, а все остальные запускаются в виде относительно слабо наделенных полномочиями обычных пользовательских процессов. В частности, если запустить каждый драйвер устройства и файловую систему как отдельные пользовательские процессы, то ошибка в одном из них может вызвать отказ соответствующего компонента, но не сможет вызвать сбой всей системы. Таким образом, ошибка в драйвере звукового устройства приведет к искажению или пропаданию звука, но не вызовет зависания компьютера. В отличие от этого в монолитной системе, где все драйверы находятся в ядре, некорректный драйвер звукового устройства может запросто сослаться на неверный адрес памяти и привести систему к немедленной вынужденной остановке.
За десятилетия было разработано и получило распространение множество различных микроядер (Haertig et al., 1997; Heiser et al., 2006; Herder et al., 2006; Hildebrand, 1992; Kirsch et al., 2005; Liedtke, 1993, 1995, 1996; Pike et al., 1992; Zuberi et al., 1999). За исключением OS X, которая основана на микроядре Mach (Accetta et al., 1986), широко распространенные операционные системы настольных компьютеров микроядра не используют. Но микроядра доминируют в приложениях, работающих в реальном масштабе времени в промышленных устройствах, авионике и военной технике, которые выполняют особо важные задачи и должны отвечать очень высоким требованиям надежности. Часть общеизвестных микроядер представляют Integrity, K42, L4, PikeOS, QNX, Symbian и MINIX 3. Кратко рассмотрим микроядро MINIX 3, в котором максимально использована идея модульности и основная часть операционной системы разбита на ряд независимых процессов, работающих в режиме пользователя. MINIX 3 — это POSIX-совместимая система с открытым исходным кодом, находящаяся в свободном доступе по адресу www.minix3.org (Giuffrida et al., 2012; Giuffrida et al., 2013; Herder etal., 2006; Herder et al., 2009; Hruby et al., 2013).
Микроядро MINIX 3 занимает всего лишь около 12 000 строк кода на языке C и 1400 строк кода на ассемблере, который использован для самых низкоуровневых функций, в частности для перехвата прерываний и переключения процессов. Код на языке С занимается управлением процессами и их распределением, управляет межпроцессным взаимодействием (путем обмена сообщениями между процессами) и предлагает набор примерно из 40 вызовов ядра, позволяя работать остальной части операционной системы. Эти вызовы выполняют функции подключения обработчиков к прерываниям, перемещения данных между адресными пространствами и установки новых схем распределения памяти для только что созданных процессов. Структура процесса MINIX 3 показана на рис. 22, где обработчики вызовов ядра обозначены Sys. В ядре также размещен драйвер часов, потому что планировщик работает в тесном взаимодействии с ними. Все остальные драйверы устройств работают как отдельные пользовательские процессы.

За пределами ядра структура системы представляет собой три уровня процессов, которые работают в режиме пользователя. Самый нижний уровень содержит драйверы устройств. Поскольку они работают в пользовательском режиме, у них нет физического доступа к пространству портов ввода-вывода и они не могут вызы¬вать команды ввода-вывода напрямую. Вместо этого, чтобы запро¬граммировать устройство ввода-вывода, драйвер создает структуру, сообщающую, какие значения в какие порты ввода-вывода следует записать. Затем драйвер осуществляет вызов ядра, сообщая ядру, что нужно произвести запись. При этом ядро может осуществить проверку, использует ли драйвер то устройство ввода-вывода, с ко¬торым он имеет право работать. Следовательно (в отличие от моно¬литной конструкции), дефектный драйвер звукового устройства не может случайно осуществить запись на диск.
Над драйверами расположен уровень, содержащий службы, которые осуществляют основной объем работы операционной си¬стемы. Все они работают в режиме пользователя. Одна или более файловых служб управляют файловой системой (или системами), диспетчер процессов создает и уничтожает процессы, управляет ими и т. д. Пользовательские программы получают доступ к услу¬гам операционной системы путем отправки коротких сообщений этим службам, которые запрашивают системные вызовы POSIX. Например, процесс, нуждающийся в выполнении вызова read, от¬правляет сообщение одной из файловых служб, предписывая ей, что нужно прочитать.
Особый интерес представляет служба перевоплощения (reincarnation server), выполняющая проверку функционирования других служб и драйверов. В случае обнаружения отказа одного из компонентов он автоматически заменяется без какого-либо вмеша¬тельства со стороны пользователя. Таким образом, система само¬стоятельно исправляет отказы и может достичь высокой надежно¬сти.
Система накладывает на полномочия каждого процесса большое количество ограничений. Уже упоминалось, что драйверы могут работать только с разрешенными портами ввода-вывода. До¬ступ к вызовам ядра также контролируется для каждого процесса через возможность посылать сообщения другим процессам. Про¬цессы также могут предоставить другим процессам ограниченные права доступа через ядро к своему адресному пространству. Например, файловая система может выдать драйверу диска разре¬шение, позволяющее ядру помещать только что считанный с диска блок в память по указанному адресу внутри адресного пространства файловой системы. Совокупность этих ограничений приводит к тому, что каждый драйвер и каждая служба имеют только те пол¬номочия, которые нужны для их работы, и не более того. Тем са¬мым существенно сокращается вред, который может быть нанесен дефектным компонентом.
Идея, имеющая некоторое отношение к использованию ми-нимального ядра, заключается в том, чтобы помещать в ядро ис-полнительный механизм, а не политику. Чтобы пояснить эту мысль, рассмотрим планирование выполнения процессов. Относительно простой алгоритм планирования заключается в назначении каж¬дому процессу приоритета с последующим запуском ядром гото¬вого к выполнению процесса с наиболее высоким приоритетом. Механизм, который находится в ядре, предназначен для поиска и запуска процесса с наибольшим приоритетом. Политика, заключа¬ющаяся в назначении процессам приоритетов, должна быть реали¬зована процессами, работающими в пользовательском режиме. Та¬ким образом, политика и механизм могут быть разобщены, а ядро — уменьшено в размерах.
6.4. Клиент-серверная модель
Небольшая вариация идеи микроядер выражается в обособ¬лении двух классов процессов: серверов, каждый из которых предоставляет какую-нибудь службу, и клиентов, которые пользу¬ются этими службами. Эта модель известна как клиент-серверная. Довольно часто самый нижний уровень представлен микроядром, но это не обязательно. Суть заключается в наличии клиентских процессов и серверных процессов.
Связь между клиентами и серверами часто организуется с помощью передачи сообщений. Чтобы воспользоваться службой, клиентский процесс составляет сообщение, в котором говорится, что именно ему нужно, и отправляет его соответствующей службе. Затем служба выполняет определенную работу и отправляет об¬ратно ответ. Если клиент и сервер запущены на одной и той же ма¬шине, то можно провести определенную оптимизацию, но концеп¬туально здесь речь идет о передаче сообщений. Очевидным разви¬тием этой идеи будет запуск клиентов и серверов на разных ком¬пьютерах, соединенных локальной или глобальной сетью (рис. 23). Поскольку клиенты связываются с серверами путем отправки со-общений, им не обязательно знать, будут ли эти сообщения обрабо¬таны локально, на их собственных машинах, или же они будут от¬правлены по сети на серверы, расположенные на удаленных маши¬нах. Что касается интересов клиента, следует отметить, что в обоих случаях происходит одно и то же: отправляются запросы и возвра¬щаются ответы. Таким образом, клиент-серверная модель является абстракцией, которая может быть использована как для отдельно взятой машины, так и для машин, объединенных в сеть.

Становится все больше и больше систем, привлекающих пользователей, сидящих за домашними компьютерами, в качестве клиентов, а большие машины, работающие где-нибудь в другом месте, — в качестве серверов. Фактически по этой схеме работает большая часть Интернета. Персональные компьютеры отправляют запросы на получение веб-страницы на сервер, и эта веб-страница им возвращается. Это типичная картина использования клиент-сер¬верной модели при работе в сети.
6.5. Виртуальные машины
Первые выпуски OS/360 были системами исключительно пакетной обработки. Но многие пользователи машин IBM/360 хо¬тели получить возможность интерактивной работы с использова¬нием терминала, поэтому различные группы разработчиков как в самой корпорации IBM, так и за ее пределами решили написать для этой машины системы с разделением времени. Позже была выпу¬щена официальная система разделения времени — TSS/360, и когда она наконец-то дошла до потребителей, то была настолько гро¬моздкой и медлительной, что под нее было переоборудовано всего лишь несколько вычислительных центров. В конечном счете от этого проекта отказались, после того как на него уже было потра¬чено 50 млн долларов (Graham, 1970).
VM/370
Группа из научного центра IBM Scientific Center в Кембри¬дже (Массачусетс) разработала совершенно другую систему, кото¬рую IBM в конечном итоге приняла как законченный продукт. Эта система, первоначально называвшаяся CP/CMS, а позже переиме¬нованная в VM/370 (Seawright and MacKinnon, 1979), была основана на следующем проницательном наблюдении: система с разделе¬нием времени обеспечивает, во-первых, многозадачность, а во-вто¬рых, расширенную машину с более удобным интерфейсом, чем у простого оборудования. Сущность VM/370 заключается в полном разделении этих двух функций.
Основа системы, известная как монитор виртуальных ма¬шин, запускается непосредственно на обычном оборудовании и обеспечивает многозадачность, предоставляя верхнему уровню не одну, а несколько виртуальных машин (рис. 24). Но, в отличие от всех других операционных систем, эти виртуальные машины не являются машинами с расширенной архитектурой. Они не поддер¬живают файлы и другие полезные свойства. Вместо этого они яв¬ляются точной копией исходной аппаратуры, включающей режим ядра и пользователя, устройства ввода-вывода, прерывания и все остальное, что есть у настоящей машины.

Поскольку каждая виртуальная машина идентична настоящему оборудованию, на каждой из них способна работать любая операционная система, которая может быть запущена непосредственно на самом оборудовании. На разных виртуальных машинах могут быть запущены разные операционные системы, как это часто и происходит на самом деле. Изначально на системах VM/370 пользователи запускали в своих виртуальных машинах OS/360 или одну из других больших операционных систем пакетной обработки или обработки транзакций, в то время как другие запускали однопользовательскую интерактивную систему CMS (Conversational Monitor System — система диалоговой обработки ) для пользователей системы разделения времени.
Когда программа под управлением операционной системы CMS выполняет системный вызов, он перехватывается в системное прерывание операционной системы на своей собственной виртуальной машине, а не на VM/370, как это было бы при ее запуске на реальной, а не на виртуальной машине. Затем CMS выдает обычные команды ввода-вывода для чтения своего виртуального диска или другие команды, которые могут ей понадобиться для выполнения этого вызова. Эти команды ввода-вывода перехватываются VM/370, которая выполняет их в рамках моделирования реального оборудования. При полном разделении функций многозадачности и предоставления машины с расширенной архитектурой каждая из составляющих может быть намного проще, гибче и удобнее для обслуживания.
В своем современном перерождении z/VM обычно используется для запуска нескольких полноценных операционных систем, а не упрощенных, однопользовательских систем вроде CMS. Например, на машинах zSeries можно запустить одну или несколько виртуальных машин Linux, а наряду с ними — обычные операционные системы IBM.
Повторное открытие виртуальных машин
Хотя в IBM виртуальные машины используются уже четыре десятилетия и ряд других компаний, включая Oracle и Hewlett-Packard, недавно добавили поддержку виртуальных машин к своим высокопроизводительным промышленным серверам, тем не менее, по большому счету, идея виртуализации в мире персональных ком¬пьютеров до последнего времени практически игнорировалась. Но сейчас сочетание новых потребностей, нового программного обес¬печения и новых технологий придало этой теме особую актуаль¬ность.
Сначала о потребностях. Многие компании традиционно запускали свои почтовые серверы, веб-серверы, FTP-серверы и все остальные серверы на отдельных компьютерах, иногда имеющих различные операционные системы. Виртуализация рассматривается ими как способ запуска всех этих серверов на одной и той же ма¬шине с возможностью избежать при этом отказа всех серверов при отказе одного из них.
Виртуализация популярна также в мире веб-хостинга. Без нее клиенты вынуждены выбирать между общим хостингом (За ним закрепилось название «виртуальный хостинг».) (который дает им только учетную запись на веб-сервере, но не позволяет управ¬лять его программным обеспечением) и выделенным хостингом (который предоставляет им их собственную, очень гибкую, но не оправдывающую затрат машину при небольших или средних по объему веб-сайтах). Когда компания, предоставляющая услуги веб-хостинга (хостинг-провайдер), сдает в аренду виртуальные ма¬шины, на одной физической машине может быть запущено множе¬ство виртуальных машин, каждая из которых превращается в пол¬ноценную машину. Клиенты, арендовавшие виртуальную машину, могут запускать на ней какие угодно операционную систему и про¬граммное обеспечение, но за часть стоимости выделенного сервера (поскольку та же самая физическая машина одновременно поддер-живает множество виртуальных машин).
Другой вариант использования виртуализации предназначен для конечных пользователей, которым необходима возможность одновременного запуска двух или более операционных систем, например Windows и Linux, поскольку некоторые из любимых ими приложений работают под управлением только одной из этих опе¬рационных систем. Такая ситуация показана на рис. 25, а, при этом термин «монитор виртуальной машины» заменен на «гипервизор первого типа» (type 1 hypervisor), который широко используется в наши дни из-за краткости при наборе по сравнению с первым вари¬антом. Но для многих авторов они являются взаимозаменяемыми.

Привлекательность виртуальных машин сомнениям не под¬вергалась, проблема заключалась в их реализации. Чтобы запустить на компьютере программное обеспечение виртуальных машин, его центральный процессор должен быть готов к работе в этом режиме (Popek and Goldberg, 1974). Проблема заключается в следующем. Когда операционная система, запущенная на виртуальной машине (в режиме пользователя), выполняет привилегированные инструк¬ции, например изменение слова состояния программы — PSW или операцию ввода-вывода, необходимо, чтобы оборудование осуще¬ствило перехват данных инструкций и вызов монитора виртуаль¬ных машин, который выполнит их программную эмуляцию. На не¬которых центральных процессорах, особенно на Pentium, его пред¬шественниках и их клонах, попытки выполнения привилегирован-ных инструкций в режиме пользователя просто игнорируются. Эта особенность исключает создание виртуальных машин на таком оборудовании, чем объясняется недостаточный интерес к ним в мире x86. Конечно, существовали интерпретаторы для Pentium, та¬кие как Bochs, которые запускались на этом процессоре, но при по¬тере производительности обычно в один-два порядка они не подхо¬дили для серьезной работы.
В 1990-х годах и в первые годы нового тысячелетия был ре¬ализован ряд научно-исследовательских проектов, в частности Disco в Стэнфорде (Bugnion et al., 1997) и Xen в Кембридже (Barham et al., 2003). Эти исследования привели к появлению не¬скольких коммерческих продуктов (например, VMware Workstation и Xen), и интерес к виртуальным машинам снова вырос. Сегодня в число популярных гипервизоров кроме VMware иXen входят KVM (для ядра Linux), VirtualBox (от Oracle) и Hyper-V (от Microsoft).
Некоторые из этих ранних исследовательских проектов улучшили производительность по сравнению с интерпретаторами типа Bochs путем трансляции блоков кода на лету, сохранения их во внутреннем кэше и повторного использования результата транс¬ляции в случае их нового исполнения. Это существенно повысило производительность и привело к созданию того, что сейчас называ¬ется моделями машин (machine simulators) (рис. 25, б). Но хотя эта технология, известная как двоичная трансляция (binary translation), помогла улучшить ситуацию, получившиеся системы, несмотря на то что они неплохо подходили для публикаций на академических конференциях, по-прежнему не отличались быстротой для исполь¬зования в коммерческих средах, где производительность имеет весьма большое значение.
Следующим шагом в улучшении производительности стало добавление модуля ядра (рис. 25, в) для выполнения ряда трудоем¬ких задач. Сложившаяся сейчас практика показывает, что все ком¬мерчески доступные гипервизоры, такие как VMware__Workstation, используют эту гибридную стратегию (а также имеют множество других усовершенствований). Все их называют гипервизорами типа 2, хотя лучше бы было назвать их гипервизорами типа 1.7, чтобы отразить тот факт, что они не являются в полном смысле програм¬мами пользовательского режима.
На практике действительным различием между гипервизо¬рами типа 1 и типа 2 является то, что в типе 2 для создания процес¬сов, сохранения файлов и т. д. используется основная операционная система (host operating system) и ее файловая система. Гипервизор типа 1 не имеет основной поддержки и должен выполнять все эти функции самостоятельно.
После запуска гипервизор типа 2 считывает установочный компакт-диск (или файл образа компакт-диска) для выбора госте¬вой операционной системы (guest operation system) и установки гос¬тевой ОС на виртуальный диск, который является просто большим файлом в файловой системе основной операционной системы. Ги¬первизор типа 1 этого делать не может по причине отсутствия ос¬новной операционной системы, в которой можно было бы хранить файлы.
Во время своей загрузки гостевая операционная система де¬лает все то же самое, что и на настоящем оборудовании, как обычно запуская некоторые фоновые процессы, а затем графиче¬ский пользовательский интерфейс. С точки зрения пользователя, гостевая операционная система ведет себя точно так же, как при запуске непосредственно на оборудовании, хотя в данном случае ситуация совсем иная.
Другим подходом к обработке управляющих инструкций является модификация операционной системы с целью их удале¬ния. Этот подход не является настоящей виртуализацией, он отно¬сится к паравиртуализации..
Виртуальная машина Java
Виртуальные машины используются, правда, несколько иным образом и в другой области — для запуска программ на языке Java. Когда компания Sun Microsystems изобрела язык программи¬рования Java, она также изобрела и виртуальную машину (то есть архитектуру компьютера), названную JVM (Java Virtual Machine — виртуальная машина Java). Компилятор Java создает код для JVM, который затем обычно выполняется программным интерпретато¬ром JVM. Преимущество такого подхода состоит в том, что код для JVM может доставляться через Интернет на любой компьютер, имеющий JVM-интерпретатор, и запускаться на этом компьютере. Если бы компилятор создавал двоичные программы, например для SPARC или x86, их нельзя было бы так же легко куда угодно до¬ставлять и где угодно запускать. (Разумеется, Sun могла бы создать компилятор, производящий двоичные файлы для SPARC, а затем распространить SPARC-интерпретатор, но у JVM намного более простая для интерпретации архитектура.) Другим преимуществом использования JVM является то, что при правильной реализации интерпретатора, что не является такой уж простой задачей, полу¬ченные JVM-программы могут быть проверены с точки зрения без-опасности, а затем выполнены в защищенной среде, не имея воз¬можности похитить данные или нанести любой другой вред.
6.6. Экзоядра
Вместо клонирования настоящей машины, как это делается в виртуальных машинах, существует иная стратегия, которая за¬ключается в их разделении, иными словами, в предоставлении каж¬дому пользователю подмножества ресурсов. При этом одна вирту¬альная машина может получить дисковые блоки от 0 до 1023, дру¬гая — блоки от 1024 до 2047 и т. д.
Самый нижний уровень, работающий в режиме ядра, — это программа под названием экзоядро (Engler et al., 1995). Ее задача состоит в распределении ресурсов между виртуальными машинами и отслеживании попыток их использования, чтобы ни одна из ма¬шин не пыталась использовать чужие ресурсы. Каждая виртуальная машина может запускать собственную операционную систему, как на VM/370 и на Pentium в режиме виртуальных машин 8086, с тем отличием, что каждая машина ограничена использованием тех ре¬сурсов, которые она запросила и которые были ей предоставлены.
Преимущество схемы экзоядра заключается в том, что она исключает уровень отображения. При других методах работы каж¬дая виртуальная машина считает, что она имеет собственный диск с нумерацией блоков от 0 до некоторого максимума. Поэтому мони¬тор виртуальных машин должен вести таблицы преобразования адресов на диске (и всех других ресурсов). При использовании эк¬зоядра необходимость в таком переназначении отпадает. Экзоядру нужно лишь отслеживать, какой виртуальной машине какие ре¬сурсы были переданы. Такой подход имеет еще одно преимущество — он отделяет многозадачность (в экзоядре) от пользовательской операционной системы (в пространстве пользователя) с меньшими затратами, так как для этого ему необходимо всего лишь не допус¬кать вмешательства одной виртуальной машины в работу другой.

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