Сколько портов процессора необходимо выделить одному контроллеру прерываний i8259
Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно.
Необходимо обновить браузер или попробовать использовать другой.
Прерывания в защищенном режиме процессора IA-32
Прерывания в защищенном режиме процессора IA-32 — Архив WASM.RU
Вообщем-то на написание этой статьи меня толкнула незавершённость цикла статей http://www.wasm.ru/series.php?sid=20 «Процессор Intel в защищенном режиме». К сожалению, автор не успел рассмотреть детально сам процесс переключения режимов, смены адресации, а так же обработку прерываний, без которой невозможна полноценная работа программы в защищенном режиме. Писать мы будем код для транслятора FASM, сгенерируем чистый бинарный файл и используем его как образ загрузочной дискеты в эмуляторе Bochs или запишем на дискету и загрузим с нее реальный компьютер.
После Power-On-Self-Test процессор генерирует прерывание 19h, обработчик которого управляет дальнейшим ходом загрузки. Он находит первый (в порядке приоритетов, устанавливаемых в BIOS Setup) загрузочный диск, считывает его первый сектор по линейному адресу 07C00 и передает ему управление.
Поскольку процессор при загрузке работает в реальном режиме с 16битной адресацией, нашей задачей будет переключение процессора в защищенный режим с 32битной адресацией, установка обработчиков прерываний и считывание символов с клавиатуры. Так же мы рассмотрим процесс переключения из защищенного режима обратно в реальный.
Итак, сначала некоторые подготовительные действия. Поскольку наше тело загрузят по адресу 7C00 и мы вряд ли уместимся в пределы одного сектора (512 байт), надо обеспечить загрузку всего остального кода с диска. Этот код приведу без дополнительных пояснений, потому что он не совсем в тему нашей статьи:
Теперь в памяти аккуратно распологается весь наш код. Далее нам необходимо включить отключенные (опять же для совместимости) адресные линии, потому что после включения компьютера функционируют только адресные линии A0-A19. Для использования полноценной 32битной адресации нам нужно включить адресную линию A20, установкой бита 1 на порту ввода-вывода 92h:
На время переключения режимов обязательно надо отключить все прерывания, ибо первый же тик таймера свалит нашу систему. Мы отключим не только аппаратные прерывания, но и замаскируем NMI установкой 7-го бита (отсчет веду с нулевого, как всегда; по счету он, конечно, восьмой) в порту 70h:
Далее нам необходимо построить GDT и IDT. Если с GDT все понятно, то про IDT стоит рассказать подробнее. И в реальном и в защищенном режиме в регистре IDTR процессор хранит адрес и лимит таблицы прерываний.
В реальном режиме база IDTR = 00000h, а лимит — 3FFh (размер 400h байт минус еденица). По адресу 00000 находится так называемая таблица векторов прерываний (Interrupt Vector Table), состоящая из 256 векторов. Каждый вектор содержит смещение и сегмент своего обработчика. Обе компоненты занимают 2 байта, таким образом общий размер таблицы составляет 256*2*2 = 1024 = 400h байт.
В защищенном режиме дело обстоит совершенно по-другому. IDTR должен указывать на так называемую дескрипторную таблицу прерываний (Interrupt Descriptor Table, IDT), состоящую из 8байтных дескрипторов для каждого прерывания, которая может содержать шлюзы задачи, прерывания и ловушки. Мы рассмотрим только шлюз прерывания.
Шлюз прерывания описывается следующей структурой:
Как нетрудно заметить, его формат напоминает дескриптор из GDT/LDT, но есть некоторые изменения. Первое и последнее слова дескриптора шлюза прерывания содержат 32битный адрес обработчика прерывания (зеленое поле «смещение» на картинке). Второе слово содержит селектор сегмента кода, где находится код обработчика. Из дескрипторов сегмента унаследованы только следующие биты:
P (Present) — бит присутствия. Если =1, прерывание обрабатывается, если =0 генерируется исключение общей защиты. DPL (Descriptor Privilege Level) — уровень привилегий, о нем позже. D — разрядность.
При генерации прерывания происходит следующее. Из IDTR извлекается база таблицы дескрипторов прерываний. В этой таблице по номеру прерывания находится дескриптор шлюза прерывания. Если его бит Present сброшен, генерируется исключение общей защиты. Если текущий уровень привилегий отличается от уровня привилегий обработчика, происходит переключение стека и в стеке обработчика сохраняется указатель на стек прерванной задачи (SS и ESP). В стек помещаются регистры EFLAGS, CS, EIP. Для некоторых исключений последним в стек помещается еще и код ошибки, который, кстати, должен вытолкнуть обработчик исключения после обработки. Очищается бит TF, для программного прерывания или исключения сбрасываются биты VM, RF и NT. При вызове обработчика через шлюз прерывания очищается бит IF, блокируя дальнейшие маскируемые аппаратные прерывания.
После обработки прерывания обработчик должен вытолкнуть из стека код ошибки, если он там есть, и выполнить инструкцию IRETD, которая восстанавливает регистр флагов из стека (поле IOPL меняется, если CPL=0, IF меняется, если CPL to clear display» на экране:
Далее ставим положение последующего вывода строк на 160 (третья строчка экрана) и переходим в бесконечный цикл ожидания прерываний:
Теперь рассмотрим наши обработчики. Начнем с простого — системный сервис INT 1:
Я думаю, ничего пояснять не надо ) Кроме того, что селектор ES у нас по-прежнему должен указывать в сегмент видеобуфера.
Далее обработчик #GP — покажем злостные ругательства и возвратим управление. Стоит заметить, что управление возвращается на ту же инструкцию, которая и вызвала исключение. Не забываем так же вытолкнуть из стека 4х байтный код ошибки.
Далее мы напишем обработчик IRQ0 от системного таймера. Мы будем инкрементировать байт ES:[0], который является самым первым байтом видеобуфера и будет отображаться в левом верхнем углу экрана:
Где int_EOI — наш «ничегонеделающий» обработчик, который просто сбрасывает заявку в контроллере прерываний.
Рассмотрим подробнее аппаратные прерывания. В компьютере есть программируемый контроллер прерываний, котогрый тесно взаимосвязан с процессором:
При возникновении аппаратного прерывания инициируется выход #INT контроллера. Он напрямую соединен с входом #INTR процессора. Если флаг IF=0, прерывание отбрасыватеся. Процессор опрашивает вход #INTR после выполнения каждой инструкции. Как только обнаруживается сигнал, процессор сразу же подтверждает прерывание через выход #INTA. Контроллер прерываний принимает сигнал INTA и выставляет на шину данных значние номера прерывания. Процессор считывает номер прерывания и входит в прерывание по описанной выше схеме. Контроллер прерываний 8259A имеет восемь входов IRQ0-IRQ7, открытых для внешних источников, выход INT и вход INTA, соединенные с #INTR и #INTA входом и выходом процессора соответственно. При получении внешнего прерывания на шине данных формируется номер прерывания из суммы IRQ-номера входа и некоторого базового значения, которое обычно равно восьми, а в защищенном режиме придется базу сдвинуть до 20h, как именно — смотри ниже. Таким образом, при получении сигнала на входе IRQ0 генерируется прерывания 8 (у нас будет 32), IRQ1 — 9 (33) и так далее.
При поступлении нескольких заявок от разных источников они обрабатываются по порядку начиная с меньшего номера IRQ. Можно также выборочно заблокировать некоторые заявки от отдельных IRQ-входов. Блокировку, или маскирование заявок, а так же выбор заявки с наибольним приоритетом обеспечивают три байтовых регистра контроллера — interrupt Mask register (iMr), interrupt Request register (iRr), interrupt Service register (iSr) и арбитр приоритетов Page Resolver (PR).
Каждый вход IRQ блокируется отдельным битом регистра масок iMr. Если прерывания на входе IRQn разрешены, бит n регистра iMr сброшен. Регистр маски iMr подключен к порту 21h процессора.
Пусть поступление запросов на вход IRQn разрешено — бит n регистра iMr сброшен. Бит n регистра запросов на прерывание iRr установится, когда придет сигнал на вход IRQn. Арбитр приоритетов PR по значению регистра iSr принимает решение о возможности обслуживания запроса. Заявка может быть принята к обслуживанию, если в регистре iSr не зафиксировано заявок с равным или большим номером. Если все нормально, контроллер выставляет сигнал INT. Заявка принимается к обслуживанию при получении сигнала INTA от процессора, на шину данных выставляется номер прерывания, бит n регистра iRr сбрасывается, бит n регистра iSr устанавливается. Установленный бит n регистра iSr теперь блокирует прерывания от входов с номерами большими либо равными n. Блокировку необходимо снять вручную в процедуре обсдуживания прерывания сбросом бита x в регистре iSr, который подключен к порту 20h (нужно записать значение 3Nh, где N — номер входа). На практике обычно пользуются командой неопределенного сброса, реализуемой посылкой в порт 20h значения 20h. По этой команде в iSr сбрасывается заявка с наименьшим номером — которая обслуживается в данный момент как наиболее приоритетная.
8 входов слишком мало, поэтому чаще всего используются два контроллера прерываний 8259A — так называемые ведомый контроллер, выход INT которого подключен к входу IRQ2 ведущего контроллера, который уже в свою очередь общается с процессором. Это называется каскадным включением контроллеров прерываний. Регистр iMr ведомого контроллера доступен через порт 0a1h, а регистр iSr — через 0a0h.
Теперь стало ясно, как должен выглядеть минимальный обработчик внешних IRQ прерываний — посылка неопределенного сброса контроллеру прерываний обоим контроллерам:
Теперь рассмотрим обработчик прерывания IRQ1 от клавиатуры. Прерывание IRQ1 генерируется контроллером клавиатуры каждый раз при нажатии клавиши. Обработчику клавиатуры скан-код считанной клавиши доступен для чтения через порт 060h. Скан-код нужно преобразовать в соответствующий ему ASCII-код символа (если он печатаем) и отобразить на экране. Преобразование произведем по следующей таблице:
Эта таблица содержит символы, индексы которых в таблице соответствуют их сканкодам, либо нули, если символы непечатаемые. Поскольку нажатие клавиш Shift и Caps Lock мы не обрабатываем, поэтому регистр букв у нас различаться не будет. В нашем обработчике нам нужно проверить, нажата ли клавиша (Её скан-код равен еденице). Если это действительно так, то вызовем процедуру переключения в реальный режим и генерации там прерывания 10h для очистки экрана. Если это не так, отобразим символ на экране. В любом случае нужно перед сбросом заявки на прерывание в контроллере прерываний послать подтверздение обработки прерывания контроллеру клавиатуры в порт 061h — необходимо установить и сразу сбросить 7 бит этого порта. После чего необходимо сбросить заявку на прерывание и вернуть управление:
Сколько портов процессора необходимо выделить одному контроллеру прерываний i8259

