Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Олифер. Сетевые операционные системы.docx
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
16.5 Mб
Скачать

Структура драйвера Unix

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

Блок-ориентированные драйверы

Драйвер блок-ориентированного устройства состоит из следующих функций:

  • open — выполняет процедуру логического открытия устройства;

  • close — выполняет процедуру логического закрытия устройства;

  • strategy — читает или записывает блок;

  • print — выводит сообщение об ошибке; '

  • size — возвращает размер раздела, который представляет данное устройство.

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

Процедуры обработки прерываний драйвера в таблице bdevsw не указываются, их адреса помещаются в специальную системную структуру — таблицу прерываний. В Unix все обработчики прерываний, в том числе и обработчики прерываний аппаратных драйверов, состоят из двух процедур, называемых соответственно top_half — верхняя часть обработчика прерываний и bottom_half нижняя часть обработчика прерываний. Верхняя часть обработчика прерываний соответствует по назначению ISR-процедуре драйвера ОС семейства Windows NT — она вызывается при возникновении аппаратного запроса прерывания от устройства. В обязанности верхней части входит быстрая реакция на событие в устройстве, вызвавшее генерирование сигнала прерывания. При обработке верхних половин все прерывания с более низкими приоритетами блокируются аппаратно за счет управления контроллером прерываний (или аналогичным по назначению блоком компьютера). Верхняя половина отвечает также за постановку в очередь на выполнение нижней половины обработчика прерываний драйвера, который выполняет менее срочную и более трудоемкую работу.

Нижние половины драйверов выполняются с низким уровнем приоритета, так что любые запросы прерываний устройств могут прервать их обработку. Нижние половины обработчиков прерываний драйверов Unix по назначению соответствуют DPC-процедурам драйверов ОС семейства Windows NT. Часто единственной обязанностью верхней половины обработчика прерываний является постановка в очередь нижней половины для последующего выполнения.

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

Функция стратегии драйвера strategy выполняет чтение и запись блока данных на основании информации в буфере — особой структуре ядра с именем buf, управляющей обменом данных с диском. Функция strategy поддерживает обмен только с системной памятью, так как блок-ориентированный драйвер не­посредственно не взаимодействует с пользовательским процессом. Между ним и пользовательским процессом всегда работает промежуточный программный слой или слои — либо слой дискового кэша вместе со слоем файловой систе­мы, либо слой байт-ориентированного драйвера диска, с помощью которого пользовательский процесс может открыть специальный файл, соответствующий диску.

В число наиболее важных элементов структуры buf входят следующие:

  • b_flags — набор битов, в котором задаются тип операции (чтение или запись), синхронный или асинхронный режим операции (при записи), признак активности операции с буфером, признак завершения операции, признак ожидания буфера процессом и некоторые другие;

  • b_forw, b_back — указатели на последующий и предыдущий буферы в списке активных (используемых) буферов;

  • av_form, av_back указатели на последующий и предыдущий буферы в списке свободных буферов; (

  • b_dev номер драйвера (major) и номер устройства (minor) из индексного дескриптора специального устройства, для которого выполняется операция обмена данными;

  • b_bcount количество байтов, которые нужно передать;

  • b_addr — адрес буфера памяти, куда нужно записать или откуда нужно прочитать данные;

  • b_blkno номер блока в разделе диска;

  • b_bufsize — размер блока (в ранних версиях Unix использовался только одни размер блока — 512 байт, в версиях, основанных на коде System V Release 4, можно работать с блоками разного размера);

  • b_iodone указатель на функцию, которая вызывается при завершении операции ввода-вывода.

Функция strategy при вызове получает указатель на структуру buf, описывающую требуемую операцию. На рис. 8.4 приведен пример блок-схемы двух функций драйвера диска — стратегии (hd_strategy) и нижней половины обработчика прерываний (hd_bottom). Функция hd_strategy преобразует логический номер блока в номера цилиндра, головки и сектора и помещает эту инфор­мацию в заголовок запроса операции для передачи ее контроллеру диска. В заголовок запроса помещается также другая информация, необходимая для работы контроллера, — это операция чтения или записи, адрес системной памяти, куда нужно поместить прочитанную информацию или откуда контролеру нужно считать записываемые данные. Драйвер ведет две очереди для передачи запросов на выполнение операций чтения и записи контроллеру диска: рабочую очередь, в которой находятся обрабатываемые контроллером запросы, и очередь приостановленных запросов, куда помещаются новые запросы в том случае, если рабочая очередь заполнена — а ее размер зависит от возможностей контроллера по параллельной обработке запросов.

Рис. 8.4. Блок-схема драйвера диска

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