Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ОСиС_2008

.pdf
Скачиваний:
96
Добавлен:
29.05.2015
Размер:
2.65 Mб
Скачать

7. Подсистема ввода-вывода

247

2)b6 — флаг ошибки. Его установка говорит о том, что при выполнении последней операции ввода-вывода произошла ошибка. Нулевое содержимое этого бита сообщает об отсутствии ошибки;

3)b4b5 используются для задания номера устройства. Таким образом, эти биты являются и битами состояния, и битами управления.

Сделано или устройство готово

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ошибка

 

Номер устройства

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

b7

b6

 

b5

 

b4

b3

b2

b1

b0

Разрешение прерывания

Функция

Разрешение работы

Рис. 60. Пример регистра состояния и управления RS

7.5.1. Двухуровневый драйвер с опросом

Реализацию данного драйвера рассмотрим на следующем гипотетическом примере. Пусть требуется разработать драйвер для управления работой считывателя перфоленты. Допустим, что файлустройство, соответствующий требуемому считывателю перфоленты, имеет имя /dev/pl3. Структура RS приведена на рис. 60. Код вводимого символа помещается в RD.

На рис. 61 приведена логическая схема драйвера. Она представляет собой совокупность трех интерфейсных логических процедур: «Открыть», «Чтение строки байт», «Опрос». Кроме того, эта схема включает две внутренние структуры данных: а) совокупность буферов чтения устройств; б) массив флагов открытия устройств. Рассмотрим работу этих модулей драйвера во взаимодействии с другими аппаратными и программными модулями.

Работа со специальным файлом (файлом-устройством) начинается с открытия этого файла в программе процесса с помощью системного вызова

ОТКРЫТЬ_ФАЙЛ_УСТРОЙСТВА ( /dev/pl3 || i).

248

Одиноков В.В., Коцубинский В.П.

Процесс

ЧТЕНИЕ_ФАЙЛА_УСТРОЙСТВА (i, A, n || )

 

(i, A, n ) ( A, n, ma, mi)

 

Интерфейс

Управление

 

ФС

 

системных

 

драйверами

вызовов

mi

( A, n, mi)

 

 

 

 

Ядро ОС

Открыть

 

Чтение

 

 

 

строки

 

Обработчик

Fmi

 

Буферmi

 

прерываний

 

 

 

 

таймера

 

 

Драйвер П/Л

 

Опрос

Прерывание

b0

b4–b5

b7

RD

 

 

 

 

таймера

 

Управление

 

 

Fu

 

 

устройством

 

 

 

 

 

Контроллер

 

 

 

Рис. 61. Логическая структура драйвера с опросом:

i — программный номер файла-устройства; A — начальный адрес прикладного буфера; n — число читаемых байтов; ma — старший номер устройства; mi — младший номер устройства; Fmi — флаг открытия mi-го устройства; b0 — бит RS разрешения работы; b4–b5 — номер устройства; b7 — бит готовности в RS; RD — буферный регистр данных;

Fu — флаг запуска устройства

Данный вызов преобразуется интерфейсом системных вызовов в команду для виртуальной ФС, которая начинает выполнять открытие файла обычным образом. При этом проверяются права доступа к файлу и создаются необходимые записи в системных таблицах. Специальная реальная ФС находит в inode файла его атрибуты — старший и младший номера устройства. Эти числа

7. Подсистема ввода-вывода

249

используются при формировании команды ФС для модуля управления драйверами.

Используя старший номер устройства, модуль управления находит в коммутаторе строковых драйверов вход в драйвер чтения

сперфоленты и находит в этом входе строку с адресом процедуры «Открыть». При вызове данной процедуры ей на вход передается параметр — младший номер устройства.

Процедура «Открыть» проверяет установку флага открытия, соответствующего устройству с номером mi. Так как устройство ввода с перфоленты является последовательно используемым (см. подразд. 2.3), то оно не может быть открыто более одного раза.

Поэтому если флаг Fmi установлен, то процедура «Открыть» блокирует вызывающий процесс (переводит в состояние «Сон»).

Если же флаг Fmi сброшен, то процедура «Открыть» устанавливает этот флаг и запускает требуемое устройство, установив в 1 b0, записав перед этим в b4–b5 номер устройства mi. Каждая запись в бит b0 приводит к копированию его содержимого во флаг Fu, который управляет работой одного из устройств. Кроме того,

