Добавлен: 29.10.2018
Просмотров: 48167
Скачиваний: 190
1.7. Структура операционной системы
91
к внешним (что, собственно, не меняло сути многоуровневой системы). Когда процеду-
ре из внешнего кольца требовалось вызвать процедуру внутреннего кольца, ей нужно
было создать эквивалент системного вызова, то есть выполнить инструкцию TRAP,
параметры которой тщательно проверялись на допустимость перед тем, как разрешить
продолжение вызова. Хотя вся операционная система в MULTICS являлась частью
адресного пространства каждого пользовательского процесса, аппаратура позволяла
определять отдельные процедуры (а фактически — сегменты памяти) как защищенные
от чтения, записи или выполнения.
Следует отметить, что система уровней в конструкции THE играла лишь вспомогатель-
ную роль, поскольку все части системы в конечном счете компоновались в единую ис-
полняемую программу, а в MULTICS кольцеобразный механизм существовал главным
образом в процессе выполнения и реализовывался за счет аппаратного обеспечения.
Преимущества кольцеобразного механизма проявлялись в том, что он мог быть легко
расширен и на структуру пользовательских подсистем. Например, профессор может
написать программу для тестирования и оценки студенческих программ и запустить
ее в кольце n, а студенческие программы будут выполняться в кольце n + 1, так что
студенты не смогут изменить свои оценки.
1.7.3. Микроядра
При использовании многоуровневого подхода разработчикам необходимо выбрать,
где провести границу между режимами ядра и пользователя. Традиционно все уровни
входили в ядро, но это было не обязательно. Существуют очень весомые аргументы
в пользу того, чтобы в режиме ядра выполнялось как можно меньше процессов, по-
скольку ошибки в ядре могут вызвать немедленный сбой системы. Для сравнения:
пользовательские процессы могут быть настроены на обладание меньшими полно-
мочиями, чтобы их ошибки не носили фатального характера.
Различные исследователи неоднократно определяли количество ошибок на 1000 строк
кода (например, Basilli and Perricone, 1984; Ostrand and Weyuker, 2002). Плотность
ошибок зависит от размера модуля, его возраста и других факторов, но приблизи-
тельная цифра для солидных промышленных систем — 10 ошибок на 1000 строк кода.
Следовательно, монолитная операционная система, состоящая из 5 000 000 строк кода,
скорее всего, содержит от 10 000 до 50 000 ошибок ядра. Разумеется, не все они имеют
фатальный характер, некоторые ошибки могут представлять собой просто выдачу не-
правильного сообщения об ошибке в той ситуации, которая складывается крайне редко.
Тем не менее операционные системы содержат столько ошибок, что производители
компьютеров снабдили свою продукцию кнопкой перезапуска (которая зачастую на-
ходится на передней панели), чего не делают производители телевизоров, стереосистем
и автомобилей, несмотря на большой объем программного обеспечения, имеющийся
в этих устройствах.
Замысел, положенный в основу конструкции микроядра, направлен на достижение
высокой надежности за счет разбиения операционной системы на небольшие, вполне
определенные модули. Только один из них — микроядро — запускается в режиме ядра,
а все остальные запускаются в виде относительно слабо наделенных полномочиями
обычных пользовательских процессов. В частности, если запустить каждый драйвер
устройства и файловую систему как отдельные пользовательские процессы, то ошиб-
ка в одном из них может вызвать отказ соответствующего компонента, но не сможет
92
Глава 1. Введение
вызвать сбой всей системы. Таким образом, ошибка в драйвере звукового устройства
приведет к искажению или пропаданию звука, но не вызовет зависания компьютера.
В отличие от этого в монолитной системе, где все драйверы находятся в ядре, некор-
ректный драйвер звукового устройства может запросто сослаться на неверный адрес
памяти и привести систему к немедленной вынужденной остановке.
За десятилетия было разработано и получило распространение множество различных
микроядер (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 et
al., 2006; Herder et al., 2009; Hruby et al., 2013).
Микроядро MINIX 3 занимает всего лишь около 12 000 строк кода на языке C
и 1400 строк кода на ассемблере, который использован для самых низкоуровневых функ-
ций, в частности для перехвата прерываний и переключения процессов. Код на языке С
занимается управлением процессами и их распределением, управляет межпроцессным
взаимодействием (путем обмена сообщениями между процессами) и предлагает набор
примерно из 40 вызовов ядра, позволяя работать остальной части операционной системы.
Эти вызовы выполняют функции подключения обработчиков к прерываниям, перемеще-
ния данных между адресными пространствами и установки новых схем распределения
памяти для только что созданных процессов. Структура процесса MINIX 3 показана на
рис. 1.22, где обработчики вызовов ядра обозначены Sys. В ядре также размещен драйвер
часов, потому что планировщик работает в тесном взаимодействии с ними. Все остальные
драйверы устройств работают как отдельные пользовательские процессы.
За пределами ядра структура системы представляет собой три уровня процессов, ко-
торые работают в режиме пользователя. Самый нижний уровень содержит драйверы
устройств. Поскольку они работают в пользовательском режиме, у них нет физического
доступа к пространству портов ввода-вывода и они не могут вызывать команды ввода-
вывода напрямую. Вместо этого, чтобы запрограммировать устройство ввода-вывода,
драйвер создает структуру, сообщающую, какие значения в какие порты ввода-вывода
следует записать. Затем драйвер осуществляет вызов ядра, сообщая ядру, что нужно
произвести запись. При этом ядро может осуществить проверку, использует ли драй-
вер то устройство ввода-вывода, с которым он имеет право работать. Следовательно
(в отличие от монолитной конструкции), дефектный драйвер звукового устройства не
может случайно осуществить запись на диск.
Над драйверами расположен уровень, содержащий службы, которые осуществляют ос-
новной объем работы операционной системы. Все они работают в режиме пользователя.
Одна или более файловых служб управляют файловой системой (или системами), дис-
петчер процессов создает и уничтожает процессы, управляет ими и т. д. Пользователь-
1.7. Структура операционной системы
93
Рис. 1.22. Упрощенная структура системы MINIX 3
ские программы получают доступ к услугам операционной системы путем отправки
коротких сообщений этим службам, которые запрашивают системные вызовы POSIX.
Например, процесс, нуждающийся в выполнении вызова read, отправляет сообщение
одной из файловых служб, предписывая ей, что нужно прочитать.
Особый интерес представляет служба перевоплощения (reincarnation server), вы-
полняющая проверку функционирования других служб и драйверов. В случае обна-
ружения отказа одного из компонентов он автоматически заменяется без какого-либо
вмешательства со стороны пользователя. Таким образом, система самостоятельно
исправляет отказы и может достичь высокой надежности.
Система накладывает на полномочия каждого процесса большое количество ограниче-
ний. Уже упоминалось, что драйверы могут работать только с разрешенными портами
ввода-вывода. Доступ к вызовам ядра также контролируется для каждого процесса
через возможность посылать сообщения другим процессам. Процессы также могут
предоставить другим процессам ограниченные права доступа через ядро к своему
адресному пространству. Например, файловая система может выдать драйверу диска
разрешение, позволяющее ядру помещать только что считанный с диска блок в память
по указанному адресу внутри адресного пространства файловой системы. Совокуп-
ность этих ограничений приводит к тому, что каждый драйвер и каждая служба имеют
только те полномочия, которые нужны для их работы, и не более того. Тем самым су-
щественно сокращается вред, который может быть нанесен дефектным компонентом.
Идея, имеющая некоторое отношение к использованию минимального ядра, заключа-
ется в том, чтобы помещать в ядро исполнительный механизм, а не политику. Чтобы
пояснить эту мысль, рассмотрим планирование выполнения процессов. Относительно
простой алгоритм планирования заключается в назначении каждому процессу при-
оритета с последующим запуском ядром готового к выполнению процесса с наиболее
высоким приоритетом. Механизм, который находится в ядре, предназначен для поиска
и запуска процесса с наибольшим приоритетом. Политика, заключающаяся в назна-
чении процессам приоритетов, должна быть реализована процессами, работающими
в пользовательском режиме. Таким образом, политика и механизм могут быть разоб-
щены, а ядро — уменьшено в размерах.
94
Глава 1. Введение
1.7.4. Клиент-серверная модель
Небольшая вариация идеи микроядер выражается в обособлении двух классов про-
цессов: серверов, каждый из которых предоставляет какую-нибудь службу, и клиентов,
которые пользуются этими службами. Эта модель известна как клиент-серверная. До-
вольно часто самый нижний уровень представлен микроядром, но это не обязательно.
Суть заключается в наличии клиентских процессов и серверных процессов.
Связь между клиентами и серверами часто организуется с помощью передачи со-
общений. Чтобы воспользоваться службой, клиентский процесс составляет сообще-
ние, в котором говорится, что именно ему нужно, и отправляет его соответствующей
службе. Затем служба выполняет определенную работу и отправляет обратно ответ.
Если клиент и сервер запущены на одной и той же машине, то можно провести опре-
деленную оптимизацию, но концептуально здесь речь идет о передаче сообщений.
Очевидным развитием этой идеи будет запуск клиентов и серверов на разных ком-
пьютерах, соединенных локальной или глобальной сетью (рис. 1.23). Поскольку кли-
енты связываются с серверами путем отправки сообщений, им не обязательно знать,
будут ли эти сообщения обработаны локально, на их собственных машинах, или же
они будут отправлены по сети на серверы, расположенные на удаленных машинах.
Что касается интересов клиента, следует отметить, что в обоих случаях происходит
одно и то же: отправляются запросы и возвращаются ответы. Таким образом, клиент-
серверная модель является абстракцией, которая может быть использована как для
отдельно взятой машины, так и для машин, объединенных в сеть.
Рис. 1.23. Клиент-серверная модель, реализованная с помощью сети
Становится все больше и больше систем, привлекающих пользователей, сидящих за
домашними компьютерами, в качестве клиентов, а большие машины, работающие
где-нибудь в другом месте, — в качестве серверов. Фактически по этой схеме работает
большая часть Интернета. Персональные компьютеры отправляют запросы на полу-
чение веб-страницы на сервер, и эта веб-страница им возвращается. Это типичная
картина использования клиент-серверной модели при работе в сети.
1.7.5. Виртуальные машины
Первые выпуски OS/360 были системами исключительно пакетной обработки. Но
многие пользователи машин IBM/360 хотели получить возможность интерактивной
работы с использованием терминала, поэтому различные группы разработчиков как
в самой корпорации IBM, так и за ее пределами решили написать для этой машины
системы с разделением времени. Позже была выпущена официальная система раз-
1.7. Структура операционной системы
95
деления времени — TSS/360, и когда она наконец-то дошла до потребителей, то была
настолько громоздкой и медлительной, что под нее было переоборудовано всего лишь
несколько вычислительных центров. В конечном счете от этого проекта отказались,
после того как на него уже было потрачено 50 млн долларов (Graham, 1970).
VM/370
Группа из научного центра IBM Scientific Center в Кембридже (Массачусетс) раз-
работала совершенно другую систему, которую IBM в конечном итоге приняла как
законченный продукт. Эта система, первоначально называвшаяся CP/CMS, а позже
переименованная в VM/370 (Seawright and MacKinnon, 1979), была основана на сле-
дующем проницательном наблюдении: система с разделением времени обеспечивает,
во-первых, многозадачность, а во-вторых, расширенную машину с более удобным
интерфейсом, чем у простого оборудования. Сущность VM/370 заключается в полном
разделении этих двух функций.
Основа системы, известная как монитор виртуальных машин, запускается непосред-
ственно на обычном оборудовании и обеспечивает многозадачность, предоставляя
верхнему уровню не одну, а несколько виртуальных машин (рис. 1.24). Но, в отличие
от всех других операционных систем, эти виртуальные машины не являются машинами
с расширенной архитектурой. Они не поддерживают файлы и другие полезные свой-
ства. Вместо этого они являются точной копией исходной аппаратуры, включающей
режим ядра и пользователя, устройства ввода-вывода, прерывания и все остальное, что
есть у настоящей машины.
Рис. 1.24. Структура VM/370 с тремя запущенными системами CMS
Поскольку каждая виртуальная машина идентична настоящему оборудованию, на каж-
дой из них способна работать любая операционная система, которая может быть запу-
щена непосредственно на самом оборудовании. На разных виртуальных машинах могут
быть запущены разные операционные системы, как это часто и происходит на самом
деле. Изначально на системах VM/370 пользователи запускали в своих виртуальных
машинах OS/360 или одну из других больших операционных систем пакетной обработ-
ки или обработки транзакций, в то время как другие запускали однопользовательскую
интерактивную систему CMS (Conversational Monitor System — система диалоговой
обработки ) для пользователей системы разделения времени.
Когда программа под управлением операционной системы CMS выполняет системный
вызов, он перехватывается в системное прерывание операционной системы на своей
собственной виртуальной машине, а не на VM/370, как это было бы при ее запуске на
реальной, а не на виртуальной машине. Затем CMS выдает обычные команды ввода-
вывода для чтения своего виртуального диска или другие команды, которые могут ей