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

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

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

Вообще говоря, назначение драйвера в том, чтобы воспринимать абстрактные запросы от аппаратно-независимых программ верхнего уровня и сообщать им, что запрос выполнен. При этом, если в момент передачи запроса драйвер бездействовал, он сразу начинает работу. Если же драйвер был занят, запрос обычно помещается в очередь и обслуживается по мере возможности.

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

При обработке запроса на обмен данными драйвер прежде всего преобразует запрос из абстрактного представления в конкретную форму. Скажем, драйвер диска должен выяснить, где находится запрощенный блок данных, проверить, работает ли привод диска, находится ли головка над нужной дорожкой и т. д. Говоря коротко, драйвер должен сам определить свою последовательность действий.

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

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

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

3.2.4. Независимое от устройств программное обеспечение ввода/вывода

Хотя некоторая часть профаммного обеспечения ввода/вывода предназначена для работы с конкретными устройствами, другая часть является независимой от



устройств. Расположение точной границы между драйверами и независимым от устройств программным обеспечением обусловлено системой (и устройствами), так как некоторые функции, которые могут быть реализованы независимым от устройств образом, часто выполняются прямо в драйверах из различных соображений, в том числе с позиций эффективности. Функции, показанные в табл. 3.2, обычно реализуются в независимом от устройств профаммном обеспечении. В MINIX большая часть таких профамм является составляющей файловой системы, которая находится на уровне 3 (см. рис. 2.13). Файловую систему мы будем изучать в главе 5, а здесь дадим только краткий обзор, чтобы продемонстрировать некоторые перспективы и лучше объяснить, как работают драйверы.

Таблица 3.2. Функции независимого от устройств программного обеспечения Единообразный интерфейс для драйверов устройств Именование устройств Защита устройств

Обеспечение аппаратно-независимого размера блока

Буферизация

Сообщение об ошибках

Выделение места на блочных устройствах

Захват и освобождение выделенных устройств

Обработка ошибок

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

Одна из основных задач операционной системы состоит в том, чтобы дать имена таким объектам, как файлы и устройства ввода/вывода. Отображением символических имен устройств на соответствующие драйверы занимаются аппа-ратно-независимые программы. Например, в UNIX имя устройства /dev/diskO однозначно указывает г-узел специального файла, а подходящий драйвер определяется по главному номеру устройства. Этот f-узел также содержит младший номер устройства, передаваемый в виде параметра драйверу для указания конкретного диска или раздела диска, к которому относится операция чтения или записи. Все устройства в системе UNIX имеют главный и второстепенный номера, по которым они однозначно идентифицируются. Выбор всех драйверов осуществляется по главному номеру устройства.

С именованием устройств тесно связан вопрос защиты. Как операционная система предотвращает доступ пользователей к устройствам, на который у них нет прав? В UNIX и в Windows 2000 устройства представляются в файловой системе в виде именованных объектов, что дает возможность применять обычные правила защиты файлов к устройствам ввода/вывода. Таким образом, системному администратору легко установить нужные разрешения для каждого устройства.



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

Буферизация также является важным вопросом как для блочных, так и для символьных устройств по самым разным причинам. Для блочных устройств аппаратное обеспечение обычно требует того, чтобы чтение или запись производились большими блоками. Но для пользовательских профамм такого ограничения нет, и они вправе передавать любые объемы информации. Поэтому, если пользователь передал только половину блока, операционная система обычно не станет сразу записывать эти данные на диск, а дождется того, когда будет передана оставшаяся часть блока. Что касается символьных устройств, то пользователь может передавать данные быстрее, чем устройство в состоянии их воспринять, таким образом, также необходима буферизация. Не исключено также, что данные, например, от клавиатуры, могут опережать свое считывание, и в этом случае также не обойтись без буфера.

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

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

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



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 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.