процедура «Открыть» сбрасывает бит RS b3, запрещая тем самым прерывания от устройства ввода с перфоленты, которые в данном драйвере не используются.

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

Fu. Установка этого флага приводит к тому, что контроллер включает двигатель устройства, обеспечивающий перемотку перфоленты на один шаг. После этого очередной байт переписывается

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

в биты b4–b5 RS, а также производит установку бита готовности b7. После этого данный логический процесс возвращается в точку своего входа.

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

250

Одиноков В.В., Коцубинский В.П.

Допустим, что через некоторое время процесс передал в ядро системный вызов для чтения требуемого числа байтов n с перфоленты:

ЧТЕНИЕ_ФАЙЛА_УСТРОЙСТВА (i, A, n || ).

Подобно обычным файлам, ФС находит inode файла, а затем использует его для определения номеров устройства ma и mi. Эти номера используются, в свою очередь, для выдачи запроса к модулю управления драйверами. Этот модуль находит требуемый вход в коммутаторе строковых драйверов и вызывает из этого входа процедуру «Чтение строки байтов».

Данная процедура выбирает из множества буферов драйвера тот буфер, который соответствует заданному номеру mi. Если количество символов, находящихся в этом буфере, не менее требуемого числа n, то первые n символов извлекаются из буфера драйвера и записываются в прикладную область памяти процесса с заданным начальным адресом A. Напомним, что модули верхнего уровня драйвера, как и модули ядра, соединяющие процесс с драйвером, выполняются в контексте этого процесса. Это обеспечивает данным модулям доступ не только к памяти ядра, но и к прикладной памяти процесса. После завершения записи в прикладную область памяти управление возвращается в прикладную часть процесса — на машинную команду, расположенную сразу же за командой системного вызова.

Если на момент выполнения процедуры «Чтение строки байтов» буфер драйвера не содержит требуемого числа символов, то данная процедура перепишет имеющиеся в буфере символы в прикладную область процесса, а затем выполнит блокирование текущего процесса, переводя его в состояние «Сон». Разблокирование процесса произойдет позже, когда процедура «Опрос» или обнаружит наличие в буфере недостающего числа символов, или обнаружит, что буфер полон. В любом случае выполнение процесса продолжится с процедуры «Чтение строки байтов», которая не только перепишет недостающие символы из буфера драйвера в прикладную область, но и выполнит включение устройства (установкой бита b0).

Основной функцией процедуры «Опрос» является прием символов, читаемых устройствами ввода с перфоленты и записываемых затем контроллером в регистр RD. Данная процедура инициируется через постоянные промежутки времени обработчиком прерываний таймера (обычно через тик) и выполняется в контексте этого обработчика, не имея никакого доступа к прикладной памя-

7. Подсистема ввода-вывода

251

ти текущего процесса. При каждом инициировании процедура «Опрос» переписывает символ из RD в буфер драйвера. Если после записи символа в буфер окажется, что буфер полон, то данная процедура выключает устройство (сбросом бита b0).

Так как процедуры «Чтение строки байтов» и «Опрос» работают с общими структурами данных, выполняясь в контексте разных процессов, то они не только кооперируются, но и конкурируют из-за этих структур данных и нуждаются в синхронизации (см. п. 2.4.3). Подобная синхронизация обеспечивается запретом на время выполнения процедуры «Чтение строки байтов» всех маскируемых прерываний (в том числе от таймера).

7.5.2. Двухуровневый драйвер с прерыванием на байт

Основная идея построения драйверов на основе использования сигналов прерывания заключается в том, чтобы информация о завершении устройством текущей операции ввода-вывода поступала в драйвер не по инициативе драйвера, то есть в результате опроса, а по инициативе самого устройства (или его ИУ). Рассмотрим реализацию такого драйвера опять на примере управления гипотетическим устройством ввода с перфоленты.

Логическая схема драйвера представляет собой активный пакет, состоящий из двух интерфейсных логических процедур, логического процесса и двух структур данных (рис. 62). Работа модулей верхнего уровня драйвера мало отличается от работы соответствующих модулей в драйвере с опросом. Отличия заключаются в том, что процедура «Открыть» не сбрасывает, а, наоборот, устанавливает бит разрешения прерываний b3.

Что касается нижнего уровня драйвера, то образующий этот уровень обработчик прерываний инициируется сигналом прерывания, поступившим в ЦП из контроллера ввода с перфоленты. Этот сигнал прерывания поступает на вход обработчика в виде управляющего воздействия через коммутатор строковых драйверов (вход драйвера «обработка прерывания») или через дескрипторную таблицу прерываний IDT (см. п. 5.4.3). Второй из этих вариантов инициирования обработчиков прерываний реализуется в большем числе систем. После своего инициирования обработчик прерываний переписывает код символа из RD в буфер драйвера и, если