(Схема взята из руководства Intel)
INTERRUPT REQUEST REGISTER (IRR)
IN-SERVICE REGISTER (ISR)
INTERRUPT MASK REGISTER (IMR)
PRIORITY RESOLVER
INT (INTERRUPT)
INTA (INTERRUPT ACKNOWLEDGE)
A0
| Chip — Purpose | I/O port |
|---|---|
| Master PIC — Command | 0x0020 |
| Master PIC — Data | 0x0021 |
| Slave PIC — Command | 0x00A0 |
| Slave PIC — Data | 0x00A1 |
- Initialization Command Words (ICWs) — перед нормальной работой контроллер прерываний должен быть инициализирован (в зависимости от нужного режима) 2-4 байтной последовательностью.
- Operation Command Words (OCWs) — Командные слова, посылаемые в процессе работы. Могут посылаться когда угодно после инициализации.
Whenever a command is issued with A0 = 0 and D4 = 1, this is interpreted as Initialization Command Word 1 (ICW1). ICW1 starts the intiitalization sequence during which the following automatically occur
ICW1

(Картинка взята из руководства Intel)
| Chip — Purpose | I/O port |
|---|---|
| Master PIC — Command | 0x0020 |
| Master PIC — Data | 0x0021 |
| Slave PIC — Command | 0x00A0 |
| Slave PIC — Data | 0x00A1 |
- Стирается Interrupt Mask Register
- Линии прерываний IR7 присваивается приоритет 7.
- The slave mode address is set to 7
- Special Mask Mode is cleared and Status Read is set to IRR.
- Если IC4 = 0, тогда все функции указываемые в ICW4 устанавливаются в 0 (Non-Buffered mode*, no auto-EOI, MCS-80, 85 system)
ICW2

- Смещение векторов прерываний должно делиться на 8, так как 8259A использует младшие биты для конкретного вектора прерывания (0..7).
- Единственный способ изменить смещение векторов прерываний для контроллера 8259A — переинициализировать его.
- Если вы планируете вернуться в реальный режим из защищенного режим (для любых нужд), вы должны восстановить его предшествующую конфигурацию
ICW3

(Иллюстрация из документации Intel)
Детальная 8259А
Программируемый контроллер прерываний (PIC-Programmable Interrupt Controller) — менеджер управления запросами прерываний устройства в микрокомпьютерной системе. Когда PIC отправляет сигнал прерывания на вывод INT процессора, процессор немедленно останавливает то, что он делал, и спрашивает, какой запрос на обслуживание прерывания должен выполнить PIC. PIC сообщает процессору, какой процесс обслуживания прерываний следует выполнить, отправляя номер прерывания, соответствующий запросу прерывания, на шину данных. Процессор получает вектор прерывания соответствующего устройства (то есть адрес программы обслуживания прерываний), запрашивая таблицу векторов прерываний (таблицу дескрипторов прерываний в 32-битном режиме защиты) в соответствии с номером прерывания чтения и начинает выполнение программы обслуживания прерываний. Когда выполнение процедуры обработки прерывания заканчивается, процессор продолжает выполнять программу, прерванную сигналом прерывания.
Каскад 8259А
В микрокомпьютерной системе 80X86 используется программируемый чип контроллера прерываний 8259A. Каждый чип 8259A может управлять 8 источниками прерываний. Посредством многокристального каскадирования 8259A может сформировать систему, которая управляет до 64 векторами прерываний.
В совместимом компьютере серии PC / AT используются два чипа 8259A, которые могут управлять в общей сложности 15 векторами прерываний. Каскадная диаграмма выглядит следующим образом 
Среди них вывод INT подчиненного чипа подключен к выводу IR2 мастер-чипа, то есть сигнал прерывания, отправленный ведомым чипом 8259A, будет использоваться в качестве входного сигнала IRQ2 мастер-чипа 8259A.
Роль контакта IRQ9 такая же, как и для IRQ2, то есть компьютер PC / AT использует аппаратную схему для перенаправления контакта IRQ2 на вывод IRQ9 PIC и использует программное обеспечение в BIOS для перенаправления прерывания IRQ9 int 71 на прерывание IRQ2 int Обработка прерываний 0x0A. Таким образом, любая 8-разрядная карта конфигурации PC / XT, использующая IRQ2, все еще может нормально использоваться под машиной PC / AT, и ПК обратно совместим.
Зачем перенаправлять IRQ2 на IRQ9?
В раннем IBM PC / XT был только один 8259A, так что он мог обрабатывать только 8 IRQ. Но вскоре было обнаружено, что это вообще не может удовлетворить спрос, поэтому в случае IBM PC / AT дополнительно 8259A было добавлено каскадным способом, чтобы можно было обрабатывать 7 видов IRQ. Оригинальный 8259A называется Master PIC, а новый — Slave PIC. Однако, поскольку ЦП имеет только одну линию прерывания, подчиненный PIC должен быть каскадно подключен к главному PIC, занимающему IRQ2, тогда устройства, использующие IRQ2 на IBM PC / XT, больше не смогут его использовать, но новая система должна Что если система остается совместимой?
Поскольку недавно добавленная подчиненная PIC не существует в исходной системе, разработчик выбирает IRQ9 из IRQ ведомой PIC и просит разработчика программного обеспечения перенаправить исходный IRQ2 на IRQ9. Другими словами, подпрограмма обслуживания прерывания IRQ9 должна удалить подпрограмму обработки прерывания IRQ2. Таким образом, устройство, которое было первоначально подключено к IRQ2, теперь подключено к IRQ 9. В программное обеспечение необходимо добавить только подпрограмму обработки прерываний IRQ 9. Вызывая подпрограмму обработки прерываний IRQ2, она может быть совместима с исходной системой. В то время расширенная программа обслуживания прерываний IRQ9 была предоставлена BIOS, разработанным разработчиком ПК, и никаких дополнительных настроек пользователю не требовалось, поэтому совместимость была в основном гарантирована.
Принцип работы 8259А
Под управлением контроллера шины микросхема 8259A может находиться в состоянии программирования и в рабочем состоянии. Состояние программирования — это состояние, при котором процессор использует команды IN или OUT для инициализации и программирования микросхемы 8259A. Как только программирование инициализации завершено, микросхема переходит в рабочее состояние. В это время микросхема может в любое время ответить на запрос прерывания (IRQ0-IRQ15) от внешнего устройства. В то же время система может также использовать слово команды операции для изменения своего метода обработки прерывания в любое время. Посредством выбора арбитража прерывания микросхема выберет текущий запрос прерывания с наивысшим приоритетом в качестве объекта обслуживания прерывания и уведомит ЦПУ о запросе прерывания через контакт ЦП INT. После того, как ЦП ответит, микросхема запрограммирует данные с шины данных D7-D0. Номер прерывания текущего объекта обслуживания отправляется, и ЦПУ, таким образом, получает соответствующее значение вектора прерывания и выполняет процедуру обслуживания прерывания.
Логическая блок-схема микросхемы 8259A выглядит следующим образом: 
На рисунке регистр запроса прерывания IRR (регистр запроса прерывания) используется для сохранения всех запросов на входном выводе запроса прерывания. 8 битов регистра (D7-D0) соответствуют контактам IR7-IR0. Регистр маски прерывания IMR (регистр маски прерывания) используется для сохранения бита, соответствующего замаскированной строке запроса прерывания, а какой бит установлен в 1, будет маскировать уровень запроса прерывания. Таким образом, IMR обрабатывает IRR, и каждый бит соответствует каждому биту запроса IRR. Экранирование входных линий с высоким приоритетом не влияет на ввод строк запроса на прерывание с низким приоритетом. Приоритет распознавателя PR (Priority Resolver) используется для определения приоритета битов, установленных в IRR, стробирования запроса прерывания с наивысшим приоритетом в служебный регистр ISR (In-Service Register). Запрос на прерывание, который получает услугу, сохраняется в ISR.
Линии запроса прерывания от каждого устройства подключены к контактам IR0-IR7 8259A. Когда один или несколько сигналов запроса прерывания поступают на эти выводы, соответствующий бит в регистре IRR запроса прерывания устанавливается и фиксируется. В это время, если установлен соответствующий бит в регистре IMR маски прерываний, соответствующий запрос прерывания не будет отправлен анализатору приоритетов. После того, как немаскированный запрос прерывания будет отправлен распознавателю приоритетов, будет выбран запрос прерывания с наивысшим приоритетом. В это время 8259A отправит сигнал INT на ЦПУ, а ЦП отправит INTA (ПРЕРЫВАНИЕ ПРЕРЫВАНИЯ) на 8259A после ответа на текущую инструкцию, чтобы ответить на сигнал прерывания. После получения этого ответного сигнала 8259A сохранит запрос прерывания с наивысшим приоритетом, выбранный в регистре обслуживания ISR, то есть соответствующий бит в ISR установлен. В то же время соответствующий бит в регистре IRR запроса прерывания сбрасывается, указывая, что запрос прерывания был обработан. После этого CPU отправит второй импульсный сигнал INTA на 8259A, который используется для уведомления 8259A об отправке номера прерывания. Во время этого импульсного сигнала 8259A отправляет 8-битные данные, представляющие номер прерывания, на шину данных для чтения ЦПУ.
В этот момент цикл прерывания процессора заканчивается. Если 8259A использует метод автоматического завершения прерывания (AEOI), текущий бит прерывания обслуживания в регистре обслуживания ISR в конце второго импульсного сигнала INTA будет сброшен. Если 8259A использует неавтоматический метод завершения, то в конце процедуры обработки прерывания программа должна отправить 8259A команду завершения прерывания (EOI) для сброса битов в ISR. Если запрос прерывания поступает от каскадного второго чипа 8259A, необходимо отправить команду EOI на оба чипа. После этого 8259A будет оценивать следующее прерывание с наивысшим приоритетом и повторять вышеуказанный процесс.
8259A приоритет прерывания
Фиксированный приоритет
В режиме фиксированного приоритета приоритет прерывания IR7 ~ IR0 определяется системой. Порядок приоритета от высокого до низкого: IR0, IR1, IR2,…, IR7. Среди них IR0 имеет самый высокий приоритет, а IR7 имеет самый низкий приоритет.
Автоматический режим приоритета цикла
В режиме автоматического приоритета цикла уровень приоритета IR7 ~ IR0 может быть изменен, и он изменяется автоматически. Закон изменения: когда определенный запрос прерывания IRi После окончания обслуживания приоритет прерывания автоматически уменьшается до самого низкого, и запрос прерывания сразу же следует IR(i+1) Приоритет автоматически повышается до самого высокого.
Например, в исходном состоянии IR4 имеет запрос, ЦП завершил свою службу, приоритет IR4 автоматически уменьшается до самого низкого, а затем приоритет IR5 повышается до самого высокого. Глядя на картинку, нам станет понятнее: 
В начале приоритет от высокого до низкого IR0, IR1, IR2, …, IR7 , В определенный момент IR4 обрабатывается процессором. После завершения обработки приоритет IR4 становится самым низким, а приоритет IR5 становится самым высоким, то есть новая последовательность приоритетов от высокого к низкому IR5,IR6,IR7,IR0,IR1,IR2,IR3,IR4 .
В режиме автоматического приоритета цикла он делится наОбычная автоматическая циркуляция с Специальный метод автоматической циркуляции Два вида.
- Нормальный автоматический цикл: начальный самый низкий приоритет в IR0 ~ IR7 назначается системой, то есть самый низкий приоритет IR7 назначается.
- Специальный автоматический цикл: начальный самый низкий приоритет в IR0 ~ IR7 задается пользователем (через OCW2).
Вложенность прерываний
Методы вложенности прерываний 8259A делятся на обычные вложенные (обычный режим вложенности) и специальные полностью вложенные (специальный режим полного вложенности).
Обычное гнездование
Также называется полным вложением или обычным полным вложением. Этот режим является режимом по умолчанию, выбранным 8259A во время инициализации. Его характеристики: IR0 имеет самый высокий приоритет, а IR7 имеет самый низкий приоритет. В течение периода обслуживания прерывания ЦП, если поступает новый запрос прерывания, он может быть только выше текущего приоритета обслуживаниявысокаяЧтобы ввести запрос на прерывание, на «тот же уровень» или «низкий уровень» на запрос прерывания запрещено отвечать.
Специальное полное вложение
Его особенности: порядок приоритетов IR7
IR0 такой же, как и для обычного вложения; отличие состоит в том, что во время обслуживания прерываний ЦП, помимо разрешения ввода запросов прерываний высокого уровня, он также позволяет вводить запросы прерываний на том же уровне, тем самым достигая того же уровня. Специальная вложенность запросов на прерывание уровня.
В случае многочипового каскада 8259A мастер-чип обычно устанавливается в специальный полный режим вложенности, а подчиненный чип — в обычный режим вложенности. Когда главный чип отвечает на запрос прерывания от подчиненного чипа, все запросы от IR7 до IR0 в подчиненном чипе проходят через определенный чип в главном чипе. IRi Запрос был введен. Поэтому IR7 ~ IR0 ведомого чипа IRi Другими словами, они принадлежат одному и тому же уровню, и только когда главный слайс работает в специальном режиме полной вложенности, подчиненные слайсы могут быть полностью вложенными.

