
1.4. Концепции программных решений 47
приложения смогут использовать предоставленные им средства только так, как
предписано операционной системой. Например, приложениям обычно запре-
щено копировать сообщения прямо в сетевой интерфейс. Взамен операционная
система предоставляет первичные операции связи, которые можно использовать
для пересылки сообщений между приложениями на различных машинах.
Следовательно, операционная система должна полностью контролировать ис-
пользование и распределение аппаратных ресурсов. Поэтому большинство про-
цессоров поддерживают как минимум два режима работы.
В реэюиме
ядра
{kernel
mode) выполняются все разрешенные инструкции, а в ходе выполнения доступна
вся имеющаяся память и любые регистры. Напротив, в
пользовательском режиме
{user
mode) доступ к регистрам и памяти ограничен. Так, приложению не будет
позволено работать с памятью за пределами набора адресов, установленного для
него операционной системой, или обращаться напрямую к регистрам устройств.
На время выполнения кода операционной системы процессор переключается
в режим ядра. Однако единственный способ перейти из пользовательского режима
в режим ядра
—
это сделать системный вызов, реализуемый через операционную
систему. Поскольку системные вызовы
—
это лишь базовые службы, предостав-
ляемые операционной системой, и поскольку ограничение доступа к памяти
и регистрам нередко реализуется аппаратно, операционная система в состоянии
полностью их контролировать.
Существование двух режимов работы привело к такой организации операци-
онных систем, при которой практически весь их код выполняется в режиме ядра.
Результатом часто становятся гигантские монолитные программы, работающие
в едином адресном пространстве. Оборотная сторона такого подхода состоит в
том, что перенастроить систему часто бывает нелегко. Другими словами, заме-
нить или адаптировать компоненты операционной системы без полной переза-
грузки, а возможно и полной перекомпиляции и новой установки очень трудно.
С точки зрения открытости, проектирования программ, надежности или легко-
сти обслуживания монолитные операционные системы
—
это не самая лучшая
из идей.
Более удобен вариант с организацией операционной системы в виде двух час-
тей.
Одна часть содержит набор модулей для управления аппаратным обеспече-
нием, которые прекрасно могут выполняться в пользовательском режиме. На-
пример, управление памятью состоит в основном из отслеживания, какие блоки
памяти выделены под процессы, а какие свободны. Единственный момент, когда
мы нуждаемся в работе в режиме ядра,
—
это установка регистров блока управ-
ления памятью.
Вторая часть операционной системы содержит небольшое микроядро {mic-
rokernel),
содержащее исключительно код, который выполняется в режиме ядра.
На практике мР1кроядро должно содержать только код для установки регистров
устройств, пере1сяючения процессора с процесса на процесс, работы с блоком управ-
ления памятью и перехвата аппаратных прерываний. Кроме того, в нем обычно
содержится код, преобразующий вызовы соответствующих модулей пользова-
тельского уровня операционной системы в системные вызовы и возвращающий
результаты. Такой подход приводит к организации, показанной на рис. 1.8.