Страдания по IRQ

Страдания по 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 — один (обычно первый) восьмибитный, а второй — шестнадцатибитный.

Правильная установка плат расширения

Перед тем как установить систему, нужно правильно расположить платы расширения в слотах материнской платы.
Дело здесь в реализации прерываний на шине PCI.
Хотя PCI-устройства теоретически удобнее и производительнее, чем их ISA-собратья, архитектура шины PCI имеет некоторые ограничения.
В отличие от шины ISA, где для запроса на прерывание разведено 11 контактов, на шине PCI под эти нужды отведено только четыре.
Но реализация ответа на прерывание у этих шин тоже разная — на ISA-шине прерывание может вызвать только одно устройство (когда сигнал изменяется с «0» на «1»), а на PCI запросом на прерывание служит сигнал со значением «0».

Это значение выставляется всегда, когда хотя бы одно из устройств генерирует IRQ, так как запросы со всех устройств объединены логически (операция «И»).
Итак, если сигнал на шине «0» — значит, кто-то хочет что-то сказать, — думает контроллер, после чего начинает опрашивать устройства на предмет «че надо?».
Если какое-то устройство, шаркаясь и слюнявя платок, говорит, что оно хотело бы пообщаться, контроллер успокаивается и вызывает нужную подпрограмму.

В спецификации PCI говорится о том, что устройства должны уметь работать с разделяемыми прерываниями и уметь правильно отвечать контролеру на его «че надо?».
Однако далеко не все они могут нормально работать, встраиваясь в цепочку опроса по одному прерыванию.

Дело в том, что после появления спецификации PCI версии 2.1 сигналы (INT A, INT B, INT C, INT D) стали перераспределяться следующим образом: сигнал INT A на первом слоте автоматически становится INT B на втором, INT B становится INT C, и так далее.
То есть, для корректной работы четырех устройств, использующих одно прерывание, этой схемы более чем достаточно, но вот если устанавливается дополнительный PCI или AGP-слот, то связка между некоторыми слотами уже происходит не со смещением (INT A —> INT B), а напрямую (INT A —> INT A).

Это приводит к тому, что устройствам приходится работать на одном и том же прерывании.
А так как контроллер опрашивает таким образом установленные платы расширения поочередно, то они должны уметь правильно отвечать на вопросы контроллера.
Мало того, иногда PCI -устройства используют несколько прерываний, что сказывается на последующих слотах расширения, так как сигнальные линии у них все равно связаны.
К сожалению, не все производители печатают платы и пишут драйвера, учитывая эти особенности — а к чему это ведет, мы с вами знаем.

Чтобы разобраться, в какие слоты лучше всего установить платы, нужно знать, какие слоты «висят» на одном и том же прерывании.
К сожалению, обычно это не пишут в документации к материнской плате, но чаще всего это 3-ий и 4-ый, а также 5-ый и 6-ой PCI-слоты.
Отсюда следствие — не стоит устанавливать капризные устройства в эти слоты.
Лучше всего, если на каждой такой паре будет висеть не более одного девайса.
Естественно, если у вас на первом слоте висит устройство, использующее одно прерывание, а на втором — плата, требующая два IRQ, поменяйте их местами, так как при сдвиге INT A первой платы перейдет в INT B второй платы, которая также его будет активно использовать.

Вообще, довольно трудно угадать, какие именно слоты спарены по прерываниям, поэтому чаще всего это проверяется методом «научного тыка» (простой способ — посмотреть на список устройств и прерываний, который выводит BIOS перед загрузкой системы).
Допустим, с расположением плат в слотах материнской платы у вас все в порядке.
Следующий этап — настройка BIOS.
Главное - выкинуть все лишнее и оставить только самое необходимое.

Освобождаем прерывания

Сначала ищем PS/2 Mouse Function Control (контроль порта мыши PS/2).
Если у вас стоит COM или USB-мышь, то смело отключайте (Disabled) или ставьте в Auto — система сама разберется, резервировать ли прерывание IRQ 12 для мыши PS/2.
Далее пристально смотрим на Onboard FDC Controller (контроллер FDD) — если отключить (Disabled), то вкупе с параметром Report No FDD For WIN 95 (cказать Windows, что флоппоглота нет) освободится прерывание IRQ6.
Стоит сделать, если FDD — абсолютно ненужная вещь в вашем компьютере или его вообще нет.
Настройки Parallel Port Mode (ECP+EPP) и ECP DMA Select отвечают за режим работы параллельного порта.
Если вы его не используете, поставьте первое значение в Normal или попробуйте во второй настройке выбрать Disabled — освободится один канал DMA, а то и целое прерывание IRQ7.

