Цитата:
А где у Вас лежит таблица (или вектор) прерываний?
Место под таблицу выделяется менеджером памяти, он выделяет первую попавшуюся свободную страницу. Проверял, выделяет правильно. Выше первого МБ и не занятые ядром. В данный момент вывел этот адрес 102000h, по адресу 100000h до 102000h у меня лежит ядро.
Код:
macro int.init
{
push eax
mm.alloc_page ; EAX <- Free page paddr
mm.map_page eax, IDT_ADDR, PAGE_PRESENT or PAGE_WRITE
ci_8259A.init ; Инициализация контроллера прерываний 8259A
; Обработчики исключений (нарушений, ловушек и аварий)
int.set_handler 0, exc_0, GATE_P+GATE_TRAP ; #DE Нарушение. Ошибка деления, код ошибки-нет. Вызвано: div, idiv
int.set_handler 1, exc_1, GATE_P+GATE_TRAP ; #DB Нарушение/Ловешка. Исключение отладки. Код ошибки-нет.
int.set_handler 2, exc_2, GATE_P+GATE_INT ; Немаскируемые прерывания поступающие на порт NMI. (Аппаратный сбой)
int.set_handler 3, exc_3, GATE_P+GATE_TRAP ; #BP Ловушка. Программное прерывание служащее для отладки. Вызвано: int 3
int.set_handler 4, exc_4, GATE_P+GATE_TRAP ; #OF Ловушка. Фиксирует арефметическое переполнение(overflow). Код ошибки-нет. Вызвано: into
int.set_handler 5, exc_5, GATE_P+GATE_TRAP ; #BR Нарушение. Нарушение границ массива. Код ошибки-нет. Вызвано: bound
int.set_handler 6, exc_6, GATE_P+GATE_TRAP ; #UD Нарушение. Недопустимый код команды. Код ошибки-нет.
int.set_handler 7, exc_7, GATE_P+GATE_TRAP ; #NM Нарушение. Сопроцессор не доступен. Код ошибки-нет. Вызвано: esc, wait
int.set_handler 8, exc_8, GATE_P+GATE_TRAP ; #DF Авария. Двойное нарушение. Код ошибки-да
int.set_handler 9, 0, 0 ; Авария. Выход сопроцессора из сегмента. Код ошибки-нет
int.set_handler 10, exc_10, GATE_P+GATE_TRAP ; #TS Нарушение. Недопуст. сегмент состояния задачи TSS. Ошибка-да. Выз. jmp, call, iret, прерывание
int.set_handler 11, exc_11, GATE_P+GATE_TRAP ; #NP Нарушение. Отсутствие сегмента. Ошибка-да. Выз. команда загрузки сегмент. регистра
int.set_handler 12, exc_12, GATE_P+GATE_TRAP ; #SS Нарушение. Ошибка обращения к стеку. Код ошибки-да. Вызвано: командой обращения к стеку
int.set_handler 13, exc_13, GATE_P+GATE_TRAP ; #GP Нарушение. Общая защита. Код ошибки-да. Вызвано: команда обращения к памяти
int.set_handler 14, exc_14, GATE_P+GATE_TRAP ; #PF Нарушение. Страничное нарушение. Код ошибки-да. Вызвано: команда обращения к памяти
int.set_handler 15, 0, 0 ; Не используется
int.set_handler 16, exc_16, GATE_P+GATE_TRAP ; #MF Нарушение. Сопроцессор не доступен. Код ошибки-нет. Вызвано: esc, wait
int.set_handler 17, exc_17, GATE_P+GATE_TRAP ; #AC Нарушение. Ошибка выравнивания. Код ошибки-да. Вызвано: команда обращения к памяти
; 18-31 Зарезервировано
; Аппаратные прерывания (Hardware interrupts) от ведущего контроллера 8259A
int.set_handler 32, int8_handler, GATE_P+GATE_INT ; IRQ0 — программируемый интервальный таймер или высокоточный таймер событий №0
int.set_handler 33, int9_handler, GATE_P+GATE_INT ; IRQ1 — клавиатура PS/2
int.set_handler 34, int_EOI, GATE_P+GATE_INT ; IRQ2 — запрос прерывания от ведомого контроллера прерываний (8259A - Slave)
int.set_handler 35, int_EOI, GATE_P+GATE_INT ; IRQ3 — произвольное устройство (в IBM PC/AT — последовательный порт COM2 и COM4)
int.set_handler 36, int_EOI, GATE_P+GATE_INT ; IRQ4 — произвольное устройство (в IBM PC/AT — последовательный порт COM1 и COM3)
int.set_handler 37, int_EOI, GATE_P+GATE_INT ; IRQ5 — произвольное устройство (в IBM PC/AT — параллельный порт LPT2)
int.set_handler 38, int_EOI, GATE_P+GATE_INT ; IRQ6 — произвольное устройство (в IBM PC/AT — контроллер гибких дисков)
int.set_handler 39, int_EOI, GATE_P+GATE_INT ; IRQ7 — произвольное устройство (в IBM PC/AT — параллельный порт LPT1)
; Аппаратные прерывания (Hardware interrupts) от ведомого контроллера 8259A (линии шины ISA)
int.set_handler 40, int_EOI, GATE_P+GATE_INT ; IRQ8 — часы реального времени или высокоточный таймер событий №1
int.set_handler 41, int_EOI, GATE_P+GATE_INT ; IRQ9 — произвольное устройство
int.set_handler 42, int_EOI, GATE_P+GATE_INT ; IRQ10 — произвольное устройство
int.set_handler 43, int_EOI, GATE_P+GATE_INT ; IRQ11 — произвольное устройство или высокоточный таймер событий №2
int.set_handler 44, int_EOI, GATE_P+GATE_INT ; IRQ12 — произвольное устройство, обычно мышь PS/2, либо высокоточный таймер событий №3
int.set_handler 45, int_EOI, GATE_P+GATE_INT ; IRQ13 — ошибка арифметического сопроцессора
int.set_handler 46, int_EOI, GATE_P+GATE_INT ; IRQ14 — произвольное устройство, обычно первый контроллер ATA (или контроллер Serial ATA в режиме совместимости
int.set_handler 47, int_EOI, GATE_P+GATE_INT ; IRQ15 — произвольное устройство, обычно второй контроллер ATA (или контроллер Serial ATA в режиме совместимости)
; Программные прерывания (Software interrupts)
int.set_handler 48, syscall_handler, GATE_P+GATE_DPL3+GATE_TRAP ; Ловушка. Печать строки
;---------------------------------------------------------------------------------------------------------------
lidt [IDTR] ; загружаем регистр IDTR.
; разрещаем аппаратные прерывания и NMI
in al,70h
and al,7Fh
out 70h,al ; разрешить NMI прерывания
sti ; Разрешить аппаратные прерывания
pop eax
}
IDTR:
.size dw (256*8)-1 ; Размер IDT таблицы
.addr dd IDT_ADDR ; Адрес IDT таблицы
; Добавить шлюз прерывания в IDT
; int_id - Номер прерывания (1 байт)
; handler - Адресс обработчика прерывания (Смещение в сегменте) (4 байта)
; attr - Атрибуты. Бит присутствия, уровень привилегий, storageSegment, тип шлюза
macro int.set_handler int_id, handler, attr
{
push eax ebx ecx
mov eax,int_id
mov ebx,handler
mov ecx,attr
call int_set_handler
pop ecx ebx eax
}
; Добавить шлюз прерывания в IDT
; eax - Номер прерывания (1 байт)
; ebx - Адресс обработчика прерывания (Смещение в сегменте) (4 байта)
; ecx - Атрибуты. Бит присутствия, уровень привилегий, storageSegment, тип шлюза
int_set_handler:
push ebx
mov word [IDT_ADDR + (eax*8)],bx ; Записываем младшую часть адреса
shr ebx, 16 ; Сдвигаем старшую часть адреса в BX
mov word [IDT_ADDR + (eax*8) + 6],bx ; Записываем старшую часть адреса
mov word [IDT_ADDR + (eax*8) + 2],SL_CODE ; Записываем селектор сегмента
mov byte [IDT_ADDR + (eax*8) + 4],0 ; Пустой. Если это шлюз вызова то младшие 5 бит это количество параметров, старшие 3 бита = 0
mov byte [IDT_ADDR + (eax*8) + 5],cl ; Установка параметров шлюза прерывания
pop ebx
ret