252

 

Одиноков В.В., Коцубинский В.П.

буфер не полон, устанавливает бит запуска устройства b0 и бит

разрешения прерываний b3. Иначе эти биты сбрасываются.

 

 

Процесс

 

 

 

ЧТЕНИЕ_ФАЙЛА_УСТРОЙСТВА (i, A, n || )

 

Интерфейс

(i, A, n )

( A, n, ma, mi)

Управление

системных

 

ФС

 

драйверами

вызовов

 

mi

 

 

 

 

 

( A, n, mi)

 

 

 

Открыть

 

Чтение строки

 

 

 

 

байт

 

 

 

Fmi

 

Буферmi

 

 

 

Fmi

 

Буферmi

 

 

 

Fmi

 

Буферmi

 

 

Драйвер П/Л

Обработчик

 

 

прерываний

 

Ядро ОС

 

 

 

 

 

 

 

b0

b4–b5

RD

b3

 

 

bb0 0

Управление 2

2

 

 

Fu

устройством

 

 

Контроллер

 

 

 

Рис. 62. Логическая структура драйвера с прерыванием:

 

i — программный номер файла-устройства; A — начальный адрес

прикладного буфера; n — число читаемых байтов;

 

ma — старший номер устройства; mi — младший номер устройства;

Fmi — флаг открытия mi-го устройства; b0 — бит RS разрешения работы;

b3 — бит разрешения прерываний в RS; b4b5 — номер устройства;

RD — буферный регистр данных; Fu — флаг запуска устройства

7. Подсистема ввода-вывода

253

Как и для драйвера с опросом, логическая схема контроллера представляет собой совокупность логических процессов, каждый из которых выполняет управление одним устройством. Если устройство не работает, его управляющий процесс находится в состоянии «Вход 1», ожидая установки флага запуска устройства Fu. Значение b0 = 1 приводит к установке этого флага для устройства с заданным номером, что инициирует работу контроллера по вводу очередного символа. Логический процесс контроллера помещает код символа в RD (сбрасывая при этом бит b0 RS)

иоказывается в состоянии «вход 2». Так как бит разрешения прерывания b3 = 1, то контроллер инициируется по данному входу

ивыдает сигнал прерывания. Обработчик прерываний считывает код символа из RD в буфер драйвера. Если при этом буфер оказывается полным, то управление сразу возвращается прерван-

ной программе. Иначе сначала установкой b0 = 1 инициируется работа контроллера по вводу следующего символа.

В рассмотренном изложении предполагалось, что аппаратный сигнал внешнего прерывания поступает от ИУ сразу в ЦП. Но

вбольшинстве ВС такие сигналы поступают сначала в програм-

мируемый контроллер прерываний. Данный контроллер упоря-

дочивает поступление сигналов внешних прерываний в ЦП.

Вкачестве примера рассмотрим контроллер прерываний i8259A. Данный контроллер имеет 8 входов — IRQ0, IRQ1…IRQ7, позволяющих принимать запросы на прерывание от восьми ИУ:

IRQ0 — таймер; IRQ1 — клавиатура;

IRQ2 — второй контроллер прерываний; IRQ3 — последовательный порт COM2; IRQ4 — последовательный порт COM1; IRQ5 — параллельный порт LPT2; IRQ6 — гибкий диск;

IRQ7 — параллельный порт LPT1.

Данные входы имеют приоритеты: чем меньше номер входа, тем приоритет выше. Поэтому самыми приоритетными являются сигналы прерываний от таймера. Приоритет сигнала используется контроллером прерываний для определения возможности направления этого сигнала в ЦП. При этом если в контроллер одновременно поступило несколько сигналов прерываний, то из них

вЦП будет отправлен тот сигнал, приоритет которого выше. Кроме того, если ЦП уже занят обработкой какого-то прерывания, то

254

Одиноков В.В., Коцубинский В.П.

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

Номер прерывания, соответствующий конкретному ИУ, можно определить следующим образом: к базовому номеру, соответствующему контроллеру прерываний (8), следует прибавить номер входа в этот контроллер. Например, номер прерывания от клавиа-

туры: N = 8 + 1 = 9.

