Как определить прерывания, специфичные для устройства на x86?

StackOverflow https://stackoverflow.com/questions/773199

  •  13-09-2019
  •  | 
  •  

Вопрос

В руководстве разработчиков программного обеспечения Intel говорится, что векторы прерываний 32–255 обычно определяются пользователем для внешних устройств ввода-вывода.На уроке системного программирования мне нужно разработать простой драйвер устройства.Мой вопрос: как я могу определить конкретный вектор прерывания, который будет использоваться для конкретного устройства?Это делается через биос?

Примечание:мы разрабатываем простую операционную систему, поэтому моя ситуация достаточно специфична, однако в конечном итоге мне нужно понять, как все это происходит в системе x86.В настоящее время наша система настроена так, что несколько векторов прерываний с номером выше 32 назначаются таким устройствам, как последовательный порт и клавиатура.При чтении таблицы данных контроллера ввода-вывода Intel 82801EB ICH5, в частности раздела, касающегося PIC 8259, говорится, что IRQ15 является вторичным каналом IDE.Как это в конечном итоге будет помещено в стек как вектор прерывания?

Возможно, я просто настолько сбит с толку, что этот вопрос не имеет смысла, поэтому заранее прошу прощения.

РЕДАКТИРОВАТЬ:Итак, наш класс системного программирования имеет очень простую ОС, в которой есть процедуры ядра для установки ISR для обработки определенных прерываний с учетом номера вектора.На нашем занятии в прошлой четверти профессор дал нам заголовочный файл, в котором клавиатура определялась как векторный номер 0x2c или что-то подобное.Я пытаюсь выяснить, как сопоставить прерывания основного и/или вторичного канала IDE с различными ISR, используя наши процедуры ядра.На данный момент все неиспользуемые векторы прерываний имеют обработчик по умолчанию, который будет печатать сообщения в случае возникновения прерывания, поэтому прерывания IDE в данный момент даже не включены, однако это другой вопрос.

Это было полезно?

Решение 5

Что ж, кажется, я нашел ответ в нашем коде поддержки, в частности, в процедуре инициализации PIC.В следующем коде строки IRQ отображаются со смещением 20h и 28h в IDT для ведущего и ведомого PIC соответственно.

/* ICW2: master offset of 20 in the IDT, slave offset of 28 */

__outb( PIC_MASTER_IMR_PORT, 0x20 );
__outb( PIC_SLAVE_IMR_PORT, 0x28 );

Это означает, что клавиатура была сопоставлена ​​с вектором номер 2c, а первичный и вторичный каналы будут сопоставлены с 2e и 2f соответственно.Некоторые из вас, вероятно, могли бы дать мне лучшие ответы, если бы я задал вопрос лучше, но я все равно ценю помощь!

В таблице 45 таблицы данных 82801EB ICH5 подробно описаны линии IRQ 8259, и в моей ОС ведущий просто загружается со смещением 20h, а ведомый — 28h.

Спасибо!

Другие советы

Вы можете запрограммировать PIC (программируемый контроллер прерываний) для сопоставления IRQ определенных устройств.

На платформе x86 есть два PIC, которые соединены последовательно и выдают IRQ0-IRQ17.IRQ0-7 управляется 8259, а IRQ8-15 — вторым 8259.Первый сигнализирует ЦП и является ведущим, а второй (ведомый) сигнализирует первому.

IDT (таблица дескрипторов прерываний) сопоставляет прерывания с адресами ISR (процедур обслуживания прерываний).Прерывания могут быть вызваны напрямую с помощью инструкции INT (программные ловушки).

Например, чтобы вызвать прерывание 0x80, выполните INT 0x80.

Чтобы обработать 0x80, mov [0x80*4], int_80_handler.Предполагая 32-битную архитектуру, адрес int_80_handler функция теперь хранится в 0x80-м месте в IDT.

Вы найдете это полезным:
http://en.wikipedia.org/wiki/Intel_8259
http://en.wikipedia.org/wiki/Interrupt_Handler
http://en.wikipedia.org/wiki/Прерывание
http://en.wikipedia.org/wiki/Interrupt_descriptor_table

Прошло много времени с тех пор, как я имел дело с этим материалом, поэтому это может быть отключено:Напомню, что контроллер прерываний ПК имеет 15 линий IRQ.Они сопоставляются с конкретными соседними векторами прерываний x86.Таким образом, когда периферийное устройство запускает линию IRQ, PIC прерывает работу ЦП и сообщает, к какому вектору перейти, как если бы была выполнена соответствующая инструкция INT.Некоторые IRQ жестко запрограммированы на определенных периферийных устройствах, но я считаю, что устройства PCI договариваются с ОС о IRQ и некоторых других ресурсах (как и устаревшие устройства ISA PnP).

Я не понимаю, что вы имеете в виду под «Как это в конечном итоге будет помещено в стек как вектор прерывания?»

Устройство может получить прерывание двумя способами:

  1. Используйте механизм Plug and Play или Pci.Если вы это сделаете, BIOS вызовет ваше периферийное устройство и запросит требования к ресурсам.После этого ваш драйвер может перечислить устройства Plug-and-Play, выполнить поиск поддерживаемого устройства и получить аппаратное прерывание от устройства.

  2. Как это делалось в первые дни:Просто используйте одно прерывание.Добавьте к устройству DIP-переключатель, который позволит пользователю выбирать между различными прерываниями.Распределение ресурсов теперь находится в руках пользователей.Пользователь также каким-то образом передаст номер прерывания драйверу во время загрузки.

Теперь как перехватить прерывание:Это зависит от ОС и режима, в котором работает x86.Для голой, голой системы вы можете запросить IDT (таблицу дескрипторов прерываний) с помощью специальной инструкции.Получив этот IDT, вы можете получить адрес и вставить адрес обработчика IRQ в правильный слот.Что касается реального режима, я больше не знаю, как это делается.

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

Насколько я помню, в начале области памяти есть таблица векторов, указывающая на подпрограмму, которую следует вызывать при возникновении определенного прерывания.Возможно, я здесь нахожусь на слишком низком уровне (старый программист на ассемблере x86), но на базовом уровне вы устанавливаете свой вектор в эту таблицу, а затем вызываете вашу подпрограмму.У меня нет с собой никаких старых справочных материалов, поэтому я не могу дать вам конкретные рекомендации, но я был бы удивлен, если бы официальный метод работал вне BIOS.

Я уверен, что в наши дни графических интерфейсов существуют другие, более подходящие методы, которые позволяют совместно использовать прерывания и все такое хорошее.

РЕДАКТИРОВАТЬ:Не обращайте на это внимания, я только что увидел, что вы смотрите на прерывания 16 и выше, которые находятся за пределами аппаратных прерываний.Я отошел от этого уровня программирования до того, как в этом пространстве появилось что-то интересное, поэтому я имел дело только с первыми 15 IRQ (16-е — каскад между контроллерами).Оставлю, вдруг кому-то будет интересно :)

INT 21h / AH=25h - установить вектор прерывания;вход:AL = номер прерывания.DS:DX -> новый обработчик прерываний.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top