Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [ 34 ] 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

к их реализации в MINIX. В отличие от UNIX, где ядро представляет собой монолитную профамму, не разбитую на модули, ядро MINIX само является набором процессов, взаимодействующих с пользователем и между собой при помощи единственного примитива - передачи сообщений. Такой подход дает более гибкую и модульную структуру, позволяя, например, легко заменить всю файловую систему другой, не пересобирая ядро.

2.5.1. Внутренняя структура MINIX

Начнем наше изучение MINIX с обзора системы с высоты птичьего полета. Структурно система разбита на четыре уровня, каждый из которых выполняет строго определенные функции. Эти уровни показаны на рис. 2.13.

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

Второй слой составляют процессы ввода/вывода, по одному на отдельный тип устройств. Чтобы отличать такие процессы от обычных пользовательских процессов, мы будем называть их задачами, но различие между задачами и процессами минимально. В большинстве систем задачи ввода/вывода называются драйверами устройств. Мы будем использовать термины задача и драйвер устройства как эквивалентные. Каждому типу устройств, будь то диски, принтеры, терминалы, сетевые интерфейсы или таймеры, нужна своя задача. Одна задача, системная, несколько отличается от всех остальных, так как она не соответствует какому-либо устройству ввода/вывода. Эту задачу мы рассмотрим в следующей главе.

Все задачи, образующие второй слой, и весь код первого слоя связаны в одну двоичную профамму, называемую ядром. У некоторых задач есть общие процедуры, но во всех отношениях они не зависят друг от друга, управляются планировщиком как отдельные процессы и взаимодействуют друг с другом при помощи сообщений. В процессорах Intel, начиная с 286, каждому процессу может быть назначен один из четырех уровней привилегий. При этом задачи и ядро работают с разными уровнями приоритета, хотя они и компилируются вместе. Настоящий код ядра может обращаться к любому адресу памяти и любому регистру, по сути, ядро вправе выполнить любую инструкцию с любыми данными. В отличие от ядра задачи не могут обращаться ко всем адресам памяти и всем регистрам процессора. Тем не менее им позволено обращаться к памяти менее привилегированных процессов, чтобы выполнять для них операции ввода/вывода.



Системная задача не занимается вводом-выводом в прямом смысле этого слова, ее цель - предоставление таких услуг, как копирование данных между различными областями памяти, для процессов, которые сами не умеют выполнять подобные действия. Конечно же, все эти ограничения не являются столь жесткими на машинах без нескольких уровней привилегий, например на некоторых старых машинах Intel.

Третий уровень населяют разнообразные службы, нужные пользовательским процессам. Эти процессы работают с меньшим уровнем привилегий, чем процессы ядра или задач, поэтому не в состоянии напрямую обращаться к портам ввода/вывода. Кроме того, они не могут обращаться к памяти вне выделенного для них сегмента. Менеджер памяти (memory manager, MM) ответственен за обработку всех системных вызовов MINIX, касающихся работы с памятью, например fork, exec и Ьгк. Все файловые системные вызовы обрабатываются файловой системой (file system, FS), это, например, read, mount и chdir.

Как было замечено в начале первой главы, операционные системы выполняют две основные задачи: управляют ресурсами и реализуют при помощи системных вызовов интерфейс расширенной машины. В MINIX распределением ресурсов заведуют преимущественно первый и второй уровни, а обработкой системных вызовов занимается третий уровень. Файловая система была реализована как сервер , поэтому она может быть размещена на удаленной машине практически в неизменном виде. То же касается и менеджера памяти, хотя удаленные серверы памяти не так полезны, как удаленные серверы файлов.

Кроме того, на третьем уровне могут существовать вспомогательные серверные процессы. На рис. 2.13 на этот уровень дополнительно помещен сетевой сервер, исходные коды которого входят в установочный пакет MINIX. Чтобы включить его, систему нужно просто перекомпилировать.

Уровень

Init

Пользовательский процесс

Менеджер памяти

Пользовательский процесс

Файловая система

Пользовательский процесс

Сетевой сервер

Задача

Задача

Задача

Задача

Задача

#

диска

терминала

часов

системы

Ethernet

Управление процессами

Пользоватепьские процессы

Серверы

Задачи ввода-вывода

Рис. 2.13. Четыре уровня структуры MINIX

Здесь нужно отметить, что хотя различные серверы и являются независимыми процессами, они отличаются от пользовательских процессов тем, что запускаются вместе с системой, и пока система активна, они не могут быть завершены. Кроме того, хотя уровень привилегий для серверных процессов и ограничивает их теми же инструкциями, что и пользовательские профаммы, серверы выполняются с несколько большим приоритетом. Код запуска ядра помещает эти процессы в привилегированные ячейки таблицы процессов до того, как запустить



любую пользовательскую программу. Чтобы добавить в ядро новый сервер, ядро необходимо перекомпилировать.

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

2.5.2. Управление процессами в MINIX

В MINIX процессы соответствуют описанной несколько ранее обобщенной модели процесса. Процессы могут запускать процессы-потомки, те, в свою очередь, могут делать то же самое, образуя, таким образом, дерево процессов. По сути, все пользовательские процессы в системе - листы одного дерева, в корне которого находится init (см. рис. 2.13).

Как возникает такая ситуация? При включении компьютера первый сектор или первая дорожка загрузочного диска автоматически считываются в память, и хранимый там код исполняется. Детали этого процесса во многом зависят от того, производится загрузка с гибкого или жесткого диска. На дискете первый сектор содержит программу начальной загрузки. Это очень маленькая программа, так как она должна уместиться в один сектор диска. Затем в MINIX эта программа загружает и запускает более сложную программу, boot, а она, в свою очередь, загружает операционную систему.

При загрузке с жесткого диска требуется дополнительный промежуточный этап. Жесткие диски разбиваются на разделы, и первый сектор жесткого диска содержит небольшую программу и таблицу разделов, вместе они называются главной загрузочной записью (Master Boot Record, MBR). Профаммная часть считывает таблицу разделов и выбирает активный раздел. В первом секторе активного раздела расположена профамма начальной зафузки, которая загружается, после чего действует так же, как при зафузке с дискеты, запуская профамму boot.

В любом случае после запуска boot ищет на диске различные компоненты системы и размещает их по нужным адресам. Это касается ядра, менеджера памяти, файловой системы и профаммы init, корневого пользовательского процесса. Запуск системы - не простая операция. Ядру необходимо выполнять действия с диском и файловой системой до того, как эти части придут в готовность. В последующих разделах мы вернемся к вопросу запуска MINIX, а сейчас будет достаточно сказать, что, как только процесс загрузки завершается, ядро начинает работу.

В процессе инициализации ядро запускает задачи, затем менеджер памяти, файловую систему и прочие сервисы третьего уровня. Когда все они инициали-



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [ 34 ] 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.