Насколько я понимаю, например: INT подчиненного чипа подключен к IR2 мастер-чипа. Предположим, что CPU отвечает на запрос прерывания подчиненного чипа IR4. Во время обработки прерывания приходит прерывание подчиненного чипа IR3, поэтому главный чип IR2 снова Запрашивая прерывание, теоретически приоритет подчиненного IR3 выше, чем IR4, что означает, что ЦП должен приостановить обработку прерываний подчиненного IR4 и обработать прерывание IR3 вместо этого. Однако IR0
IR7 ведомого слайса вводятся через IR2 главного слайса, поскольку ЦП обслуживает IR2 главного слайса. В это время IR2 снова запрашивает прерывание. Для обычного метода вложения ЦП не отвечает, поскольку он принадлежит к тому же уровню. Все IR2.
Если вы хотите вложить прерывание IR3 из среза в прерывание IR4 из среза, вам нужно, чтобы ЦП разрешил прерывания на том же уровне, поэтому задайте для основного среза специальный метод полного вложения. Таким образом, высокий приоритет подчиненного может быть «истинно» вложенным в низкий приоритет подчиненного.
Объяснение в книге таково: в специальном режиме полной вложенности, когда обрабатывается запрос на прерывание, отправленный со среза, подчиненный срез не будет исключен приоритетом главного среза. Следовательно, другие запросы прерываний с более высоким приоритетом, выданные ведомым устройством, будут распознаны ведущим, и мастер немедленно выдаст прерывание ЦПУ. В вышеупомянутом обычном способе вложения, когда запрос подчиненного прерывания обслуживается, ведомое устройство будет экранировано ведущим. Следовательно, запрос прерывания более высокого приоритета от подчиненного устройства не может быть обработан.
Метод маскировки прерываний
Метод маскирования прерываний — это метод управления прерываниями для экранирования внешних источников прерываний IR7 ~ IR0 8259 А. Существует два вида обычных методов экранирования и специальные методы экранирования.
Обычный метод экранирования
Запишите слово команды операции OCW1, регистр маски прерывания (IMR) Di Положение 1, чтобы достичь правого IRi ( i=0~7 ) Маскировка запроса прерывания.

