Страдания по IRQ
Начнем с понятия «прерывание».
Прерывание — это событие, которое говорит системе, что что-то произошло, и требует вмешательства.
Такими событиями могут быть: нажатая клавиша на клавиатуре, сигнал от модема, всевозможные ошибки (вроде деления на нуль) и тому подобное.
Как вы наверняка уже слышали, существуют аппаратные и программные прерывания.
Аппаратные (IRQ — Interrupt ReQuest) — те, которые инициируются железом, а программные — софтом, причем механизмы вызова аппаратного или программного прерывания немного различаются, хотя для процессора это в принципе одно и то же.
С программными прерываниями (INT — Interrupt) просто - программа вызывает запрос на прерывание (на языке ассемблера это INT xx, где xx — номер прерывания), после чего процессор сохраняет адрес возврата в программу и флаги состояния процессора, и переходит к обработчику прерывания.
Найти адрес программы-обработчика процессору очень просто (даже думать не приходится) — первый килобайт оперативной памяти содержит адреса этих программ.
Адрес обработчика нулевого прерывания (прерывания нумеруются с нуля) расположен в самом начале, сразу за ним — адрес обработчика первого прерывания, и так далее до 255-го прерывания.
Выход из обработчика прерывания производится программой-обработчиком, причем управление передается команде, следующей за процедурой вызова прерывания.
Аппаратные прерывания организуются немного сложнее — у каждой шины (PCI, ISA и т. д.) существуют определенные линии (читай — контакты), которые отвечают за прерывания, вызываемые устройствами.
Номера аппаратных прерываний не прямо соответствуют адресам программных, то есть аппаратному IRQ 0 соответствует INT 8, и так далее по таблице.
Зачем, спрашивается, нужны эти IRQ?
Во-первых - постоянно опрашивать все устройства на предмет «а не желаете ли Вы нам что-нибудь этакое передать?» просто непозволительно с точки зрения производительности.
Процессор просто утомится это делать — гораздо легче дать устройству какие-то права, и пусть оно командует.
Во-вторых, сам механизм позволяет программам и процессору абсолютно наплевательски относиться ко всем выступлениям со стороны устройств.
То есть программа даже не замечает, что, пока она работала, произошло 843 IRQ от жестких дисков, клавиатуры, таймера и прочего неотъемлемого барахла из мира внутренностей компьютера.
К тому же, очень важен тот факт, что устройство теоретически может быть обслужено именно в тот момент, когда оно готово что-то сделать или что-то сообщить системе.
Представьте себе, что на двух разных прерываниях «висят» два устройства - радар слежения за ракетами дальнего действия и чайник.
И вдруг они одновременно вызывают свои прерывания.
Что важнее для вас — чайник или сноп ракет, который может через минуту опуститься вам на голову?
То-то же!
Для разрешения таких ситуаций и существует система приоритетов, исходя из которых процессор выбирает, какое прерывание ему обслужить в первую очередь.
Вот список аппаратных прерываний, которые обычно используются в системе, которая не настроена каким-то особым образом:
• 0 (INT 08h) — системный таймер
• 1 (INT 09h) — контроллер клавиатуры
• 2 (INT 0Ah) — сопряжен с видеокартой на XT; на AT и выше используется для каскадирования второй микросхемы контроллера прерываний
• 3 (INT 0Bh) — стандартный для COM2/COM4
• 4 (INT 0Ch) — стандартный для COM1/COM3
• 5 (INT 0Dh) — обычно свободен, но на XT на этом IRQ находился контроллер жесткого диска
• 6 (INT 0Eh) — контроллер FDD
• 7 (INT 0Fh) — прерывание параллельного порта (LPT), однако многими LPT-контроллерами не используется
• 8 (INT 70h) — часы реального времени (RTC — Real Time Clock), прерывание вызывается 18,2 раза в секунду
• 9 (INT 71h) — эмуляция IRQ2 (для совместимости)
• 10 (INT 72h) — свободен
• 11 (INT 73h) — свободен
• 12 (INT 74h) — контроллер PS/2 мыши
• 13 (INT 75h) — математический сопроцессор
• 14 (INT 76h) — первый канал контроллера IDE HDD
• 15 (INT 77h) — второй канал контроллера IDE HDD
Что же это за звери — IRQ2 и IRQ9, которые связаны каким-то непонятным образом?
Дело в том, что на компьютерах XT (помните еще такие?) была всего одна микросхема, отвечающая за обработку аппаратных прерываний.
Возможности этой микросхемы были, мягко скажем, скудны — она могла обслуживать только аппаратные прерывания.
Но в нее был заложен потенциал — при каскадировании одного из прерываний на другую микросхему можно было подключить еще несколько таких наборов логики, и на компьютерах IBM AT таких микросхем было уже две, а аппаратных прерываний — 16.
Так как доступ ко второй микросхеме на аппаратном уровне осуществлялся через IRQ 2 первой (мост IRQ2-IRQ9), то использование в своих нуждах IRQ 2 или IRQ9 имело ряд особенностей.
Когда устройство, работающее на IRQ2, вызывало прерывание, новая логика AT аппаратно отправляла его на IRQ9, после чего BIOS, в свою очередь, перенаправлял сигнал на IRQ2 — чтобы программное обеспечение, рассчитанное на работу с IRQ2, имело возможность нормально работать с девайсом.
Именно поэтому в современных материнских платах, где вся логика работы с аппаратными прерываниями уже встроена в чипсет, для совместимости со старым программным и аппаратным обеспечением оставлен тандем IRQ2-IRQ9.
Сейчас можно совершенно спокойно использовать IRQ9 в своих целях.
Ну, хорошо, получили мы сигнал о том, что устройство нам что-то желает поведать, а дальше-то что?
Ведь нужно данные получить и как-то обработать.
Для этого организуется участок оперативной памяти, в котором устройство располагает данные для обработки, а драйвер, соответственно, ими оперирует.
Обычно эту область памяти называют адресами ввода-вывода.
Для того, чтобы не загружать каждый раз процессор передачей данных от устройства к памяти, используется DMA (Direct Memory Access - прямой доступ к памяти).
Передача данных ведется по так называемым каналам, которых всего семь:
• 0 — используется для регенерации памяти в некоторых системах
• 1 — свободен
• 2 — обслуживает контроллер FDD
• 3 — свободен (на XT - контроллер жесткого диска)
• 5 — свободен
• 6 — свободен
• 7 — свободен
Следует учитывать, что каналы 0-3 — восьмиразрядные, а каналы 5-7 — шестнадцатиразрядные.
Именно поэтому старый добрый SB 16 требовал два канала DMA — один (обычно первый) восьмибитный, а второй — шестнадцатибитный.