С контроллером жесткого диска можно поступить так же жестко, как и с FDC — в настройке Onboard PCI IDE Enable выберите только тот канал, на котором висят устройства.
Если у вас стоит два диска или диск и CD-ROM, подключите их к одному каналу (это скажется на производительности, но освободит прерывание).
В зависимости от выбранного канала освободится прерывание IRQ14 или IRQ15.
В опции PCI IDE IRQ Map to можно также заставить BIOS отдать прерывания IDE-контроллера шине ISA — но, как правило, это совсем тяжелый случай.

Также иногда встречается опция PCI Slot IDE 2nd Channel (управление вторым каналом контроллера PCI IDE), которая позволяет запретить второй канал IDE-контроллера и освободить прерывание.
В случае, если USB-устройств у вас нет, смело выключайте USB IRQ (прерывание шины USB) — IRQ10 будет свободно как никогда.
Также иногда можно встретить Assign IRQ for VGA.
Если ваша карта способна работать без прерывания (а таких сейчас много) — смело отключайте (Disable).

Настраиваем чипсет

Главное — не гнаться за скоростью.
Часто бывает так, что одна карта работает хорошо с некоторыми настройками чипсета, а другая вообще с ними не живет.
Чтобы не рисковать, отключаем Snoop Ahead (потоковый обмен данными между PCI и памятью), Host Bus Fast Data Ready (быстрая готовность данных на шине), Spread Spectrum Modulated (уменьшение электромагнитного излучения), так как некоторые устройства это не любят.
С параметром PCI 2.1 Support (спецификации PCI версии 2.1) надо быть осторожным — так как мост PCI — PCI, позволяющий вешать на материнскую плату более 4-х устройств, в случае выбора Disabled работать не будет в принципе, хотя для достаточно старых плат это может помочь.

Дырку внутри 15-го мегабайта памяти (Memory Hole At 15M-16M) стоит разрешать только в том случае, если в описании к устройству черным по белому написано, что без нее оно работать не будет или будет работать очень медленно.
Следует поэкспериментировать с Peer Concurrancy (параллельная работа нескольких устройств на шине PCI) — зачастую именно этот параметр может повлиять на работу устройств с shared IRQ.
Если у вас есть плата ISA, активно работающая с DMA, то нужно будет выключить Passive Release (параллельная работа шин ISA и PCI).

Если ваша материнская плата не поддерживает спецификацию PCI версии 2.1, то параметр PCI Delayed Transaction (использование 32-битного буфера для удлиненного цикла обмена на шине PCI) нужно отключить.
Таймер задержки для устройств на шине PCI (PCI Latency Timer) определяет максимальное количество тактов шины, в течение которых любое устройство может удерживать шину от доступа к ней других устройств.
Этот параметр зависит от материнской платы, но иногда его увеличение способствует увеличению стабильности работы девайсов в ущерб производительности.

PnP мучения

Смотрим на параметр PNP OS Installed (взваливание всех проблем по распределению ресурсов на BIOS или ОС).
Если выбирается Yes, то BIOS предоставляет операционной системе все геморрои по настройке плат расширения, а если No, то этим будет заниматься сам BIOS.
Далее следует настройка Resources Controlled By (метод управления ресурсами).
Если стоит Auto, то BIOS сам назначит прерывания и каналы DMA всем PCI-устройствам.
Для наших мытарств лучше всего поставить значение Manual, то есть ручная настройка всего, чего только можно.
Иногда в этом параметре можно выбирать метод управления ресурсами для каждого PCI-слота.
После того, как вы выбрали ручную настройку, появятся много других опций, но о них позже, а сейчас посмотрим на опцию Reset Configuration Data (сброс данных конфигурации).