Если Mi = 1, соответствующий уровень запроса прерывания заблокирован IRi Если Mi = 0, разрешить IRi Кроме того, маскирование высокого приоритета не влияет на другие запросы прерываний с низким приоритетом.
Специальный метод экранирования
Когда 8259A работает в специальном режиме маскирования, на все немаскированные запросы на приоритетное прерывание (более высокое и более низкое) можно ответить во время процесса прерывания, то есть прерывание с низким приоритетом может прервать высокоуровневое прерывание высокого уровня. Приоритетное прерывание.
В режиме специальной маскировки команда маски прерывания может использоваться в подпрограмме обслуживания прерываний для маскировки обрабатываемого в настоящее время уровня прерывания, и в то же время соответствующий бит в ISR может быть очищен. , А также действительно открывал запросы прерываний более низкого уровня. В этом случае, хотя ЦП продолжает выполнять подпрограмму обслуживания прерываний более высокого уровня, соответствующий бит в ISR очищен, как будто он не отвечает на прерывание. Следовательно, в это время ЦП может отвечать на запросы прерываний более низкого уровня.
Конец прерывания
Метод завершения прерывания означает, что ЦП должен сбрасывать бит флага обслуживания прерывания после обслуживания запроса прерывания, в противном случае это означает, что обслуживание прерывания продолжается, и на запрос прерывания с более низким приоритетом, чем он, не может быть дан ответ. Флаг обслуживания прерывания сохраняется в регистре обслуживания прерывания (ISR), когда источник прерывания IRi После ответа на Di Бит установлен в 1, и сервис должен быть очищен во времени. 8259A предоставляет три метода завершения прерывания.
Автоматический конец метода
Когда бит автоматического завершения прерывания (AEOI) в ICW4 установлен, бит флага обслуживания прерывания в ISR сбрасывается задним фронтом импульса INTA второго сигнала прерывания, выдаваемого ЦПУ. Этот метод прерывания обслуживания прерывания автоматически завершается аппаратным обеспечением.
Следует отметить, что очистка бита "1" в ISR завершается во время процесса ответа на прерывание, а не фактического завершения подпрограммы обслуживания прерывания. 8259A не сохраняет никакого флага, чтобы указать, что текущая услуга не завершилась. Существует запрос прерывания, и IF (x86 EFLAGS регистр b9, бит разрешения прерываний) = 1, независимо от его приоритета (Выше, ниже или такой же, как этот уровень), получит ответ, особенно когда ЦП отвечает на сигнал запроса прерывания, если он не отменен во времени, он будет снова отправлен (второе прерывание). Это может нарушить работу обслуживаемой программы. Следовательно, этот метод применим только тогда, когда длительность сигнала запроса прерывания ограничена и нет вложенности прерывания.
Обычный конец
Обычный метод завершения состоит в очистке приоритета в ISR путем программирования слова команды операции записи OCW2 в подпрограмме обслуживания прерываний и передачи 8259A команды обычного завершения прерывания (EOI, end of interrupt) (команда не указывает уровень прерывания, подлежащий сбросу). Самый высокий уровень установлен.
Поскольку этот метод завершения предназначен для сброса установки самого высокого уровня приоритета в ISR, он подходит для использования в полностью вложенном режиме. Поскольку в полностью вложенном режиме приоритет прерывания является фиксированным, 8259A всегда реагирует на прерывание с наивысшим приоритетом, и соответствующий бит с наивысшим приоритетом, сохраненный в ISR, должен соответствовать выполняемой сервисной программе.
Специальный конец
Специальный метод завершения — очистить указанный бит в ISR, запрограммировав слово команды операции записи OCW2 в подпрограмме обслуживания прерываний и передав специальную команду EOI на 8259A (команда указывает уровень прерывания, который должен быть сброшен).
В некоторых случаях порядок ответов на запросы прерываний не соответствует фиксированному приоритету. Например, когда 8259A работает в режиме специальной маскировки, прерывание с низким приоритетом может прерывать обслуживаемое прерывание с высоким приоритетом, а прерывание с высоким приоритетом также может прерывать обслуживаемое прерывание с низким приоритетом. В настоящее время его нельзя определить в соответствии с содержимым ISR. Прерывание только что обработано. Это требует сброса уровня прерывания в команде EOI.
Метод запуска прерывания
Входные клеммы IR7 ~ IR0 запроса прерывания 8259A могут запускаться двумя способами: триггером уровня и граничным триггером, которые задаются битом LTIM в командном слове инициализации ICW1.
Режим триггера уровня
Когда LTIM = 1, это режим запуска уровня. Когда 8259A обнаруживает IRi ( i=0~7 ) Прерывание генерируется, когда терминал имеет высокий уровень. В этом режиме запуска уровень запуска должен поддерживаться до тех пор, пока ответный сигнал прерывания INTA не станет действительным. После того, как процессор отреагирует на прерывание, он должен своевременно отменить сигнал запроса, чтобы процессор не ответил снова и не повторил прерывание.
Режим триггера
Когда LTIM = 0, это режим запуска по фронту. Когда 8259A обнаруживает IRi Когда на терминале есть сигнал перехода с низкого уровня на высокий (нарастающий фронт), генерируется прерывание.
Подключение к шине данных
Существует два способа подключения линии данных 8259A к системной шине данных: буферизованная и небуферизованная.

