§ Установка IDT в программе

Как уже говорилось в разделе "защищённый режим", воспользоваться прерываниями BIOS и DOS программа, работающая в P-Mode, не может. Это связано с тем, что вектора от 00h до 1Fh заняты исключениями либо зарезервированы для них, следовательно, прерывания, отображённые на эти вектора, предоставляют доступ не к ресурсам BIOS-а, а к обработчикам прерывания. Например, команда INT 10h в режиме реальных адресов обеспечивает доступ к сервису управления видеоадаптером, а в защищённом режиме - к обработчику исключения плавающей точки x87 FPU.
Итак, для того, чтобы определить прерывания в защищённом режиме, нужно выполнить следующие действия:
  • Перенаправить аппаратные прерывания (IRQ)
  • Создать дескрипторы для всех используемых векторов (исключений, аппаратных и программных прерываний).
  • Подготовить образ IDTR и загрузить его в регистр IDTR.
  • Разрешить прерывания
Действие 1 были рассмотрены в предыдущей главе, действие 3 - см. в исходнике - оно совмещено с построением GDT; в этой главе будет обсуждаться только 2-е.
Некоторые процедуры, из-за своей громоздкости, здесь будут приведены не полностью - будет показан только принцип их построения. В конце главы вы сможете найти ссылку на архив (7Кб) с файлами исходника, библиотеки и самой программы.
Теперь для каждого примера будет своя библиотека, т.к. макросы, определяющие обработчики прерываний, можно будет менять и дополнять в пределах изучаемой темы и отдельная библиотека для каждого примера позволит избежать путаницы и лишней работы по редактированию макросов.
Создаём дескрипторы для всех используемых векторов прерываний.
Для всех исключений и прерываний создадим дескрипторы шлюзов прерываний и ловушек; шлюзы задач будут рассматриваться отдельно в разделе "Мультизадачность".
Шлюзы прерываний и ловушек содержат точку входа (сегмент:смещение) и права доступа обработчика. В следующем ниже примере функцию самих обработчиков будут выполнять заглушки, определённые соответствующими макросами; функциональная реализация обработчиков исключений и аппаратных прерываний будет описана в дальнейших главах.
Для установки дескрипторов прерываний давайте определим три следующих функции. Базовая функция set_IDT_descriptor устанавливает дескриптор с правами доступа в CX. Шлюзы прерывания и ловушки отличаются всего лишь одним битом в байте прав доступа (бит D в дескрипторе шлюза ловушки равен 0, т.к. стек, используемый обработчиком ловушек в нашем примере - 16-разрядный).
Вот и все основные функции, необходимые для правильной работы системы прерываний в защищённом режиме. Для того, чтобы установить или обновить обработчик прерывания или исключения, нужно всего лишь изменить соответствующий макрос вида ..._handler, все остальные функции при компиляции правильно построят IDT и обеспечат корректную работу системы.
Обратите внимание, что все обработчики исключений и аппаратных прерываний представляют собой простое зацикливание - это и есть простейший пример реализации заглушек. Эти заглушки необходимы на начальной стадии построения операционной системы, когда вы ещё не решили, как будут обрабатываться исключения и прерывания, но работать они должны.
В главе 7 будут показаны примеры заглушек для исключений, которые будут выдавать информацию о самих исключениях.
В этом примере определена IDT из 32h (т.е. 50) дескрипторов. Для примера - этого вполне хватает, для других программ - может не хватить, но главное, чтобы вы знали о возможности увеличить/уменьшить IDT простой заменой значения макроса idt_descr_n.
Для программных прерываний в примере определено всего 2 дескриптора - просто чтобы было понятно, как их определять. На самом деле, операционная система защищённого режима не нуждается в программных прерываниях - её сервис удобней предоставлять в виде вызовов соответствующих процедур или задач, к тому же, в защищённом режиме прерывание обрабатывается довольно-таки долго, по сравнению с дальним вызовом.
Процедуры смотреть здесь.