Приветствую дзенствующих! Возник у меня такой вопрос. Решил реализовать в ядре VESA-графику. И хочется менять режимы уже после перехода в PM. Так как vbe 3 поддерживают не все, да и vbe 2 тоже, то решил организовать переключение видеорежимов временным переходом в реальный режим. Делаю вот что: 1. Копирую 16-разрядный код ниже первого мегабайта. 2. Заполняю структуру для регистров (ax, bx, cx и т.д.). 3. Запрещаю прерывания (cli), сохраняю все регистры общего назначения и esp. 4. Загружаю IDTR реального режима. 5. Выключаю paging и pe в cr0, перехожу в реальный режим на 16-разрядный код. 6. Инициализирую сегментные регистры и стек. 7. Загружаю регистры из структуры. 8. Вызываю int 10h. 9. Сохраняю регистры в структуру. 10. Перехожу в защищённый режим на 32-битный код. 11. Включаю paging. 13. Восстанавливаю селекторные регистры. 12. Загружаю IDTR защищённого режима. 14. Восстанавливаю сохранённый esp и регистры общего назначения. 15. Разрешаю прерывания (cli). И заметил следующее: функция 4f00h спокойно выполняется без проблем. А вот с 4f02h возникает нечто непонятное: после выхода из неё перестают поступать IRQ. И это наблюдается на реальном железе. А вот на эмуляторах qemu + bochs такого нет, там всё переключается без проблем. Что можете посоветовать?
тупая мысль, но может быть в коде int 10h гдето есть sti, который портит всю малину.. а обработчик не сбрасывает заявку на прерывание
Мысль действительно не очень. Но имеет право на жизнь. Я пытался после выхода переинициализировать контроллер прерываний и послать EOI в master и slave. М. Ничего толкового из этого не вышло. Только продлилась тема на два переключения туда-обратно (в смысле, в текстовый режим и в графический).
Проверил ещё раз. 4f00h тоже вешается после нескольких последовательных вызовов. Код тут: http://xskernel.svn.sourceforge.net/viewvc/xskernel/xskernel/include/system/realmode/realmode.s?revision=199&view=markup
Для начала проверь, идут ли прерывания в вызываемом коде реального режима - например идут ли прерывания таймера Int 8 (IRQ0) - до и после вызова Int 10. После возвращения из реального режима попробуй обнулить маски обоих PIC. Попробуй вместо Код (Text): 106 mov eax, cr0 107 or al, 1 108 mov cr0, eax делать Код (Text): 107 mov eax, 1 108 mov cr0, eax В общем, cr0 нужно инициализировать целиком - константой, или сохранённым ранее значением.
Сохранять cr0 попробую. Дело в том, что у меня IRQ0-15 запрограммированы на векторы 0x20-0x2f. Я забыл это указать. Маски обоих PIC не обнуляю, но записываю туда маски открытых прерываний (сейчас у меня это timer, keyboard, cascade, floppy). Сделал между возвратом в PM и включением прерываний задержечку. Таймер вроде продолжает работать, а вот клава отваливается. И это я только пытаюсь запустить 0x03 режим (текстовый).
Для реального режима лучше программируй IRQ0 на Int8, т.к. хоть ты и запрещаешь прерывания, но внутри BIOS они иногда разрешаются. Наверно поэтому и клавиатура зависает, потому что не обрабатывается прерывание отжатия клавиши.
Господа! Я в ауте! Если выставлять бит исользования LFB при включении режима, то всё прекрасно! Если не выставлять, то отваливаются прерывания . В принципе, ну его нафиг . Всё равно без LFB никакого кайфа нет . Так что, кажися, проблема решена .
В общем, подытоживаю: 1. Обязательно надо включить обработчики прерываний в реальном режиме перед вызовом int 10h. 2. Если перепрограммирован контроллер - скопировать векторы прерываний реального режима на новые. 3. Использовать только LFB-режимы.
SadKo Если правильно понял, BIOS плевать на номера векторов, но сами его обработчики внешних прерываний должны в реальном режиме вызываться, пускай и под новыми номерами?
Просто теоретически нельзя исключать каких-либо махинаций БИОС, "закладывающихся" на соответствие IRQ определённым векторам. Хотя, надеюсь, ни один БИОСописатель до такого маразма не дошёл.