Метод буферизации
Если 8259A подключен к системной шине данных через драйвер шины, то следует выбрать метод буферизации. В это время EN является выходным контактом. Когда номер типа прерывания выдается 8259A, EN выдает низкий уровень и использует этот сигнал в качестве сигнала запуска драйвера шины.
В режиме буфера бит M / S ICW4 определяет, является ли 8259A ведущим или ведомым.

Unbuffered
Если линия данных 8259A напрямую подключена к системной шине данных, следует выбрать метод без буферизации. В это время SP является входным контактом, и его уровень используется для определения того, является ли 8259A ведущим (SP = 1) или ведомым (SP = 0).
В небуферизованном режиме значение ICF4 BUF = 0, а бит M / S не имеет смысла.

8259A программирование
Слово команды инициализации
Перед тем, как 8259A сможет нормально работать, вы должны сначала установить содержимое набора регистров командного слова инициализации ICW (слова команд инициализации).В ходе его работы вы можете использовать регистр командных слов операции записи OCW (Слова командных операций), установленный для установки и управления рабочим режимом 8259A в любое время.
Линия A0 используется для выбора регистра для работы. В микрокомпьютерной системе PC / AT, когда A0 = 0, адреса портов микросхемы равны 0x20 (главный чип) и 0xA0 (подчиненный чип), когда A0 = 1, порты составляют 0x21 (главный чип) и 0xA1 (подчиненный чип).
Процесс программирования слова команды инициализации показан на рисунке ниже. Из рисунка видно, что необходимы настройки для ICW1 и ICW2. И только необходимо установить ICW3, когда система содержит несколько микросхем 8259A и находится в каскадном режиме. Это должно быть четко указано в настройках ICW1. Кроме того, нужно ли указывать ICW4, также необходимо указать в ICW1.

Когда 5-й бит (D4) переданного байта = 1 и адресная строка A0 = 0, это означает, что ICW1 запрограммирован. В это время для многочипового каскада микрокомпьютерной системы PC / AT адрес порта мастер-чипа 8259A равен 0x20, а адрес порта подчиненного чипа — 0xA0.
Формат ICWl выглядит следующим образом:

Вот более краткая картина.

В ядре Linux-0.11 ICW1 имеет значение 0x11. Указывает, что запрос на прерывание инициирован по фронту, необходимо отправить несколько каскадов 8259A и ICW4.
ICW2 используется для установки верхних 5 цифр номера прерывания, отправляемого чипом. После настройки ICW1, когда A0 = 1, это означает установить ICW2. В это время для многочипового каскада микрокомпьютерной системы PC / AT адрес порта мастер-чипа 8259A равен 0x21, а адрес порта подчиненного чипа — 0xA1.
Формат ICW2 выглядит следующим образом.

В системе, использующей процессор 8086/88 или совместимую систему, T7
T3 являются старшими 5 битами номера прерывания, а младшие 3 бита автоматически устанавливаются микросхемой 8259A (8259A автоматически заполняется в соответствии с трехразрядным значением кода IR0 ~ IR7) для формирования 8 Номер прерывания бита. Когда 8259A получает второй импульс INTA ответа на прерывание, он отправляет этот номер прерывания на шину данных для чтения ЦПУ.

Система Linux-0.11 устанавливает ICW2 основного слайса равным 0x20, указывая, что номер прерывания, соответствующий уровню запроса прерывания основного слайса 0
0x27 Установите ICW2 ведомого чипа в 0x28, указывая, что соответствующий номер прерывания уровня запроса подчиненного прерывания 8

