прерывания и планировщик

Тема в разделе "WASM.OS.DEVEL", создана пользователем Hell_Knight, 10 окт 2010.

  1. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Это скорее всего происходит из-за аппаратных прерываний. Нужно запретить все необрабатываемые прерывания в контроллере и в добавок поставить заглушки вместо обработчиков. У меня для всех аппаратных прерываний нет ни одного обнуленного дескриптора, только для зарезервированных/неиспользуемых исключений и программных прерываний.
     
  2. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    Я таким образом запретил прерывания:
    Код (Text):
    1. mov     ax, 0xFEFF  ; запрещаем, всё кроме 8-го прерывания
    2. out     0x21, ax
    ошибка перестала вылетать, но и обработчик не обрабатывает
    если делать jmp, туда где лежит обработчик, он отрабатывает
    но если сделать
    Код (Text):
    1. int 8
    я славливаю #GP
     
  3. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    поправка:
    Код (Text):
    1. mov        ax, 0xFFFE    ; запрещаем, всё кроме 8-го прерывания(IRQ0)
    2. out        0x21, ax
    и с тиком таймера #GP
     
  4. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.568
    Адрес:
    Russia
    Hell_Knight
    Если все так плачевно попробуйте заюзать QEMU - в нем дебагер есть. Ну как минимум посмотрите состояние регистров и памяти на момент креша.
    А вообще проверьте
    1) сам код обработчика прерывания (там они немного разные кстати, разное кол-во параметров в стек заносится, в зависимости от типа прерывания).
    2) валидность адресов\страниц

    А вообще че-то я не пойму. Вначале вроде запрещается все, включая NMI. А потом уже разрешаем. А на наоборот. Для теста можете сделать даже так. Запрещаете все аппаратные. И разрешаете одно программное. вызываете int 3 - сработало? Ну и далее по обстоятельствам.
    Ну и покажите код настройки контроллера прерываний.
    А так же поиск по форуму - уже 1000 раз код приводился кстати.
     
  5. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    окей, щас скачаю, просмотрю в чем может быть ошибка...

    В обработчики стоит заглушка:
    вывод красной полоски и
    jmp $
    при прямомо jmp на обработчик всё окей, срабатывает

    на самом деле всё как положено, это я щас отключал, что бы исключить ситуации когда появляется #GP из-за других прерываний
    поэтому оно действительно от тика таймера

    не сработало....
     
  6. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.568
    Адрес:
    Russia
    Значит вот проверяйте правильность адресов, что хранит IDTR после загрузки, что вы имеете в нем, какие адреса. Кажись все дело в том, что вы не по тому адресу записали вашу таблицу. И в итоге оттуда откуда считывается инфа - там пусто. Ну и биты доступа дескрипторов проверьте.
     
  7. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    вот элемент IDT
    Код (Text):
    1. dd  0x00083000
    2. dd  0x00008E00
    параметры:
    Смещение: 0x00003000
    такое, как и должно быть! указывает на планировщик
    если jmp 0x3000 то будет выполнен код планировщика
    Селектор сегмента кода обработчика: 0x0008 (у меня страничная адресация поэтому, на всякий случай посатвил 8, может RPL работает ;) )
    0x8E00 = 10001110 0000
    P = 1
    DPL = 0
    вроде бы всё правильно...

    сохранял обратно IDTR и проверял значения... всё они правильно указывают...

    я же написал процедуру вывода на экран значения 32-битного значения втолкнутого в стэк
    проверял так....
    и в IDT элемент вроде бы правильный...
    значит возможно я неправильно составил элемент дескприптора... ??

    может есть еще какой-то подводный камень в который и упирается всё это ?
    подскажите пожалуйста правильно ли я делаю ?
     
  8. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    щас дополнительно просмотрел запись в таблице страниц куда она указывает:
    0x0009167
    ну как и нужно:
    G = 1 глобальная страница
    A = 1 бит доступа установлен, т. к. к нему мы обратились...
    D = 1 dirty, это же IDT мы в него записывали элементы...
    R/W = 1 страница доступна для чтения/записи
    U/S = 1 страница доступна пользователю и супервизору
    P = 1 бит присутствия

    З.Ы.
    страница с планировщиком (обработчиком IRQ0) обладает такими же параметрами
    0x0003167
     
  9. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.568
    Адрес:
    Russia
    Hell_Knight
    Эх как я не люблю такие записи. Вы хотите чтоб мы все за вас разбирали?
    И так
    разбираем: 0x00083000
    переводим в двоичную: 0000 0000 0000 1000 0011 0000 0000 0000
    Сопоставляем:
    Сегмент селектор: 0000 0000 0000 1000, Смещение (15:00 биты): 0011 0000 0000 0000
    Вроде верно.
    Разбираем сл значение: 0x00008E00
    переводим в двоичную: 0000 0000 0000 0000 1000 1110 0000 0000
    Сопоставляем:
    Смещение (31:16 биты): 0000 0000 0000 0000, P - 1, DPL - 00 , 0, Size Of Gate - 1, 110, 0000 0000
    Тоже верно.
    Далее покажите таблицу вашу GDT которая. Желательно всю.
    А лучше всего - прикрепите код наконец, который у вас не работает.
     
  10. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    у меня ведь страничная адресация...
    оно у меня работало, просто потом бац, и перестало))))
    и хз почему))) аж смешно...

    GDT:
    у меня правильный
    Код (Text):
    1. GDT:
    2. ; нулевой дескриптор
    3. NULL_descr      db      8 dup(0)
    4. ; дескриптор 32-разрядного сегмента кода: база = 0000 0000h, размер = FFFF FFFFh
    5. CODE_descr      db      0xFF, 0xFF, 0x0, 0x0, 0x0, 10011010b, 11001111b, 0x0
    6. ; дескриптор 32-разрядного сегмента данных: база = 0000 0000h, размер = FFFF FFFFh
    7. DATA_descr      db      0xFF, 0xFF, 0x0, 0x0, 0x0, 10010010b, 11001111b, 0x0
    8. ; размер таблицы GDT:
    9. GDT_size        db      $-GDT
    10. GDTR            dw      GDT_size-1
    11.                 dd      ?
    не жалуюсь на него...
     
  11. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    стэк, может как-то влиять ?
    у меня он как в real mode указывал на 0x7c00 так я его до сих пор не менял...
    а при попытки сменить возникает #GP
    я даже для него делал отдельную страничку...
    ну так и оставил на месте
     
  12. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    Скачай GRUB, укажи в нем лог в файл, запусти, произойдет исключение, он вылетит, но в логе будет записана ошибка из-за которой произошло исключение, содержимое регистров и и даже используемые регистры GDT. После этого уже можно некоторые заключения сделать, а так только голову ломать, ошибка может находится в самом неподходящем месте.
     
  13. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    Стек НУЖНО менять сразу после входа в PM, в SS нужно записать селектор данных, в ESP (именно ESP, а не SP!!!) место где он будет храниться + размер, я для начала не рекомендую создавать для стека отдельный сегмент с обратной адресацией - можно легко запутаться, особенно с VM
    конечно если ты сразу хочешь использовать VM, то нужно подготовить страницы для данных, кода, стека... желательно для отладки еще до входа в PM, еще не забудь о различиях в физической адресации и в типе RM сегмент/смещение.
     
  14. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    элемент GDT стэк:
    Код (Text):
    1. ; стэк база 0, лимит максимум
    2. ; S = 1, данные, растет вниз, доступен, чтение/запись
    3. ; DPL = 0; p = 1; AVL = 00; D/B = 1(32-bits); G=1
    4. STACK_descr     dd      0x0000FFFF, 00000000110011111001011100000000b
    вот как я его инициализировал:
    Код (Text):
    1.     mov     ax, 11000b  ; #3 эелемент GDT
    2.     mov     ss, ax
    3.     mov     esp, 0xFFFFFFF0
    в итоге словил неприятный #GP
     
  15. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    извинияюсь болван я)
    установил стэк в то место где код))))
    установил я успешно этот стэк...

    Код (Text):
    1. ; стэк база 0x9000, 0x03FF + 1
    2. ; S = 1, данные, растет вниз, доступен, чтение/запись
    3. ; DPL = 0; p = 1; AVL = 00; D/B = 1(32-bits); G=0
    4. STACK_descr     dd      0x900003FF, 00000000010000001001011100000000b
    а нужно делать стэк шлюзов там ?
    у меня же ведь страничная адресация ?
    дескриптор ведь не юзается...
     
  16. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    Это чего за изобретение? и где(там)?
    Кто сказал, что режим VM отменяет сегментацию? просто по верх сегментов происходит отображение адресов.
    зачем тебе сегментация если ты используешь VM?, хватит всего 2 дескриптора: 1 - для кода, 2 - для данных и стека (база = 0, предел = 4ГБ), не делай обратной адресации в сегменте если не хочешь дважды вступить на одни и те же грабли...
     
  17. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    т. е. работает сразу 2 режима сегментация + страничная ?

    з.ы. поправил, ss инициализировал сегментом данных, в esp пробил нужный адрес + размер

    З.З.Ы. поймите меня правильно, я не халявщик, пришедший за готовым кодом, я просто хочу понять как оно работает, и во что она в данном случае упирается, и из-за чего у меня возникает #GP
    ну или скажите в каком мануале прочитать по этому поводу, в английском немного разбираюсь так что, что-то пойму да пойму
     
  18. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.568
    Адрес:
    Russia
    Hell_Knight
    Не отменяет. Работают оба режима. Просто вы неявно обращаетесь к сегментным регистрам. Вспомните fs:[30h] (если вам это говорит о чем то).
    Ну и да. Без стека нельзя. Сразу его делайте как сегмент данных, так что вам правильно подсказали. И #GP скорее всего из-за того, что прерывания, если вы помните, ложат в стек инфу, код\ адрес возврата\флаги. В общем почитайте маны интела . И про #GP там есть инфа.
    И в конце концов. Вы отладчик включите наконец?
     
  19. Hell_Knight

    Hell_Knight New Member

    Публикаций:
    0
    Регистрация:
    3 ноя 2009
    Сообщения:
    51
    ну конечно знаю =) если бы не знал, я бы не брался за разработку ОС
    из селектора, который в fs извлекается идентификатор дескриптора (15..3 биты)
    далее по адресу: смотрим куда указывает GDTR + идентификатор дескриптора * 8 элемент GDT
    в нём смотрим базовый адрес + смещение
    в данном случае смещение 30h
    да я бы с радостью, но к сожалению, другими виртуальными машинами, кроме VMware я пользоваться не умею...
    в qemu что-то не так настроил, запустилось и машина вылетела с ошибкой
    в boch тоже не догнал с настройками, вроде бы указываю верно грузиться с образа жесткого диска, так всёравно так и не грузится...
    в grub, его еще чем-то нужно скомпилировать, не знаю чем...
    P.S. единственное чего не знаю так это что такое TSS всё остальное мне известно
     
  20. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    TSS - Task Segment State - сегмент состояния задачи, структура куда процессор сохраняет контекст задачи(регистры, etc) при переключении задачи, при этом состояние новой задачи он восстанавливает из сегмента на который указывает селектор для новой задачи. Сама структура TSS формируется в ОЗУ, также в GDT(LDT для задач неприменим) формируется дескриптор особого формата задачи указывающий на TSS в памяти. Ну собственно по селектору куда попал дескриптор TSS и происходит переключение задачи, например far jmp [selector]:[смещение любое - все равно игнорируется], также существуют и другие способы переключения задач, существует понятие вложенной задачи, т.е. вызывается call far как процедура и возвращает управление в вызвавшую ее задачу. А вообще переключение задач - дело творческое для разработчика оси, я например (давно уже это было...) использовал обычный far jmp...