Обработчики прерываний
Хотя бывают случаи, когда вполне можно обойтись и программным вводом-выводом, все же для большинства операций ввода-вывода прерывания являются не чем иным, как суровой необходимостью. Они должны быть спрятаны как можно глубже в недрах операционной системы, чтобы о них было известно как можно меньшей части этой системы. Лучший способ их спрятать это заблокировать тот драйвер, который начал операцию ввода-вывода, до тех пор пока не будет завершен ввод-вывод и не будет получено прерывание. Драйвер может заблокировать себя сам, выполнив, к примеру, процедуру down на семафоре, или же процедуру wait на переменной состояния, или процедуру receive на сообщении, или еще что-либо подобное.
Кода происходит прерывание, то все необходимое для его обработки делает процедура — обработчик прерывания. Затем она может разблокировать запустивший ее драйвер. В ряде случаев она просто выполняет процедуру up на семафоре. В других случаях она вызывает процедуру signal для переменной условия в мониторе. Во всех остальных случаях она посылает заблокированному драйверу сообщение. В любом случае заключительным действием прерывания будет предоставление возможности возобновления работы ранее заблокированному драйверу. Такая модель лучше всего работает в том случае, если драйверы структурно относятся к процессам ядра, имея свои собственные состояния, стеки и счетчики команд.
Разумеется, в действительности не все так просто. Обработка прерывания не ограничивается только его перехватом, вызовом процедуры up для некого семафора, а затем выполнением команды IRET для возвращения из прерывания к предыдущему процессу. На операционную систему возлагается куда более существенный объем работы. Сейчас будет дано лишь краткое описание этой работы в виде последовательности шагов, которые должны быть выполнены программным обеспечением после завершения аппаратного прерывания. Следует заметить, что подробности этой работы сильно зависят от конкретной операционной системы, поэтому некоторые из перечисленных ниже шагов конкретной машине могут и не
понадобиться, в отличие от шагов, не попавших в этот перечень. Кроме того, реальные шаги на некоторых машинах могут следовать в ином порядке.
1. Сохранить все регистры (включая PSW), которые еще не были сохранены аппаратурой, вызвавшей прерывание.
2. Установить контекст для процедуры обработки прерывания. Здесь может быть задействована установка TLB, MMII и таблицы страниц.
3. Установить стек для процедуры обработки прерывания.
4. Послать подтверждение контроллеру прерываний. В отсутствие централизованного контроллера прерываний разрешить прерывания.
5. Скопировать регистры из того мета, где они были сохранены (возможно, из какого-нибудь стека), в таблицу процессов.
6. Запустить процедуру обработки прерывания, которая извлечет информацию из регистров контроллера устройства, вызвавшего прерывание.
7. Выбрать следующий запускаемый процесс. Если прерывание привело к готовности какого-то ранее заблокированного процесса, имеющего высокий уровень приоритета, то теперь может быть выбран запуск именно этого процесса.
8. Установить контекст MMU для следующего запускаемого процесса. Могут потребоваться и некоторые установки TLB.
9. Загрузить регистры нового процесса, включая его PSW.
10. Запустить выполнение нового процесса.