Адрес порта главной микросхемы равен 0x21, а адрес порта подчиненной микросхемы равен 0xA1.
Для основной части Si = 1 означает, что IRi Подключите к контакту INT ведомого. Проще говоря, это каскадные подчиненные слайсы, соответствующие битам главных слайсов S7
S0. То, какой бит равен 1, указывает, что сигнал на выводе IR запроса прерывания мастер-чипа поступает от подчиненного чипа, в противном случае соответствующий контакт IR не подключен к подчиненному чипу.
Для подчиненного чипа три бита ID2
ID0 соответствуют идентификационному номеру каждого подчиненного чипа, который подключен к уровню прерывания мастер-чипа. Когда ведомое устройство получает входное значение каскадной линии (CAS2-CAS0), равное его собственному ID2
ID0, это означает, что ведомое устройство выбрано. В это время ведомое устройство должно отправить номер прерывания текущего выбранного запроса прерывания на шину данных.
Ядро Linux-0.11 устанавливает ICW3 основного чипа 8259A в 0x04, то есть S2 = 1, а остальные биты равны 0. Контакт IR2 главного чипа подключен к подчиненному чипу. ICW3 ведомого чипа установлен на 0x02, то есть его идентификационный номер равен 2. Указывает, что это подчиненное устройство подключено к выводу IR2 ведущего устройства. Поэтому порядок приоритетов прерываний таков: уровень 0 — самый высокий, уровень 1 — второй, за ним следуют 8–15 уровней на подчиненном чипе и, наконец, 3–7 уровней мастер-чипа.
Когда бит 0 (IC4) ICW1 установлен, это означает, что ICW4 необходим. Адресная строка A0 = 1, адрес порта главной микросхемы равен 0x21, а адрес порта подчиненной микросхемы равен 0xA1.

Давайте сделаем еще одну краткую картину:

Значение командного слова ICW4, отправляемого ядром Linux-0.11 на главный и подчиненный чипы 8259A, составляет 0x01. Это означает, что микросхема 8259A настроена на обычный полностью вложенный не буферизованный неавтоматический режим конечного прерывания и используется в 8086 и совместимых системах.
Слово команды операции
После установки слова команды инициализации на 8259A микросхема готова принять сигнал запроса на прерывание устройства. Однако во время работы 8259A мы также можем использовать слова рабочих команд OCW1
OCW3 для контроля рабочего состояния 8259A или изменить режим работы 8259A, установленный при инициализации в любое время.
Следует отметить, что в отличие от командных слов инициализации ICW1-ICW4, которые необходимо установить в указанном порядке, установка командных слов операций OCW1-OCW3 не определяет порядок, и различные командные слова операций могут гибко выбираться в соответствии с потребностями во время использования. 8259A.
OCW1 используется для чтения / записи регистра IMR маски прерываний в 8259A. Адресная строка A0 должна быть 1.

Если Mi = 1, соответствующий уровень запроса прерывания заблокирован IRi Если Mi = 0, разрешить IRi Кроме того, маскирование высокого приоритета не влияет на другие запросы прерываний с низким приоритетом.
В процессе инициализации ядра Linux-0.11 код будет использовать слово команды операции для изменения соответствующего бита маски запроса прерывания после установки соответствующего драйвера устройства. Например, в конце инициализации драйвера дисковода гибких дисков, чтобы позволить устройству дисковода гибких дисков выдать запрос на прерывание, он прочитает порт 0x21, чтобы получить текущее слово маски чипа 8259A, а затем
0x40 Сбросить M6 (Контроллер дискеты подключен к запросу прерывания IR6) и, наконец, выполняет запись обратно в регистр маски прерывания

