Главная страница Межпроцессное взаимодействие (состязание) системный вызов, операционная система некоторым волшебным образом переключается из пользовательской части в ядерную . Такой механизм является пережитком MULTICS, где переключение было простым вызовом процедуры, а не ловушкой с сохранением состояния пользовательской части процесса, как в UNIX. В UNIX драйверы устройств являются простыми подпрограммами ядра, которые может вызывать часть процесса, загруженная в пространстве ядра. Когда драйверу надо дождаться прерывания, он вызывает процедуру, и процесс засыпает до тех пор, пока прерывание его не разбудит. Заметьте, что пользовательский процесс при этом также приостанавливается, так как это две части одного процесса. Можно бесконечно перечислять аргументы о преимуществах монолитных систем (таких как UNIX) перед структурированными в виде процессов (наподобие MINIX), и наоборот. Используемый в MINIX подход обеспечивает лучшую модульность, более прозрачный интерфейс между компонентами и легко расширяется на распределенные системы, где разные процессы могут выполняться на разных машинах. Подход UNIX более эффективен, так как вызов подпрограммы гораздо быстрее, чем передача сообщения. MINIX разбита на множество процессов, так как мы убеждены, что по мере роста производительности компьютерных систем ясная структура программного обеспечения будет важнее, чем небольшая жертва производительности. Но знайте, что многие разработчики операционных систем не разделяют это убеждение. В этой главе обсуждаются драйверы RAM-диска, жесткого диска, таймера и терминала. Стандартная комплектация MINIX включает в себя также драйверы для флоппи-дисковода и принтера, которые мы подробно не рассматриваем. Кроме того, имеются драйверы для последовательного интерфейса RS-232, интерфейса SCSI, приводов CD-ROM, адаптера Ethernet и звуковой карты. Они могут быть задействованы при перекомпиляции MINIX. Все эти задачи взаимодействуют с другими частями MINIX одинаковым образом: путем отправки сообщений. Сообщения с запросами содержат различные поля, в которые помещаются код операции (например, чтение или запись) и ее параметры. Получив сообщение, задача пытается выполнить запрос и отправляет ответное сообщение. Поля запроса и ответа для блочного устройства приведены в табл. 3.4. Сообщение с запросом содержит адрес буфера для обмена данными. Ответ включает в себя информацию о состоянии, которую вызвавший процесс может использовать для проверки правильности выполнения запроса. Для символьных устройств поля сообщений могут несколько отличаться от задачи к задаче, но в целом имеют сходную структуру. Например, сообщения для задачи таймера содержат значения времени, а сообщения для задачи терминала - адрес структуры данных, описывающей все возможные параметры, такие как символы, используемые функциями строчного редактирования. Назначение задач - воспринимать и выполнять запросы от других процессов (в норме - от файловой системы) и выполнять их. Для блочных устройств все задачи написаны так, чтобы получить запрос, выполнить его и послать ответ. Такая структура означает простой, линейный алгоритм задач. Когда происходит аппаратное прерывание, задача вызывает операцию receive, чтобы указать, что далее она ожидает только сообщения от прерываний. Новые запросы при этом будут отложены до тех пор, пока текущий не будет обслужен. Задача терминала работает несколько по-другому, так как в этом случае одна задача обслуживает несколько устройств. Поэтому она может воспринимать задание на ввод с клавиатуры и тогда, когда еще не завершено чтение с последовательного интерфейса. Тем не менее для каждого отдельного устройства новая задача начинает выполняться только после завершения старой. Таблица 3.4. Поля запросов от файловой системы к драйверам блочных устройств и ответов, отправляемых файловой системе
Структура основной части кода у каждой задачи одинакова и в общих чертах приведена в листинге 3.1. При запуске системы управление передается каждому из драйверов, с целью дать им возможность инициализировать внутренние таблицы и тому подобные данные. Завершив инициализацию, каждая из задач делает вызов receive, чтобы получить сообщение, и переходит в состояние блокировки. Когда сообщение приходит, запоминается, какой процесс его отправил, после чего вызывается подпрофамма для выполнения необходимых действий. После того как обработка запроса завершена, вызвавшему процессу отправляется сообщение с результатами, а задача переходит к началу цикла и ожидает новых сообщений. За выполнение различных действий, поддерживаемых драйвером, ответственны подпрограммы с именами dev xxx. Код завершения помещается в поле REP STATUS ответа, он равен количеству переданных байтов (ноль или положительное число), если операция закончилась успехом, или номер ошибки (отрицательное число) в противном случае. Количество переданных байтов может отличаться от запрошенного, например, когда достигнут конец файла. В случае терминалов за один запрос возвращается не больше одной строки, даже если запрошено большее количество информации. Листинг 3.1. Общая структура программы задач ввода/вывода message mess: /* Буфер сообщений */ void io task() { initializeO: /* Вызывается только один раз */ while (TRUE) { receive(ANY. &mess): /* Ожидаем запрос */ caller = mess.source: /* Процесс, сделавший запрос */ switch(mess.type) { case READ: rcode = dev read(&mess): break: case WRITE: rcode = dev write(&mess): break; /* Тут находится код для выполнения других действий, таких как OPEN, CLOSE и IOCTL */ default: rcode = ERROR: mess,type = TASK REPLY: mess.status = rcode: /* Код возврата */ sendCcaller. &mess): /* Отправляем ответ */ 3.4.3. Аппаратно-независимый код ввода/вывода в MINIX Весь аппаратно-независимый код ввода/вывода в MINIX является частью файловой системы. Система ввода/вывода так тесно связана с файловой системой, что они обе объединены в один процесс. Функции файловой системы перечислены в табл. 3.2, за исключением функций захвата и освобождения отдельных устройств, которых в существующей конфигурации MINIX нет. Тем не менее, если такая потребность возникнет, эти функции могут быть легко добавлены в код соответствующих драйверов. В дополнение к взаимодействию с драйверами, к буферизации и выделению блоков, файловая система также решает задачи защиты и управления i-узлами, каталогами и монтированными файловыми системами. Подробно эта тема будет рассмотрена в главе 5. 3.4.4. Программы ввода/вывода пользовательского уровня в MINIX Здесь также применяется обобщенная модель, описанная ранее в этой главе. Для выполнения системных вызовов и стандартных функций С, требуемых стандартом POSIX (например, функций форматного ввода/вывода printf и scanf), предоставляются библиотечные процедуры. В стандартной конфигурации MINIX имеется также демон Ipd, который занимается поддержкой очереди печати документов, отправленных на печать командой 1р. В стандартной комплектации MINIX имеется еще ряд демонов, ответственных за различные сетевые функции. Работа этих демонов требует поддержки сетевых функций в ядре, но они могут быть легко задействованы при перекомпиляции. Для этого необходимо включить в систему сетевой сервер, работающий с тем же уровнем привилегий, что и менед-
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |