проблема с реализацией мультизадачности в защищённом режиме.

Тема в разделе "WASM.NT.KERNEL", создана пользователем rpy3uH, 16 янв 2008.

  1. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    В общем есть три задачи: главная, задача №1 и задача №2. Есть Шлюз задачи он находится на IRQ0. На все остальных аппратных прерываниях стоит обычный шлюз прерывания (с пустыми обработчиками). идея такая: на каждом первом прерывании (irq0) возвращаю управление главной задаче, на каждом втором прерывании возвращаю управление задаче №1, на каждом третьем - задача №2, на каждом четвёртом главной задаче.
    с кодом главной задачи проблем нет и он заканчивается так
    Код (Text):
    1. MainTask:  
    2. ;загружаем IDTR, инициализируем контроллеры прерываний.....
    3. ....
    4.  sti
    5.  jmp $
    с кодом задачи №1 и задачи №2 тоже проблем нет, объявлены они так
    Код (Text):
    1. TASK_NUMBER_1:
    2.         jmp $
    3.  
    4. TASK_NUMBER_2:
    5.         jmp $
    проблема с кодом обработчика irq0 (шлюз задачи)
    Код (Text):
    1. counter dd 0h
    2.         db 0  
    3. irq0_handler:
    4.  
    5.    .repeat:
    6.     mov edi, Irq0_handler_Tss
    7.  
    8.         virtual at edi
    9.          .edi TSS32 ; структуру объявил сам, с ней тоже вроде проблем нет
    10.         end virtual
    11.  
    12.     cli
    13.  
    14.     inc dword [counter]
    15.  
    16.     mov edx, [counter]
    17.  
    18.     and edx, 011b
    19.     cmp edx, 0
    20.     jz .end_dispatch
    21.     cmp edx, 11b
    22.     jnz @f
    23.     mov [.edi.PreviousTaskLink],MainTask_Selektor
    24.  
    25.     jmp .end_dispatch
    26.    @@:
    27.     cmp edx, 01b
    28.     jnz @f
    29.     mov [.edi.PreviousTaskLink], TASK_NUMBER_1_Selektor
    30.  
    31.     jmp .end_dispatch
    32.    @@:
    33.     cmp edx, 10b
    34.     mov [.edi.PreviousTaskLink],TASK_NUMBER_2_Selektor
    35.  
    36.    .end_dispatch:
    37.     mov  al, 20h
    38.     out  020h, al  
    39.     out  0a0h, al
    40.  
    41.     sti
    42.  
    43.     iretd
    44.     jmp .repeat
    тестирую в Bochs 2.3, проблема в том что программа застревает при первой же генерации прерывания IRQ0.
    c сообщением
    ired : CF
    делал так что бы во всех случаях в поле PreviousTaskLink ставилось значение MainTask_Selektor, всё работало!
    Вопрос: почему не работает, с тремя задачами.
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    бит B в дескрипторе TSS, который соответствует заменяемому селектору, сбрасывается?
    см. 3А, 6.4.2 (Modifying Task Linkages)
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    дескриптор, соответствующий TASK_NUMBER_1_Selektor является busy?
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Возможно, проблема в флаге занятости задачи. Перед тем как выходить в задачу по iret необходимо поставить флаг занятости во входящей задаче. Ну и соответсвенно снять его в той, которая лежит в prev_task, иначе в нее нельзя будет войти повторно.

    rei3er опередил :).
     
  5. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    всё понятно! TASK_NUMBER_1_Selektor у меня НЕ busy (как и TASK_NUMBER_2_Selektor).
    т.е. при выходе по команде iret, в новой задаче должен быть выставлен бит busy.

    и ещё 3A, 6.3 (пункт 4).
     
  6. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    ОПЯТЬ ПРОБЛЕМА!
    теперь почему то не вызывается обработчик прерывания. управление передаётся первой задаче и остаётся там навсегда. После выкидывания лишних наворотов и примочек от ообработчика прерывания осталось вот это :
    Код (Text):
    1. interrupt_mes db "Interupt message  "
    2. counter dd 11111111h  
    3.         db 0
    4.  
    5. irq0_handler:
    6.  
    7.     mov edi, Irq0_handler_Tss
    8.  
    9.     virtual at edi
    10.      .edi TSS32
    11.     end virtual
    12.  
    13.    .repeat:
    14.     inc dword [counter]
    15.            ; передача параметров функции для вывода строки
    16.         mov esi,interrupt_mes ; указатель на ZS строку
    17.         mov al, 0   ;столбец
    18.         mov ah, 4  ;строка
    19.         mov bl, "5" ;цвет символа и цвет фона
    20.         call OutText ;после строки должны выводится четыре закорючки
    21.            ;эта функция работает нормально проблем с ней нет
    22.  
    23.     cli
    24.     xor eax, eax
    25.  
    26.     mov ax, [.edi.PreviousTaskLink]
    27.     call ClearBusyFlag
    28.  
    29.     cmp ax, TASK_NUMBER_1_Selektor
    30.     jz @f
    31.     mov ax, TASK_NUMBER_1_Selektor
    32.     call SetBusyFlag
    33.     mov [.edi.PreviousTaskLink], TASK_NUMBER_1_Selektor
    34.  
    35.     jmp .end_dispatch
    36.    @@:
    37.     mov ax, TASK_NUMBER_2_Selektor
    38.     call SetBusyFlag
    39.     mov [.edi.PreviousTaskLink], TASK_NUMBER_2_Selektor
    40.  
    41.  
    42.    .end_dispatch:
    43.     mov  al, 20h
    44.     out  020h, al  
    45.     out  0a0h, al
    46.  
    47.     sti
    48.  
    49.     iretd
    50.     jmp .repeat
    соглано этому коду обработчик прерывания получив управление первый раз, передаст управление задаче №1, потом по очереди при каждом вызове передавать управление обоим задачам. но так не получается: задача №1 получает управление навсегда (тестил так: кидал в обе задачи код вывода строки, задача №2 строку не выводит, а задача №1 выводит). а обработчик прерывания после первого вызова никогда не получает управление, т.е. после строки "Interupt message " стоят неподвижно 4 закорючки, хотя четыре закорючки должны постоянно изменяться. Задача №1 и №2 пустые: в них только одна команда- jmp $. Функции SetBusyFlag и ClearBusyFlag тестил отдельно, работают нормально.
    У в чем же может быть причина того что обработчик прерывания не вызывается повторно?
     
  7. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Не совсем понял, кто должен печатать "закорючку", если обе задачи состоят из 'jmp $', а обработчик прерывания, судя по коду, печатает строку а одном и том же месте?

    А сам код, вроде, правильный.
     
  8. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    Код (Text):
    1. interrupt_mes db "Interupt message  " ;;здесь нет нуля
    2. counter dd 11111111h      ;; это и есть закорючки  
    3.         db 0 ;; <-----ноль
    counter инкрементится при каждом вызове обработчика, и строка выводится самим обработчиком, отличаться должны только четыре последних "закорючки"
    Код (Text):
    1.          inc dword [counter]
    2. ...............
    3.         call OutText
    проблема не в закорючках (просто ещё нет преобразователя числа в строку), а пролема в том что обработчик вызывается только один раз, т.е. закорючки у меня не меняются, а должны постоянно изменяться (при каждом вызове обработчика).
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    пробуй так
    Код (Text):
    1.     mov  al, 20h
    2.     out  020h, al  
    3.     out  0a0h, al
    4.     sti
    5.     and dword [0FEE000B0h], 0 ;Local APIC EOI
    6. ...
     
  10. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    не помогает :dntknw:
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    rpy3uH
    может в TSS задачи, которой соответствует TASK_NUMBER_1_Selektor, сброшен IF в EFLAGS?
    тогда в контексте этой задачи все маскируемые прерывания запрещены
     
  12. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    rei3er, ты прав! всё заработало!
    БОЛЬШОЕ СПАСИБО ВСЕМ ЗА ПОМОЩЬ!