Добрый день, есть некоторая фирмварь, которую очень хочется загрузить и заставить работать. Фирмварь изначально рассчитана на работу в защищенном режиме и оригинального загрузчика к ней нет. Поэтому начал писать свой загрузчик (враппер который запускается из биоса). Проблемы загрузки фирмвари в память, настройки защищенного режима и передачи управления на фирмварь вроде преодолел. Но дальше появились проблемы уже в самой фирмвари - похоже какой-то цикл калибровки задержек: Code (Text): xor ecx, ecx xor ebx, ebx jmp short loop1_entry loop1: inc ecx loop1_entry: mov edx, 20h in al, dx test al, 1 jz short loop1 mov eax, 80h mov dl, 61h out dx, al jmp short loop2_entry loop2: inc ecx loop2_entry: mov edx, 20h in al, dx test al, 1 jnz short loop2 inc ebx cmp ebx, 99 jle short loop1_entry mov dx, 10000 lea eax, [ecx+5000] mov ecx, edx xor edx, edx div ecx Перед этим куском кода таймер настраивается на 1000Hz и Mode3 (Square wave). Если прерывания не включать - то зацикливается на loop2, если поставить пустой обработчик на IRQ0 (просто писать 0x20 в порт 0x20) - то IRR регистр скидыватся в 0 и код зацикливается на loop1. Подозреваю что обработчик IRQ0 должен как-то менять свое поведение согласно внутреннему счетчику таймера, но так как раньше дела с таймерами не имел - просто пока не могу представить для чего это нужно. Если кто-то видел/знает подобные конструкции - подскажите для чего это необходимо и как правильно написать обработчик.
Avenger Насколько понимаю, данный кусок кода просто ждёт 1/10 секунды, и подсчитывает сколько раз он за это время успеет прочитать порт, правда зачем в порт 61h записывает 80h, а в конце число чтений делится на 10000, непонятно.
Black_mirror Да, 1/10 секунды тут прослеживается, но EBX инкрементируется только если IRQ0 уже обслужено (IRR бит0 = 0, т.е. из порта 0x20 вернется бит0 = 0). Но при таком условии оно просто не выйдет из loop1 Соответственно обработчик IRQ0 должен не обрабатывать некоторое количество прерываний..., так как выход из loop1 это IRR=1 а выход из loop2 это IRR=0. Если IRQ0 всегда обрабатывается - то код никогда не дойдет до инкрементации EBX. Очень похоже что обработчик IRQ0 зависит от вывода 0x80 в порт 0x61... Но документация Intel (на ICH7 например) говорит что биты 4-7 read-only.
Кажется я понял. Запись 0x80 в порт 0x61 делает ресет IRQ0 (при использовании PS/2 контроллера) Соответственно код действительно ждет 1/10 секунды при условии отстутствия каких либо irq-хендлеров. Т.е. записью в порт 0x61 он сам подтверждает получение IRQ0. Но так как я этот код запускал на QEMU - там это просто не реализовано и на порту 0x61 "слушает" исключительно PC Speaker. Соответственно запись 0х80 ни на что не влияла, и код "зависал".
Pavia Ой не врите. Младшие 4 бита 61-го порта R/W, старший нибл ридонли: 0 R/W Вход GATE PIT. 1 R/W Отключает спикер(запилена логическое & с выходом на спикер). 2, 3 R/W Управляет шинами хз. 4 R Регенерация памяти связана с этой линией. 5 R Выход счётчика PIT. 6, 7 R Сигнализирует ошибки на шине или рам.
У intel этот бит обозначен как read only начиная от PIIx4 заканчивая ICH8. От материки к материке значение всего порта менялось, так что все не проверял. А вот на PS/2 да 80h отвечает за сброс защёлки IRQ0
А вопрос в догонку - получается что порт 61h должен слушать какой-то свой контроллер, который уже форвардит реквесты на ICHx ? Так как должен же быть какой-то уровень совместимости с PS/2... где бы про него почитать... ЗЫ. Эта фирмвать работает на х86-совместимом железе и не только на чипсетах от Intel. Гарантировано запускается на Geode и вполне возможно на некоторых NForce чипсетах. Т.е. какой-то уровень совместимости должен быть в не зависимости от того что пишет интел в своих документах.
kejcerfcrv Так спикер не затрагивается режимом совместимости: Code (Text): 0061 w KB controller port B (ISA, EISA) (PS/2 port A is at 0092) system control port for compatibility with 8255 bit 7 (1= IRQ 0 reset ) bit 6-4 reserved bit 3 = 1 channel check enable bit 2 = 1 parity check enable bit 1 = 1 speaker data enable bit 0 = 1 timer 2 gate to speaker enable Биты 0 и 1 точно также отвечают за спикер, как и в документации Intel. Вопрос в том что старшие четыре бита по документации read-only... Но если это работает на реальном железе, значит в чипсете реализована совместимость с PS/2 - вот и интересно где это искать. (Так как я хочу запустить эту фирмварь на QEMU - то соотв. мне нужно реализовать эмуляцию этой совместимости самому...)