Когда все нормально — лучше поставить в Disabled, но если система после мягкой перезагрузки не может правильно «отконфигурить» устройства — то ставьте в Enabled, и BIOS будет очищать область ESCD (Extended System Configuration Data — расширенные данные конфигурации системы).
Далее, если вы выбрали ручную настройку прерываний и каналов DMA, идет список прерываний, а в возможностях выбора — типы устройств.
Выглядит это как IRQ n Assigned to (прерывание номер такое-то принадлежит …), а выбрать можно из Legacy ISA (обыкновенные ISA карты без поддержки PnP) или PCI/ISA PnP (PCI или ISA-устройства с поддержкой PnP).
Если поддержка ISA PnP у карты выполнена очень слабо или «криво», есть возможность выставить прерывания и каналы DMA вручную — лучше попросить BIOS не трогать это прерывание.

Для этого напротив данного прерывания выбираем значение Legacy ISA.
Аналогом этой опции является параметр IRQ n Used By ISA, где для того, чтобы запретить BIOS самостоятельно настраивать карту, нужно поставить «Yes», а чтобы разрешить — значение No/ICU.
Практически тот же смысл, только по отношению к каналам DMA, имеет настройка DMA Assigned to (назначить канал DMA на следующий тип устройств …) и ее аналог DMA Used By ISA.
После настройки вереницы прерываний вас недружелюбно встретит пункт PCI IRQ Activated by (механизм активации прерываний).
Возможные варианты — Level (реакция на уровень сигнала) или Edge (реакция на перепад сигнала).

Как мы уже разбирали в теории, для устройств на шине PCI по спецификации предусмотрено, что контроллер реагирует на уровень сигнала, так что если хотите, чтобы все работало так, как надо — лучше оставьте значение Level.
Если заставить контроллер реагировать только на перепад сигнала (Edge), то, возможно, произойдет неверная по приоритетам обработка прерываний, а также велика вероятность потери некоторых вызовов IRQ, особенно если в системе стоит больше одного PCI-устройства.
Естественно, если к документации к вашему девайсу четко написано, что лучше поставить Edge, то выбора у вас нет.

Далее идет еще один важный параметр — базовый адрес блока памяти для ISA-устройств (ISA MEM Block BASE) и его размер (ISA MEM Block SIZE).
Адрес памяти можно выбрать из значений.
Далее идет еще один важный параметр — базовый адрес блока памяти для ISA-устройств (ISA MEM Block BASE) и его размер (ISA MEM Block SIZE).
Адрес памяти можно выбрать из значений C800, CC00, D000, D400, D800 и DC00 , а размер блока — 8 кб, 16 кб, 32 кб, 64 кб.
В любом случае, этот параметр нужен для тех карт, которые имеют на борту свою память и требуют, чтобы доступ к ней осуществлялся именно по этим адресам.

После того, как вы настроили BIOS, пора заняться инсталляцией ОС и установкой плат расширения.
Для начала лучше всего поставить Windows на «голую» машину — вообще безо всяких дополнительных плат расширения.
Даем системе нормально загрузиться, заходим в Device Manager, смотрим на устройства — все нормально.
Теперь нужно воткнуть самую капризную плату расширения - так шанс занять нужное прерывание, канал DMA и адреса ввода-вывода на «голой» машине будет самым высоким.
Тут уж придется потрудиться на славу — перелопачивание BIOS, установка платы в разные слоты, а также настройка системы в области распределения прерываний и методов работы с шиной PCI в целом.

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

Часто проблема решается так: перед тем, как Windows начнет определять состав внутренностей компьютера (при установке системы), или перед тем, как поставить драйвера, карта инициализируется в «голом» DOS, после чего производится мягкая перезагрузка, а уж потом — установка драйверов.
Бывает такое, что драйвер может установиться только после того, как поставили специализированное программное обеспечение, прилагаемое к устройству.
Этот тип установки драйверов особенно распространен у сканеров.

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

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

Допустим, битва с первой платой завершена.
Теперь попробуйте поиграть с ее настройками и посмотрите и запишите, на каких прерываниях плата может работать, какие адреса ввода-вывода и каналы DMA может использовать.
Это вам пригодится при установке следующих плат.
Кстати, следует посмотреть, можно ли как-то еще освободить ресурсы системы.
Например, SB Live! по умолчанию ставит поддержку SB16 в DOS- играх, что нужно далеко не каждому.
Этим самым занимается один IRQ, два канала DMA и еще несколько портов ввода-вывода.
Если вам это не нужно — просто поставьте Disabled в свойствах Creative SB16 Emulation.