Как и любое ИУ, контроллер прерываний имеет порты, которые используются программами (драйверами) для управления им. Эти порты имеют адреса 20h и 21h. Порт 21h используется, в частности, для маскирования (то есть для запрета) прерываний от устройств требуемого типа. Для этого требуется записать единицу в тот бит порта, который соответствует номеру входа для устройства. Например, следующие две команды выполняют маскирование прерываний от клавиатуры:

mov

AL, 00000010b ; Вход для клавиатуры — IRQ1

out

21h, AL

Существуют другие команды управления контроллером прерываний, позволяющие размаскировать прерывания от любого ИУ (независимо от маскирования в ЦП), а также изменять приоритеты ИУ. Аналогичные команды используются и для управления вторым (ведомым) контроллером прерываний, который подсоединяется к входу IRQ2 ведущего контроллера. Поэтому ИУ, обслуживаемые ведомым контроллером, выдают сигналы прерываний с приоритетами, расположенными между приоритетами клавиатуры и последовательного порта COM2. Для управления ведомым контроллером используются порты A0h и A1h, аналогичные портам 20h и 21h для ведущего контроллера. Базовый номер прерываний, соответствующий ведомому контроллеру прерываний, равен 70h.

В заключение приведем два типа устройств, обслуживаемых ведомым контроллером прерываний (с указанием его входов):

IRQ13 — математический сопроцессор;

IRQ14 — жесткий магнитный диск.

Благодаря коммутаторам драйверов любая вышестоящая система (ФС, дисковый КЭШ или подсистема управления памятью) имеет стандартный интерфейс для доступа к любым драйверам. Допускается построение строчно-блоковых драйверов, имеющих свои записи в обоих коммутаторах. Поведение такого драйвера

7. Подсистема ввода-вывода

255

(а точнее — используемый набор интерфейсных процедур) зависит от того, через какой коммутатор был сделан доступ к драйверу.

7.5.3. Блочные драйверы с прямым доступом в память

Основное отличие блочных и строковых драйверов заключается в том, как они выполняют обслуживание поступающих запросов на ввод-вывод данных. Строковые драйверы используют для этого две отдельные интерфейсные процедуры «Чтение строки байт» и «Запись строки байт», каждая из которых использует отдельный буфер-очередь драйвера для размещения символьных строк, обслуживаемых в порядке поступления. Каждый блочный драйвер использует для обслуживания поступающих запросов на ввод-вывод данных единственную интерфейсную процедуру «Чте- ние-запись блока», которая помещает все запросы в единственную очередь (рис. 63), элементами которой являются дескрипторы буферов блоков, предназначенных для вывода на устройство или читаемых с него. При этом отметим, что блоковый драйвер не имеет собственного буфера, так как в качестве буферов блоков используются или элементы буфера КЭШа (см. п. 6.4.2), или физические страницы ОП (см. п. 5.3.1).

Вызов процедуры «Чтение-запись блока» происходит следующим образом: дисковый КЭШ или подсистема управления памятью вызывает процедуру «Управление драйверами», передав ей на вход единственный параметр — указатель на дескриптор буфера блока. Этот дескриптор содержит детали требуемой операции информационного обмена с устройством. Структура дескриптора буфера блока была рассмотрена нами в п. 6.4.2. Одно из полей этой структуры содержит старший номер устройства и используется модулем управления драйверами для поиска требуемой точки входа в коммутаторе блочных драйверов. Далее модуль управления драйверами инициирует процедуру «Чтение-запись блока» в требуемом драйвере, передав ей указатель на дескриптор буфера блока.

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

256

Одиноков В.В., Коцубинский В.П.

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

цилиндрами диска. Поэтому целесообразно сначала выполнить чте-

От дискового КЭШа, или

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

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

драйверов

. . . . .

 

 

 

 

открыть

 

 

 

 

закрыть

 

 

 

 

чтение-запись

 

 

 

блока

u

 

 

 

обработка

 

 

ер

прерывания

 

 

. . . . .

Очередь

 

Буфер

(A, v, n)

 

 

 

Открыть

Чтение-

 

Подготовка

 

запись блока

 

ПДП

Драйвер дисковода

 

 

 

К

 

 

 

 

диспетчеру

Обработчик

Драйвер

 

 

прерываний

 

 

ПДП

 

Прерывание

RS1

 

 

RS2

 

 

 

 

Контроллер

2

Канал

2

дисковода

ПДП

1

 

 

 

 

Контроллер ПДП