Добавлен: 20.10.2018
Просмотров: 1039
Скачиваний: 5
8. Драйвер проверяет код завершения операции и в зависимости от его
значения либо повторяет цикл ввода/вывода для следующего элемента
данных, либо передает на верхний уровень сообщение о возникшей
ошибке.
Эта общая схема требует уточнения для конкретных операций. Например,
вывод на принтер по одному элементу данных неэффективен, поэтому в
схему добавляются следующие шаги:
стандартная программа печати накапливает группу выводимых
элементов данных в промежуточном буфере вывода и передает адрес
этого буфера драйверу принтера;
драйвер принтера запускает процесс печати и блокируется на время
выполнения операции вывода этой порции данных (шаги 1-6
приведенного выше алгоритма);
когда принтер закончит печать заданной порции данных, он генерирует
прерывание (механизм прерываний рассматривается ниже), по
которому драйвер принтера вновь активизируется и выполняет
завершающую работу (шаги 7 и 8).
Необходимо помнить, что драйвер – это программа, для выполнения
которой ей необходимо предоставить процессор, а поскольку большинство
операций
ввода/вывода
выполняется
относительно
медленно,
то
блокирование драйвера на время выполнения устройством операции
ввода/вывода вполне оправданно.
Большинство драйверов имеют следующую типовую структуру:
секция запуска предназначена для инициирования операции
ввода/вывода;
секция продолжения выполняет основную работу по обмену данными,
в том числе такую важную, как обработка прерываний с запуском
соответствующей компоненты секции продолжения; часто драйверы
содержат несколько секций продолжения;
секция завершения выполняет необходимые завершающие действия.
Одним из фундаментальных понятий подсистемы ввода/вывода является
понятие
прерывания,
важность
которого
для
функционирования
вычислительных систем настолько высока, что требует отдельного
рассмотрения.
Прерывание (interrupt) – это механизм, с помощью которого
вычислительная система может реагировать на возникающие в ней события.
Система должна уметь распознать возникшее событие и обработать его, т.е.
выполнить предусмотренные для этого действия. При этом процессор
должен переключиться на выполнение программного кода обработки
прерывания. Важнейшая особенность прерываний – непредсказуемость
моментов их возникновения.
Основной тип прерываний – это внешние или аппаратные прерывания,
источниками которых являются контроллеры различных устройств, в том
числе - устройств ввода/вывода. Примерами таких прерываний являются:
нажатие клавиши на клавиатуре, нажатие кнопки мыши, завершение
дисковой операции, сигнал от системного таймера и т.д. Именно эти
прерывания позволяют организовать согласованную работу всех устройств
вычислительной системы.
Интуитивно понятно, что возникающие в системе события могут иметь
разную степень важности, поэтому механизм прерываний реализует
приоритетную схему обработки. Все прерывания упорядочены по степени
убывания важности следующим образом:
критические сбои аппаратуры (сбой питания, ошибка шины);
прерывания от системного таймера (основа механизма квантования при
вытесняющей многозадачности);
прерывания от дисковых устройств;
прерывания от сетевых устройств;
прерывания от клавиатуры и мыши.
Эти приоритеты играют большую роль в алгоритме обработки
прерываний. Необходимо отметить, что обработка прерываний в
существенной степени выполняется на аппаратном уровне, что объясняется
большой частотой их возникновения и необходимостью обработки с
максимально высокой скоростью. Для этого многие современные
вычислительные системы имеют специальное устройство – контроллер
прерываний. Каждое устройство получает свой номер прерывания (иногда
один и тот же номер могут иметь сразу несколько устройств). Когда
устройство хочет сообщить о некотором событии, оно выставляет сигнал на
выделенную ему линию шины. Этот сигнал распознается контроллером
прерываний, который с помощью своей встроенной логики реализует
следующие действия:
если процессор занят обработкой более приоритетного прерывания, то
новое прерывание игнорируется, не обрабатывается, но устройство
−
источник прерывания продолжает удерживать сигнал прерывания на
шине до наступления “лучших времен”, т.е. освобождения процессора;
если процессор выполняет менее приоритетную работу, эта работа
прерывается с сохранением контекста и происходит переключение на
обработку нового прерывания.
Простейший способ запуска обработчиков прерываний состоит в
использовании специальных таблиц, называемых таблицами векторов
прерываний. Такая таблица содержит начальные адреса размещения в
памяти соответствующих обработчиков прерываний. Сама таблица
находится в памяти в строго фиксированном месте и индексируется номером
прерывания. Например, если прерывания перенумерованы от 0 до 255, то
таблица содержит 256 записей по 4 байта, т.е. занимает 1 Кб памяти. В этом
случае по номеру прерывания (индекс в таблице!) сразу определяется адрес
той команды, с которой начинается код соответствующего обработчика. Этот
адрес заносится в счетчик команд, и тем самым процессор переключается на
выполнение кода обработчика. Само переключение контекста выполняется
обычным образом, с сохранением информации о прерванном потоке и с его
возобновлением, когда это будет возможно.
Кроме внешних (аппаратных) прерываний часто рассматриваются и два
других типа прерываний – внутренние и программные. Внутренние
прерывания возникают при выполнении процессором потока команд, когда
очередная команда в этом потоке по тем или иным причинам не может быть
выполнена. Например: попытка деления на ноль, обращение по
неправильному адресу, попытка выполнить запрещенную команду,
отсутствие запрошенной страницы памяти и т.д. Такие особые ситуации
(часто их называют исключениями) распознаются процессором и должны
быть соответствующим образом обработаны. Программные прерывания, или
псевдопрерывания, генерируются специальными командами и часто
используются программистами для быстрого вызова важных системных
функций. Программные прерывания имеют меньший приоритет по
сравнению с аппаратными и поэтому обрабатываются в последнюю очередь.
В качестве примера ниже приводятся шестнадцатеричные адреса
некоторых прерываний процессоров семейства Intel.
Аппаратные прерывания:
08h - от системного таймера;
09h - от клавиатуры;
0Eh - от гибкого диска;
76h - от жесткого диска.
Внутренние прерывания:
00h - деление на 0;
0lh - пошаговое выполнение команд программы в режиме отладки.
Программные прерывания:
10h – обращение к подпрограммам BIOS управления видеосистемой;
13h – обращение к подпрограммам BIOS управления дисками;
16h – обращение к подпрограммам BIOS управления клавиатурой.
Управляющие программы, которые можно назвать одним термином
“диспетчер (или менеджер) ввода/вывода”, реализуют верхний уровень
программного слоя подсистемы ввода/вывода. Главное, но не единственное
назначение диспетчера – принимать вызовы на выполнение операций
ввода/вывода от прикладных и системных процессов, транслировать эти
вызовы соответствующим драйверам и возвращать результаты выполнения
затребованных операций процессам-потребителям. Особенно актуальной эта
задача становится в условиях многозадачности, когда один и тот же ресурс
может потребоваться нескольким процессам.
Для решения такой задачи диспетчер ввода/вывода должен в каждый
момент времени знать текущее состояние каждого из установленных в
системе устройств. Для этого система создает и поддерживает одну или
несколько связанных информационных структур данных (таблиц). Основная
таблица должна содержать перечень всего имеющегося в системе
оборудования. Для каждого устройства создается своя запись-дескриптор,
содержащая следующие данные:
тип устройства и его основные характеристики;
номера используемых портов и выделенных устройству прерываний;
информация о драйвере устройства, в частности – адреса точек входа
всех входящих в него процедур;
текущее состояние устройства и, в частности, идентификатор процесса,
использующего устройство в данный момент;
если устройство использует буферы для обмена данными, то адреса
размещения в памяти всех буферов;
адрес начала списка процессов, ожидающих данное устройство;
логическое имя устройства, используемое высокоуровневыми
вызовами.
Обобщенный алгоритм работы диспетчера ввода/вывода можно
представить следующим образом:
диспетчер принимает запрос на выполнение операции в виде
системного вызова от активного процесса и проверяет правильность
передаваемых в этом запросе параметров;