Реферат: Разработка операционных систем
Системы клиент-сервер
Компромиссом между
операционной системой, которая делает все, и операционной системой, не делающей
ничего, является операционная система, делающая кое-что. Результатом такого
дизайна является схема микроядра, при которой большая часть операционной
системы представляет собой серверные процессы, работающие на уровне
пользователя (см. рис. 1.23). Такое устройство обладает наибольшей модульностью
и гибкостью по сравнению с другими схемами. Предел гибкости заключается в том,
чтобы каждый драйвер устройства также работал в виде пользовательского
процесса, полностью защищенного от ядра и других драйверов. Удаление драйверов
из ядра позволяет устранить наибольший источник нестабильности в любой
операционной системе – полные ошибок драйверы, написанные третьими фирмами.
Разумеется, драйверы
устройств должны получать доступ к аппаратным регистрам устройств, поэтому
необходим определенный механизм, обеспечивающий этот доступ. Если аппаратура
это позволяет, то каждому драйверному процессу может быть предоставлен доступ
только к нужным ему устройствам ввода-вывода. Например, если регистры устройств
ввода-вывода отображаются на адресное пространство памяти, то у каждого
драйверного процесса может быть страница памяти, на которую отображаются
регистры соответствующего устройства, но не другие страницы. Если же
пространство портов ввода-вывода частично защищено, каждому драйверу может быть
разрешен доступ к нужной ему порции этого пространства.
Даже если аппаратная
поддержка недоступна, этой идеей все равно можно воспользоваться. Для этого
нужен новый системный вызов, доступный только для драйверных процессов. Для
работы этот системный вызов пользуется списком пар (порт, значение). Ядро
сначала проверяет, владеет ли процесс всеми портами в списке. Если да, то оно
копирует в порты соответствующие значения для инициализации устройства
ввода-вывода Подобный системный вызов может быть использован для чтения портов
ввода-вывода защищенным образом.
Такой метод защищает
структуры данных ядра от изучения и повреждения их драйверами устройств, что
(по большей части) хорошо. Возможно создание аналогичного набора вызовов,
позволяющим драйверам устройств читать и писать таблицы ядра, но только под
контролем ядра и с его одобрения.
Главная проблема такого
подхода, и проблема микроядер вообще, заключается в снижении
производительности, вызываемом дополнительными переключениями контекста. Однако
практически вся работа по созданию микроядер была выполнена много лет назад,
когда центральные процессоры были значительно медленнее. Сегодня не так уж
много приложений, использующих каждую каплю мощности процессора, которые не
могут смириться с малейшей потерей производительности. В конце концов, когда
работает текстовый редактор или web-браузер, центральный процессор простаивает
около 90 % времени. Если операционная система, основанная на микроядре,
превращает систему с процессором, работающем на частоте 900 МГц, в надежную
систему, аналогичную по производительности системе с частотой 800 МГц, мало кто
из пользователей станет жаловаться. Большинство пользователей были просто
счастливы всего несколько лет назад, когда приобрели свой предыдущий компьютер
с потрясающей тогда частотой процессора в 100 МГц.
Расширяемые системы
В обсуждавшихся выше
системах клиент-сервер идея заключалась в том, чтобы вынести за пределы ядра
столько, сколько возможно. Противоположный подход заключается в том, чтобы
поместить больше модулей в ядро, но защищенным способом. Ключевое слово здесь,
разумеется, защищенным. Самыми важными из них являются «песочницы» и программы
с электронной подписью, так как интерпретацию применять в ядре непрактично.
Конечно, сама расширяемая
система не является методом структурирования операционной системы. Однако,
начав с минимальной системы, состоящей в основном из механизма защиты, и
постепенно добавляя к ядру защищенные модули, пока не будет достигнута
требуемая функциональность, можно создать минимальную систему для конкретного
приложения. При таком подходе новая операционная система может выкраиваться под
каждое новое приложение благодаря включению только тех элементов, которые
необходимы для данного приложения. Примером такой системы является Paramecium.
Потоки ядра
Еще один вопрос, имеющий
отношение к данной теме, независимо от выбора структурной модели – это
системные потоки. Иногда бывает удобно позволить существовать потокам ядра
отдельно от пользовательских процессов. Эти потоки могут работать в фоновом
режиме, записывая «грязные» страницы на диск, занимаясь свопингом процессов и
т. д. На самом деле ядро само может целиком состоять из таких потоков. Когда
пользователь обращается к системному вызову, пользовательский поток не
выполняется в режиме ядра, а блокируется и передает управление потоку ядра,
который принимает управление для выполнения работы.
Помимо потоков ядра,
работающих в фоновом режиме, большинство систем также запускают в фоновом
режиме множество процессов-демонов. Хотя они и не являются частью операционной
системы, они часто выполняют «системные» функции. Это может быть получение и
отправка электронной почты, а также обслуживание различных запросов удаленных
пользователей, как, например, FTP или web-страницы.
Механизм и политика
Еще один принцип,
помогающий добиться архитектурной согласованности, наряду с принципами
минимализма и структурированности заключается в отделении механизма от
политики. Если поместить механизм в операционную систему, а политику оставить
пользовательским процессам, система может остаться неизменной, даже если
появляется потребность в изменении политики. Даже если модуль, занимающийся
политикой, должен располагаться в ядре, он должен быть, по возможности,
изолирован от механизма, чтобы изменения в модуле политики не влияли на модуль
механизма.
Чтобы сделать границу
между механизмом и политикой отчетливей, рассмотрим два примера из реального
мира. В качестве первого примера возьмем большую компанию, у которой есть отдел
заработной платы, ответственный за выплату жалования сотрудникам. У него есть
компьютеры, программное обеспечение, бланки, договоренность с банками, а также
другие механизмы, требуемые для фактической выплаты зарплаты. Однако политика –
принятие решений, кто и сколько получит – полностью отделена и является
прерогативой управления. Отдел заработной платы просто выполняет порученную ему
работу.
В качестве второго
примера рассмотрим ресторан. Он обладает механизмом для обслуживания
посетителей, включая столы, посуду, официантов, полную оборудования кухню,
договоры с компаниями, продающими товары по кредитным карточкам и т. д.
Политика, то есть что будет в меню, определяется шеф-поваром. Если шеф-повар
решит, что тофу кончился, а большие бифштексы остались, то новая политика может
быть выполнена существующим механизмом.
Теперь рассмотрим
некоторые примеры из области операционных систем. Во-первых, взглянем на
планирование потоков. В ядре может располагаться приоритетный планировщик с k
уровнями приоритетов. Этот механизм представляет собой массив, проиндексированный
уровнем приоритета. Каждый элемент массива представляет собой заголовок списка
готовых потоков с данным уровнем приоритета. Планировщик просто просматривает
массив, начиная с максимального приоритета, выбирая первый подходящий поток.
Политика заключается в установке приоритетов. В системе могут быть различные
классы пользователей, например, у каждого пользователя может быть свой
приоритет. Система может также позволять процессам устанавливать относительные
приоритеты для своих потоков. Приоритеты могут увеличиваться после завершения
операции ввода-вывода или уменьшаться, когда процесс истратил отпущенный ему
квант. Может применяться также еще множество других политических подходов, но
основной принцип состоит в разделении между установкой политики и претворением
ее в жизнь.
Вторым примером является
страничная подкачка. Механизм включает в себя управление блоком MMU, поддержку
списка занятых и свободных страниц, а также программу для перемещения страниц с
диска в память и обратно. Политика в данном случае заключается в принятии
решения о выполняемых действиях при возникновении страничного прерывания.
Политика может быть локальной или глобальной, основываться на алгоритме LRU,
FIFO или каком-либо другом алгоритме, но она может (и должна) быть полностью
отделена от механики фактической работы со страницами.
Третий пример –
возможность загрузки модулей в ядро. Механизм определяет то, как они
устанавливаются в ядро, как они связываются, к каким вызовам они могут
обращаться и какие вызовы могут сами предоставлять. Политика определяет список
пользователей, которым разрешается загружать модуль в ядро, а также список
модулей, которые разрешается загружать каждому пользователю. Возможно, только
суперпользователь может загружать модули, но разрешение загружать модули может
также предоставляться и любому пользователю, если у модуля есть цифровая
подпись соответствующей авторитетной организации.
Ортогональность
Хорошая системная
организация включает в себя отдельные концепции, которые можно независимо смешивать.
Например, в языке С++ есть примитивные типы данных, включающие целые,
символьные числа и числа с плавающей точкой. Существуют механизмы для
комбинирования типов данных, включая массивы, структуры и объединения. Эти
концепции независимы друг от друга, что позволяет создавать целые массивы,
символьные массивы, массивы структур, структуры, состоящие из массивов и т. д.
Действительно, как только
определен новый тип данных, например массив целых чисел, он может
использоваться в качестве члена структуры или объединения, как если бы он был
примитивным типом данных. Возможность независимо комбинировать раздельные
концепции называется ортогональностью. Это свойство является прямым следствием
простоты и полноты принципов.
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 |