
- •7. Ввод-вывод
- •7.1. Доступ к устройствам ввода-вывода
- •7.2. Прерывания
- •7.2.1. Аппаратное обеспечение для поддержки прерываний
- •7.2.2. Запрет и разрешение прерываний
- •7.2.3. Обслуживание нескольких устройств
- •7.2.4. Управление запросами устройств
- •7.2.5. Исключения
- •7.2.6. Прерывания в операционных системах
- •7.3. Механизм прерываний процессора Pentium
- •7.4. Прямой доступ к памяти
7.2.6. Прерывания в операционных системах
Операционная система (ОС) отвечает за координацию всех действий компьютера. Она выполняет операции ввода-вывода, взаимодействует с пользовательскими программами и управляет ими, интенсивно используя прерывания. Механизм прерываний позволяет операционной системе назначать приоритеты, переключаться от одной пользовательской программы к другой, реализовывать функции безопасности и защиты, координировать операции ввода-вывода. В данном разделе мы вкратце обсудим некоторые их этих аспектов.
В состав операционной системы входят программы обработки прерываний для всех подключенных к компьютеру устройств. Прикладные программы не выполняют операции ввода-вывода самостоятельно. Когда прикладной программе необходимо произвести одну из указанных операций, она указывает на подлежащие пересылке данные и просит операционную систему выполнить эту операцию. ОС приостанавливает выполнение программы и осуществляет запрошенную операцию ввода-вывода. По окончании операции ОС опять передает управление прикладной программе. (ОС и прикладная программа передают друг другу управление посредством программных прерываний.)
Операционная система выполняет для прикладных программ множество сервисных функций. Для их реализации многие процессоры поддерживают по нескольку разных команд программных прерываний, каждая их которых имеет собственный вектор прерывания. Эти команды могут использоваться для вызова разных частей ОС, в зависимости от выполняемой функции.
Если компьютер поддерживает два режима, супервизора и пользовательский, получив запрос прерывания, он всегда переключается в режим супервизора. Для этого он устанавливает соответствующий разряд регистра состояния процессора, предварительно сохранив в стеке старое его, регистра, значение. Таким образом, если прикладная программа вызывает ОС с помощью команды программного прерывания, процессор автоматически переключается в режим супервизора, предоставляя ОС полный доступ к ресурсам компьютера. Когда ОС выполняет команду возврата из прерывания, слово состояния процессора, соответствующее выполняемой прикладной программе, восстанавливается из стека. В результате процессор переключается обратно в пользовательский режим.
Чтобы проиллюстрировать взаимодействие между прикладными программами и операционной системой, давайте рассмотрим пример работы в многозадачном режиме, то есть когда процессор выполняет несколько пользовательских программ одновременно. Применяемая при этом стандартная технология называется квантованием времени. Суть ее заключается в том, что каждая прикладная программа выполняется в течение короткого промежутка времени τ, называемого квантом времени, после чего другая программа выполняется в течение своего кванта времени и т, д. Величина τ определяется непрерывно работающими аппаратными часами (таймером), генерирующими прерывание каждые -г секунд.
На рис. 7.10 приведены программы, необходимые для реализации важнейших функций многозадачного окружения. Во время запуска операционной системы выполняется инициализационная подпрограмма, обозначенная на рисунке как OSINIT. Кроме всего прочего эта подпрограмма загружает векторы прерываний, расположенные по отведенным для них фиксированным адресам, В них она записывает начальные адреса программ обработки прерываний. В частности, OSINIT загружает начальный адрес программы-планировщика SHEDULER по адресу, соответствующему вектору прерывания таймера. Таким образом, в конце каждого кванта времени прерывание таймера приводит к выполнению этой программы.
Программа вместе с информацией, описывающей ее текущее состояние, определяется ОС как процесс. Процесс может находиться в одном из трех состояний:
выполнение, ожидание и блокировка, или останов. Под выполняющимся процессом подразумевается выполняемая в данный момент программа. Готовый к выполнению процесс — это программа, ожидающая выбора планировщиком, реализация которой в любой момент может быть начата или продолжена. А заблокированный процесс — это программа, выполнение которой по какой-то причине в данный момент не может быть продолжено (скажем, из-за того, что она ожидает завершения запрошенной операции ввода-вывода).
Предположим, что в течение заданного кванта времени программа А находится в состоянии выполнения. В конце этого кванта времени таймер прерывает работу этой программы и запускает планировщик SHEDULER. Основная задача программы состоит в определении того, какая из пользовательских программ должна выполняться в течение следующего кванта времени. Она начинает свою работу с сохранения всей информации, которая потребуется позднее, при возобновлении работы программы А, Эта информация, называемая состоянием программы, включает содержимое регистров, счетчик команд и слово состояния процессора. Регистры должны быть сохранены потому, что они могут содержать промежуточные результаты вычислений, выполняющихся в момент окончания кванта времени. Счетчик команд указывает, с какой команды должно быть возобновлено выполнение программы. Слово состояния процессора содержит флаги условий и другую важную информацию, в том числе коды приоритетов.
Далее SHEDULER выбирает для выполнения какую-нибудь другую программу, предположим В, приостановленную ранее и находящуюся в режиме готовности. Планировщик восстанавливает всю информацию, сохраненную после приостановления программы В, включая содержимое регистров FX и PC, и выполняет команду возврата из прерывания. В результате этого выполнение программы В возобновляется и продолжается в течение т секунд, после чего таймер снова генерирует прерывание и выполняется переключение контекста на другой процесс, находящийся в состоянии готовности.
OSINIT Установка векторов прерываний:
таймер квантования (SCHEDULER)
программное прерывание (OSSERVICES)
прерывания от клавиатуры (IOData)
OSSERVICES Анализ стека для определения запрошенной операции
Вызов соответствующей программы
SCHEDULER Сохранение состояния программы
Выбор готового к выполнению процесса
Восстановление сохраненного контекста нового процесса Проталкивание в стек новых значений FX и PC
Возврат из прерывания
а
IOINIT Перевод процесса в состояние блокировки
Инициализация указателя на буфер в памяти и счетчика
Вызов драйвера устройства для его инициализации и разрешения прерываний
Возврат из подпрограммы
IODATA Опрос устройств для определения инициатора прерывания
Вызов соответствующего драйвера
Перевод процесса в состояние готовности, если END-1
Возврат из прерывания
б
KBDINIT Разрешение прерываний
Возврат из подпрограммы
KBDDATA Проверка состояния устройства
Если устройство готово к работе, пересылка символа
Если значение символа равно CR, то флаг END устанавливается в 1, что соответствует запрету на прерывания; в противном случае END устанавливается в 0
Возврат из подпрограммы
в
Рис. 7.10. Некоторые из программ операционной системы:
программы инициализации ОС, сервисов и планировщика (а);
программы ввода-вывода (б); драйвер клавиатуры (а)
Предположим, что программе А требуется прочитать вводимую с клавиатуры строку. Вместо того чтобы выполнять эту операцию самостоятельно, программа запрашивает у операционной системы функцию ввода-вывода. Для передачи операционной системе информации о требуемой операции (в том числе об устройстве ввода-вывода и адресе буфера в области данных программы, в который следует поместить прочитанную строку) она использует стек или регистры процессора. Затем программа выполняет команду программного прерывания. Вектор прерывания этой команды указывает на подпрограмму OSSERVICES, представленную на рис. 7.10, а. Эта подпрограмма анализирует информацию в стеке и инициирует запрошенную операцию с помощью вызова соответствующей подпрограммы ОС. В нашем примере она вызывает подпрограмму IOINIT, отвечающую за инициирование операций ввода-вывода (рис. 7.10, б).
Пока выполняется операция ввода-вывода, запросившая ее программа не может продолжать свою работу. Поэтому подпрограмма IOINIT переводит процесс, связанный с программой А, в состояние блокировки, указывающее планировщику, что пока выполнение этой программы не может быть продолжено. Затем данная подпрограмма производит подготовительную работу, необходимую для выполнения операции ввода-вывода (например, инициализацию указателей и счетчика байтов), и вызывает подпрограмму, осуществляющую операцию ввода-вывода.
Как правило, операционные системы строятся так, чтобы все программное обеспечение, связанное с конкретным устройством, заключалось в отдельный модуль, называемый драйверам устройства. Такой модуль легко добавить в операционную систему и легко из нее удалить. Мы предположили, что драйвер клавиатуры состоит из двух подпрограмм, KBDINIT и KBDDATA (рис. 7.10, в). Подпрограмма IOINIT вызывает KBDINIT, выполняющую инициализацию устройства и его интерфейсной схемы. Кроме того, подпрограмма KBDINIT разрешает прерывания от данного устройства, установив соответствующий бит в управляющем регистре его интерфейсной схемы, а затем возвращает управление подпрограмме IOINIT, которая, в свою очередь, возвращает управление подпрограмме OSSERVICES. После этого клавиатура готова к операциям пересылки данных. После каждого нажатия клавиши она будет генерировать запрос прерывания.
После возврата управления подпрограмме OSSERVICES планировщик SHEDULER выбирает для выполнения другую пользовательскую программу. Он не сможет выбрать программу А, поскольку она пока находится в заблокированном состоянии. Команда возврата из прерывания, после которой начинается выполнение выбранной пользовательской программы, разрешает прерывания в процессоре, загрузив в его регистр состояния новое содержимое. Таким образом, сгенерированный клавиатурой запрос прерывания будет принят процессором. Вектор этого прерывания указывает на программу ОС, названную IODATA. Поскольку к одной линии запроса прерывания может быть подсоединено несколько устройств, программа IODATA начинает опрашивать эти устройства, чтобы узнать, кому из них потребовалось обслуживание. Затем она вызывает соответствующий драйвер устройства для обслуживания запроса. В нашем случае будет вызван драйвер KBDDATA, который перешлет в процессор один символ. Если это символ возврата каретки, драйвер установит значение флага END в 1, чтобы проинформировать IODATA о завершении операции ввода-вывода. После этого программа IODATA изменит состояние процесса А — теперь он будет не блокированным, а готовым к выполнению, и когда подойдет его очередь, планировщик сможет выбрать его для выполнения в течение очередного кванта времени.