Проблема с аппаратными прерываниями в PM

Тема в разделе "WASM.ASSEMBLER", создана пользователем LeonidPr, 18 июл 2006.

  1. LeonidPr

    LeonidPr New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    4
    Возникла следующая проблема. Я написал прогу, которая переводит проц в защищенный режим и обрабатывает прерывания. Все это до тех пор, пока я не нажму esc. Проверка идет просто, в цикле проверяю содержимое порта 60h. Проблема такая. После перепрограммирования контроллера прерываний я размаскировал только прерывание от клавы. Но, активируется почему-то при нажатии клавиш обработчик для irq7. Описание IDT проверил несколько раз вроде все нормально. Что это может быть.
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Я сравнил Ваш пример со своим - вроде бы немного по-разному инициализируется контроллер (reprogram_8259). Возможно, причина еще в чем-то...
     
  3. LeonidPr

    LeonidPr New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    4
    Я посмотрел, разница только в ICW4. Но, такой вариант, как у вас я уже пробовал. Безрезультатно.
     
  4. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Вроде бы разобрался с твоим примером... Я бы перечислил ошибки, но их слишком много ;) Основные:

    1) Неверно инициализируется контроллер - из-за этого прерывания не возникали, я исправил это;
    2) Неверно определены ловушки (их должно быть 20h, потом уже идут прерывания), неверно определен атрибут в описателе прерывания (нужно 8Eh);
    3) Команда iret в обработчиках прерывания вызывает исключение 0Dh, нужно дописать db 66h.

    Ну и так далее... Смотри исправленный пример (правда, он теперь виснет при выходе в дос, но прерывания точно работают). Также рекомендую посмотреть как у меня идет работа в обработчике прерывания от клавиатуры с портами.

    ++ Добавлены нормальные обработчики исключений - они выводят номер исключения и кусок стека (там адрес исключения и т.п.)
     
  5. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Нужно просто писать iretd - хотя это конечно одно и то же...
     
  6. LeonidPr

    LeonidPr New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    4
    Большое спасибо. Вчера разбирался с тем, что вы доделали. Хочу немного прокомментировать те ошибки, которые вы отметили.
    1. Про неверную инициализацию контроллера прерываний. Я заменил в вашем примере процедуру перепрограммирования ПКП на свою. Все работает!
    2. Атрибут 8Еh в описателе прерываний указывает на то, что шлюз-32 битный. Т.к. у меня все сегменты определены с атрибутом use16 и в GDT все дескрипторы описывают сегменты как 16 битные, то и в описании шлюза я использовал 86h. Отсюда следует ...
    3. db 66h перед iret не нужно.

    Моя проблема была в другом. У меня работали прерывания, но как-то странно. У вас с ними все нормально. Сейчас ищу разницу между вашим примером и своим. Еще раз спасибо.
     
  7. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Да не за что ;)

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

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

    Тут я заметил, что исключений не 20h, а другое число. Обработчки прерывний должны идти следом. Я исправил это, а также атрибут в дескрипторе прерывания, меня также смутило что у ловушек и прерываний он одинаковый, заменил инициализацию контроллера. Тут же возникло исключение.

    Я более подробно вывел информацию по исключению, адрес краша. Так я понял, что исключение 0Dh вызывает команда iret в обработчике прерываний, я исправил ее на iretd и все заработало, но не работали прерывания от клавиатуры.

    Затем я убрал цикл опроса порта клавиатуры 60h на просто проверку числа прерываний от таймера:

    lpwait:
    cmp word ptr ds:Int08Counter,0FFh
    jnz lpwait
    assume ds:gdt_seg

    После этого прерывания от клавиатуры появились.

    Единственное, что после выхода в DOS все виснет. В моем примере (первом) такого нет, но я не доделал все окончательно...
     
  8. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    А контроллер прерываний обратно восстановить не забыл? А idtr на реальный режим перестроил?
     
  9. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Ustus

    Не знаю, я все, что после перехода в RM обратно - не проверял (тот код, что я корректировал). Знаю только, что виснуть начало как заработали прерывания от клавиатуры (от таймера когда только были - все работало и потом), и еще - в моем примере нет такой проблемы.