| Немного | имя | смысл |
|---|---|---|
| 7 | R | Установлен ли приоритет прерывания циклически. R = 1 означает использование циклического режима, R = 0 означает использование ациклического режима. |
| 6 | SL | Действительны ли L2 |
OCW2 Commands
| R | SL | EOI | Приоритетное управление | Конец прерывания |
|---|---|---|---|---|
| 0 | 0 | 1 | Фиксированный приоритет | Генеральный ВЗ |
| 0 | 1 | 1 | Фиксированный приоритет | Специальный ВЗ, ISR(L2 |
Ядро Linux-0.11 использует это командное слово только для отправки команды конечного прерывания (EOI) на 8259A до окончания процесса обработки прерывания. Используемое значение OCW2 составляет 0x20, что означает фиксированный приоритет и общий EOI (соответствующий первой строке приведенной выше таблицы).
OCW3 используется для установки или сброса режима специальной маски и считывания статуса регистра (IRR и ISR). Когда D4D3 = 01 и адресная строка A0 = 0, это означает программирование OCW3. Это командное слово операции не используется в ядре Linux-0.11.

| Немного | имя | смысл |
|---|---|---|
| D7 | — | Константа 0 |
| D6 | ESMM | SMM включить бит. ESMM = 0, значение SMM бесполезно, ESMM = 1 определяется битом SMM, работать ли в режиме специального экранирования. |
| D5 | SMM | ESMM = 1, когда SMM = 0, сбросить специальный экран (указывая, что 8259A не работает в режиме специального экрана), ESMM = SMM = 1, установить специальный экран. |
| D4-D3 | — | Константа 01, что является характерным битом OCW3 |
| D2 | P | Флаг команды запроса (команда опроса). P = 1, запрос; P = 0, нет запроса. |
| D1-D0 | RR,RIS | RR (команда чтения регистра) = 1, что означает чтение ISR или IRR. Когда RR = 1 и RIS = 0, IRR считывается, когда RR = 1 и RIS = 1, ISR считывается. |
Английский знаток может видеть эту картину.

Например, предположим, что адреса двух портов 8259A — это 20H и 21H, а OCW3, ISR и IRR используют один и тот же адрес 20H.
POLL Mode
Если выходной контакт INT не используется или флаг разрешения внутренних прерываний ЦП равен 0, внешнее устройство не может передать действительный сигнал запроса прерывания в ЦП. В этом случае можно использовать режим запроса. Кроме того, когда в системе много источников прерываний, более 64, вы также можете использовать метод запроса.
В следующей команде считывания после того, как позиция P OCW3 равна 1, 8259A рассматривается как сигнал ответа на прерывание ЦПУ 8259A очищает соответствующий бит IRR, ISR соответствует позиции 1 и отправляет слово запроса на шину данных. Команда read читает слово запроса из шины данных в формате:
D7 бит I = 0: указывает на отсутствие прерывания.
D7 бит I = 1: указывает, что этот фрагмент 8259A имеет запрос на прерывание, а W2
W0 — коды источника прерывания с наивысшим приоритетом.
Таблица быстрого поиска адреса порта командного слова
Для каждого порта командного слова я перечислил таблицу быстрого просмотра.
4. Прерывания
Для обработки событий, происходящих асинхронно по отношению к выполнению программы, лучше всего подходит механизм прерываний. Прерывание можно рассматривать как некоторое особое событие в системе, требующее моментальной реакции. Например, хорошо спроектированные системы повышенной надежности используют прерывание по аварии в питающей сети для выполнения процедур записи содержимого регистров и оперативной памяти на магнитный носитель с тем, чтобы после восстановления питания можно было продолжить работу с того же места.
Кажется очевидным, что возможны самые разнообразные прерывания по самым различным причинам. Поэтому прерывание рассматривается не просто как таковое: с ним связывают число, называемое номером типа прерывания или просто номером прерывания. С каждым номером прерывания связывается то или иное событие. Система умеет распознавать, какое прерывание, с каким номером оно произошло, и запускает соответствующую этому номеру процедуру.
Программы могут сами вызывать прерывания с заданным номером. Для этого они используют команду INT. Это так называемые программные прерывания. Программные прерывания не являются асинхронными, так как вызываются из программы (а она-то знает, когда она вызывает прерывание!).
Программные прерывания удобно использовать для организации доступа к отдельным, общим для всех программ модулям. Например, программные модули операционной системы доступны прикладным программам именно через прерывания, и нет необходимости при вызове этих модулей знать их текущий адрес в памяти. Прикладные программы могут сами устанавливать свои обработчики прерываний для их последующего использования другими программами. Для этого встраиваемые обработчики прерываний должны быть резидентными в памяти. Мы научимся создавать свои программы обработки прерываний и будем говорить об этом при обсуждении резидентных программ.
Аппаратные прерывания вызываются физическими устройствами и приходят асинхронно. Эти прерывания информируют систему о событиях, связанных с работой устройств, например о том, что наконец-то завершилась печать символа на принтере и неплохо было бы выдать следующий символ, или о том, что требуемый сектор диска уже прочитан, его содержимое доступно программе.
Использование прерываний при работе с медленными внешними устройствами позволяют совместить ввод/вывод с обработкой данных в центральном процессоре и в результате повышает общую производительность системы.
Некоторые прерывания (первые пять в порядке номеров) зарезервированы для использования самим центральным процессором на случай каких-либо особых событий вроде попытки деления на ноль, переполнения и т.п.
Иногда желательно сделать систему нечувствительной ко всем или отдельным прерываниям. Для этого используют так называемое маскирование прерываний, о котором мы еще будем подробно говорить. Но некоторые прерывания замаскировать нельзя, это немаскируемые прерывания.
Заметим еще, что обработчики прерываний могут сами вызывать программные прерывания, например, для получения доступа к сервису BIOS или DOS (сервис BIOS также доступен через механизм программных прерываний).
Составление собственных программ обработки прерываний и замена стандартных обработчиков DOS и BIOS является ответственной и сложной работой. Необходимо учитывать все тонкости работы аппаратуры и взаимодействия программного и аппаратного обеспечения. При отладке возможно разрушение операционной системы с непредсказуемыми последствиями, поэтому надо очень внимательно следить за тем, что делает Ваша программа.
4.2. Таблица векторов прерываний
Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти — адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов — FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний. В первом слове элемента таблицы записано смещение, а во втором — адрес сегмента обработчика прерывания.
Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с номером 1 — 0000:0004 и т.д. Для программиста, использующего язык Си, таблицу можно описать следующим образом:
Инициализация таблицы происходит частично BIOSпосле тестирования аппаратуры и перед началом загрузки операционной системой, частично при загрузке DOS. DOS может переключить на себя некоторые прерывания BIOS.
Займемся теперь содержимым таблицы векторов прерываний. Приведем назначение некоторых наиболее важных векторов:
Ошибка деления. Вызывается автоматически после выполнения команд DIV или IDIV, если в результате деления происходит переполнение (например, при делении на 0). DOS обычно при обработке этого прерывания выводит сообщение об ошибке и останавливает выполнение программы. Для процессора 8086 при этом адрес возврата указывает на следующую после команды деления команду, а в процессоре 80286 — на первый байт команды, вызвавшей прерывание.
Прерывание пошагового режима. Вырабатывается после выполнения каждой машинной команды, если в слове флагов установлен бит пошаговой трассировки TF. Используется для отладки программ. Это прерывание не вырабатывается после выполнения команды MOV в сегментные регистры или после загрузки сегментных регистров командой POP.
Аппаратное немаскируемое прерывание. Это прерывание может использоваться по-разному в разных машинах. Обычно вырабатывается при ошибке четности в оперативной памяти и при запросе прерывания от сопроцессора.
Прерывание для трассировки. Это прерывание генерируется при выполнении однобайтовой машинной команды с кодом CCh и обычно используется отладчиками для установки точки прерывания.
Переполнение. Генерируется машинной командой INTO, если установлен флаг OF. Если флаг не установлен, то команда INTO выполняется как NOP. Это прерывание используется для обработки ошибок при выполнении арифметических операций.
Печать копии экрана. Генерируется при нажатии на клавиатуре клавиши PrtScr. Обычно используется для печати образа экрана. Для процессора 80286 генерируется при выполнении машинной команды BOUND, если проверяемое значение вышло за пределы заданного диапазона.
Неопределенный код операции или длина команды больше 10 байт (для процессора 80286).
Особый случай отсутствия математического сопроцессора (процессор 80286).
IRQ0 — прерывание интервального таймера, возникает 18,2 раза в секунду.
IRQ1 — прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных от клавиатуры.
IRQ2 — используется для каскадирования аппаратных прерываний в машинах класса AT.
IRQ3 — прерывание асинхронного порта COM2.
IRQ4 — прерывание асинхронного порта COM1.
IRQ5 — прерывание от контроллера жесткого диска для XT.
IRQ6 — прерывание генерируется контроллером флоппи-диска после завершения операции.
IRQ7 — прерывание принтера. Генерируется принтером, когда он готов к выполнению очередной операции. Многие адаптеры принтера не используют это прерывание.