Иногда плата умеет очень многое из того, что вам попросту не нужно — попробуйте отключить те ресурсы (если вы знаете о них точно), которые отвечают за необязательные для вас функции.
Бывает, что производители предусматривают такую возможность прямо в драйверах, а в вариантах настроек, кроме различных номеров IRQ и DMA, учитываются возможные функциональные ограничения; то есть, отключены некоторые функции и связанные с ними ресурсы.
Этот метод предпочтительнее, нежели ручная настройка.

С первой платой покончено, смотрим на оставшиеся и читаем документацию.
Если есть плата, которая работает только с фиксированными значениями IRQ, DMA и адресами, то лучше начать с нее.
Ставим ее на место, загружаемся и пытаемся проинсталлировать драйвера.
Если это не получается, и карта не встает ни в какую, сначала смотрим на конфликты в Device Manager.
Если конфликты с первой картой — пытаемся посмотреть, можно ли изменить данный ресурс у первой карты.
Допустим, ничто уже не конфликтует, а карта все равно не работает.
Делаем финт ушами — резервируем ресурсы первой платы, вынимаем ее и вставляем вторую карту.

Если она все равно не работает, постепенно освобождаем по одному зарезервированному ресурсу и смотрим, стала ли плата работать.
Допустим, вы нашли тот ресурс, который каким-то образом влияет на вторую карту, но напрямую (во всяком случае, по версии Windows) она его не использует.
Здесь уже проблему стоит искать в BIOS, разводке слотов PCI или же в драйверах материнской платы.
Обычно проблемы при установке нескольких PCI-плат можно встретить на материнских платах, построенных на старых чипсетах от VIA, SIS и ALI.

Тут уже придется лезть на сайт производителя чипсета и скачивать новые драйвера, причем их установка — дело не такое простое, как может показаться сначала.
Главное — порядок, в котором производится установка драйверов оборудования и чипсета.
Так как угадать правильную последовательность непросто, вам придется прилично поругаться.

Установка драйверов тоже таит в себе массу неприятностей.
Иногда Windows решает, что ей ну просто необходим диск с дистрибутивом системы, и начинает плеваться разношерстными сообщениями.
Причем делает это так искусно, что иногда приходится по несколько минут вчитываться, чтобы понять, что подразумевает Windows под «Yes», «No», «Ignore» и «Cancel», так как каждый раз она может иметь в виду совсем разные действия.
И вот нажмешь случайно не ту кнопку, драйвер встанет как-нибудь криво, а потом ничего не заметишь.
Бывает еще противнее — драйвер встанет, но вот только работать нормально не будет, а при попытках его переустановить система будет брыкаться и автоматически ставить уже установленный где-то в системе драйвер этого устройства.

Наилучший вариант — использовать продвинутые деинсталляторы или специальные программы, которые сохраняют образ системы.
Наихудший — использовать отростки плеч, то есть руки.
Чтобы система опять прикинулась девственницей и сказала, что этот тип устройства она не знает, нужно найти тот INF-файл (а лежат они, как правило, в спрятанной директории INF, что в каталоге Windows) и просто его удалить.
А заодно и отправить в корзину все новые файлы, которые появились с новым драйвером, чтобы система не мучила вас сложными вопросами.
Теперь инсталляцию драйвера можно провести сызнова.

Наверное, вам показалось, что разрешение конфликтов — смертельно опасная вещь, и браться за нее нужно только с пакетом валерьянки, шаром для медитаций и с заземленными руками и ногами.
Это совсем не так.
Иногда достаточно всего лишь сесть на пол в позе лотоса и хорошенько загипнотизировать «мать» и все платы расширения, попеременно манипулируя перемычками и dip-переключателями.

Последний штрих — все вставить, включить компьютер, зайти в BIOS, поставить на него пароль с закрытыми глазами, а потом смело звонить знакомому компьютерному гуру с просьбой разблокировать систему — ведь до всего остального он «дозреет» сам, не правда ли?

Автор: Андрей Забелин