OSDev

для всех
Текущее время: 27 апр 2024, 09:15

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 60 ]  На страницу 1, 2, 3, 4, 5, 6  След.
Автор Сообщение
СообщениеДобавлено: 16 ноя 2012, 11:18 

Зарегистрирован: 18 апр 2010, 15:59
Сообщения: 155
Приветствую сообщество osdev!

Мною был обнаружен баг в реализации таймера APIC-а в VmWare 8. Согласно документации Intel, при запуске APIC-а в режиме One Shot таймер APIC-а должен генерировать прерывание при достижении счетчиком нуля. Таким образом, после получения прерывания от этого таймера теоретически при прочтении регистра текущего значения счетчика мы ВСЕГДА должны получать значение ноль. По крайней мере я на это рассчитывал, и проверял это значение после получения прерывания, чтобы убедиться, что прерывание поступило именно от таймера, а не от криво настроенного PIC или IO APIC. На практике, при использовании виртуальной машины оказалось, что это предположение не всегда истинно и VmWare может запускать прерывание от таймера, до того как счетчик достигнет нуля. В частности, периодически, я получал значение 1. На реальном железе, я надеюсь, такое поведение не должно воспроизводиться.

Пример кода:
Код:
VOID ASMCODE HandleTimerRing(KrnControlBlock* CONST)
{
    __asm
    {
        push  ECX
        xor   EAX, EAX
        mov   EAX, DS:APIC_PAGE.currentCount.value
        test  EAX,            EAX
        jnz   short SPURIOUS_RING
    }
   
        ....

SPURIOUS_RING:
   __asm pushad;
   __asm mov ecx, DS:APIC_PAGE.currentCount.value;
   __asm mov edx, 14;
   __asm push 6;
   __asm call PrintUlong;
   __asm popad;
   
   __asm pushad;
   __asm mov ecx, eax;
   __asm mov edx, 14;
   __asm push 7;
   __asm call PrintUlong;
   __asm popad;

   __asm pop ECX              ; //
   __asm jmp short EoiHandling; // 9
}


В результате выполнения этого кода обработчика прерывания таймера APIC в седьмой строке я получаю значение "00000001" а в шестой - "00000000". Заметьте, что в седьмую строку записывается значение EAX заполненное ранее из регистра Current Count APIC-а в начале обработчика. То есть APIC продолжает декрементировать значение регистра. В связи с этим, я полагаю, что current count регистр APIC может содержать любое относительно небольшое значение во время запуска прерывания.

Надеюсь, что данный пост поможет кому-нибудь сэкономить кучу времени, так как отладка планировщика - это то еще извращение.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 ноя 2012, 14:37 
Аватара пользователя

Зарегистрирован: 14 мар 2011, 12:31
Сообщения: 970
Откуда: Дагоба
Надо бы сообщить об этом разработчикам VmWare.

_________________
Yet Other Developer of Architecture.
The mistery of Yoda’s speech uncovered is:
Just an old Forth programmer Yoda was.

<<< OS Boot Tools. >>>


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 16 ноя 2012, 17:33 
Заблокирован

Зарегистрирован: 28 окт 2011, 12:14
Сообщения: 555
Откуда: Новосибирск
В контроллере APIC регистр Current Count Register (+390h) меняется очень быстро и возможно в момент срабатывания прерывания по его 0ю прочитаем его состояние уже не 0е. На его изменения ничего не влияет, а настройка только его интервал и делитель.
При срабатывании прерывания он становится равным Initial Count Register (+380h) и уменьшается на 1 до 0 в зависимости от делителя.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 03:36 

Зарегистрирован: 18 апр 2010, 15:59
Сообщения: 155
Станислав, если я правильно понимаю устройство этого таймера, то к регистру CurrentCount привязан какой-то компаратор, который на каждом такте, проверяет значение регистра на ноль. И только если эта проверка прошла успешно, срабатывает управляющая логика, которая в случае режима One Shot останавливает счетчик и запускает прерывание. Так что согласно этой логике, невозможно прочитать не нулевое значение из этого регистра после получения прерывания. Это первое. Второе, после запуска прерывания и до чтения регистра проходит существенное время: процессор принимает прерывание, останавливает/сбрасывает конвейер, создает на стеке кадр прерывания, вычитавает IDT, передает управление обработчику прерывания, тот в свою очередь проводит диспетчеризацию прерывания, добивает кадр прерывания до универсального, сохраняет контекст прерванного потока управления, проводит вторичную диспетчеризацию вызывая обработчик таймера и только тот уже читает значение из регистра. Только по коду ядра будет выполнено не менее 15 разнокалиберных инструкций. В целом с учетом всевозможных кэширований, выборок данных из памяти и тому подобной внутрепроцессорной мути пройдет не менее 50 тактов с момента инициирования прерывания таймером до чтения регистра.

В общем, я не могу представить как на реальном железе это может произойти.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 04:50 
Заблокирован

Зарегистрирован: 28 окт 2011, 12:14
Сообщения: 555
Откуда: Новосибирск
Понятно, в прерывании читается 0, значит всё верно, кстати при срабатывании прерывания процессор ещё загружает селектор данных указанный в IDT(т.е. ещё и GDT смотрится), а в стеке он просто сохраняет адрес возврата, и флаги(они могут быть использованы, т.к. прерваться может в любой момент). Во многих системах стек ещё и меняется, для того, чтобы деятельность прерывания не портила стек прерванной задачи, да и ВАП тоже меняется системой.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 07:07 

Зарегистрирован: 18 апр 2010, 15:59
Сообщения: 155
Оно то все понятно. Непонятно только почему VmWare себя так ведет. Станислав, а какую виртуалку вы используете для своих проектов в области ОС и ОСобразного программирования голого железа?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 11:03 
Аватара пользователя

Зарегистрирован: 14 мар 2011, 12:31
Сообщения: 970
Откуда: Дагоба
Станислав любит QEMU. Я Bochs.

_________________
Yet Other Developer of Architecture.
The mistery of Yoda’s speech uncovered is:
Just an old Forth programmer Yoda was.

<<< OS Boot Tools. >>>


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 11:59 

Зарегистрирован: 18 апр 2010, 15:59
Сообщения: 155
Под Виндой они работают (Windows XP и Windows 7)?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 12:02 

Зарегистрирован: 18 апр 2010, 15:59
Сообщения: 155
Поделитесь опытом если не сложно, какие подходы/методы/трюки вы используете, чтобы сделать разработку более удобной/простой/быстрой? Может есть еще какие-нибудь трюки кроме использования виртуалки?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 22 ноя 2012, 15:19 
Заблокирован

Зарегистрирован: 28 окт 2011, 12:14
Сообщения: 555
Откуда: Новосибирск
В QEMU мне нравится, что сам бинарник затранслируемый фасмом указанный как диск в QEMU запускается без всяких проверок на геометрию диска, я просто нажимаю в QEMU на старт и он мне бинарник запускает. В бинарнике первые 512 байт в 7C00h а остальное сам грузиш и запускаеш, ну как всегда.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 60 ]  На страницу 1, 2, 3, 4, 5, 6  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB