прерывание 15 неизвесно откуда

Тема в разделе "WASM.BEGINNERS", создана пользователем sorron, 30 май 2010.

  1. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    Здравствуйте!

    Сначала осуществляю переход в защищенный режим, потом настраиваю IDT. При совершении любых неправомерных действий в защищенном режиме вызывается 15е прерывание. Проверял заведомо неправильным кодом:

    Код (Text):
    1. _asm
    2.     {
    3.         mov ax, 0
    4.         mov ss, ax
    5.     }
    Насколько я понимаю должно вызываться #SS (12е)
    Проверено на VMWare и на реальном компе.
    Помогите пожалуйста разобраться.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Возможно, причина "непонятного" вызова int 15 в том, что ты не перенес IRQ вектора - тогда вектора IRQ0-15 (выставленные по дефолту биосовским загрузчиком) перекрывается с векторами исключений Intel. при загрузке выставляется база IRQ0 = 8, тогда IRQ1 = 9, IRQ2 = A, ..., IRQ7 = F.
    Вот у тебя как раз и генерится IRQ7 - скорее всего там сетевая карта какая-нибудь. Или еще какие девайсы.

    Нужно перенести IRQ на вектора > 0x20, создать для них корректные обработчики, делать EOI и все такое.
    Например так:
    Код (Text):
    1. IRQ0_Handler:
    2.     ; timer interrupt
    3.     pusha
    4.     ...
    5.     inc [gTickCount]
    6.     ...
    7.     popa
    8.     jmp CommonEoiHelper
    9.  
    10. IRQ1_Handler:
    11.     ; keyboard interrupt
    12.     ; .. save registers, read-in the byte from PS/2 controller, process scan-code, etc ..
    13.     ....
    14.     jmp CommonEoiHelper
    15.  
    16. ; Common routine that has to be called at the end of IRQ dispatch.
    17. CommonEoiHelper:
    18.     push ax
    19.     mov  al, 20h
    20.     out  020h, al
    21.     out  0a0h, al
    22.     pop  ax
    23.     iretd
    Это в простейшем случае когда мы работаем в режиме эмуляции 8259A.
    Современные ОС должны использовать "продвинутые" Local APIC для назначения прерываниям конкретных номеров векторов, I/O APIC для маршрутизации прерываний к конкретному процессору.

    В любом случае, оставлять биосовский дефолт не выйдет.

    Кстати говоря, ничего не будет сгенерировано. Селектор будет проверен только когда будет выполняться команда, обращающаяся через этот сегментный регистр (в данном случае ss).
    То есть mov ax, 0 / mov ss, ax / push ax сгенерирует исключение не на "mov ss,ax", а на "push ax" - при фактическом обращении. А уж какое исключение (SS,GP,PF) - зависит от того, какой селектор ты записал, есть ли соответствующая ему запись в GDT и какие там права и какое значение ESP и тп..
     
  3. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    Прерывания перенес следующим кодом (у вас на форуме брал):

    Код (Text):
    1. _asm
    2.     {
    3.     mov bx,07870h
    4.     mov dx,0000h
    5.  
    6.  
    7.     mov al,11h
    8.     out 0a0h,al
    9.     out 20h,al
    10.  
    11.     mov al,bh
    12.     out 0a1h,al
    13.     mov al,bl
    14.     out 21h,al
    15.  
    16.     mov al,02
    17.     out 0a1h,al
    18.     mov al,04
    19.     out 21h,al
    20.  
    21.     mov al,01
    22.     out 0a1h,al
    23.     out 21h,al
    24.  
    25.     mov al,dh
    26.     out 0a1h,al
    27.     mov al,dl
    28.     out 21h,al
    29.  
    30.     }
    Я думал, что загружая нулевой селектор всегда исключение буде... Не важно, еще таски неправильно переключал и т. д. - все-равно 15е
     
  4. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    2great.
    mov ax,0 mov ss,ax вызовет эксепшн независимо от обращения к памяти. загрузка селектора в ss обрабатывается по другому нежели остальные сегментные рег-ры.
    хотя есть метод записать в ss (впрочем как и в cs) нулевой дескриптор, sysexit а помощь :)
     
  5. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    2sorron
    Ты где-то в хэндлерах упоролся. По идее инт15 невалидный эксепшн, соответственно проц его сам вызвать не может. Код инициализации PIC корректный, значит где-то лагаешь в хэндлере. Код в студию
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    medstrax1
    Верно, регистр Ss просто загрузкой туда нуля нельзя обнулять(посредством iret тоже):
    При обработке Sysexit проверок нет.
     
  7. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    Вы какой именно хендлер имеете ввиду? Если 15го, то он-то работает нормально:
    Код (Text):
    1. __declspec(naked) void gp()
    2. {  
    3.    // prolog
    4.    _asm
    5.    {
    6.       push ebp
    7.       mov ebp, esp
    8.       sub esp, __LOCAL_SIZE
    9.    }
    10.    {
    11.         sys_con->print("exception");
    12.         for(;;);
    13.    }
    14.    // epilog
    15.    _asm {
    16.       mov esp, ebp
    17.       pop ebp
    18.       iretd
    19.    }
    20.  
    21. }
    На остальных стоит заглушка, которая выводит другое сообщение и тоже входит в бесконечный цикл.
    Но выводит именно exception, потому как intr_table->set_int(15, (void*)gp);
     
  8. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Раз при mov ax,0 mov ss,ax у тебя происходит вызов инт15, то очевидно либо косяк в хэндлере инт12, либо в IDT
     
  9. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    Косяк в IDT, спасибо разобрался.
     
  10. TermoSINteZ

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

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.561
    Адрес:
    Russia
    sorron
    Ну напишите, какой был косяк. Вдруг кто-то столкнется с такой же проблемой.
     
  11. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    Был сдвиг на 2 позиции в IDT. Но проблема глубже, когда разберусь полностью - напишу
     
  12. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    Дурацкая ошибка вышла. Раньше обращался только к полям структур, которые были в стеке, в блоках _asm. И почему-то пришло в голову, что так же можно обращаться и полям объектов. Ошибку спровоцировало:
    Код (Text):
    1. _asm
    2.     {
    3.         mov ebx, inter_table
    Как оказалось, этот код заносит в ebx смещение поля inter_table относительно начала объекта. Правильно будет так:

    Код (Text):
    1. _asm
    2.     {
    3.         mov ebx, this
    4.         lea [ebx+inter_table]
     
  13. sorron

    sorron New Member

    Публикаций:
    0
    Регистрация:
    29 май 2010
    Сообщения:
    7
    точнее так:

    Код (Text):
    1. _asm
    2.     {
    3.         mov ebx, this
    4.         mov ebx, [ebx+inter_table]