OSDev http://osdev.su/ |
|
GPF и DF исключения? или внешние прерывания? http://osdev.su/viewtopic.php?f=6&t=707 |
Страница 1 из 1 |
Автор: | Tormozzz [ 08 мар 2013, 03:15 ] |
Заголовок сообщения: | GPF и DF исключения? или внешние прерывания? |
Доброго времени суток. Для начала вопрос. Какое минимальное число обработчиков прерываний нужно установить после перехода в защищенный режим? что я должен сделать, дабы безопасно поднять флаг IF? Теперь суть проблемы - гружу загрузчик, читаю дискету, нахожу вторичный загрузчик(он же ядро), перехожу в защищенный режим, далее кидаю ядро в 0х200000 и перехожу на си код. и все бы хорошо, если бы я в один прекрасный момент не захотел бы разрешить прерывания... =( или, если судить по EXT = 1 векторе, то это внешние прерывания? я, кажется, совсем запутался =( лог бокса - Код: 00016171228d[CPU0 ] protected mode activated 00016171237d[CPU0 ] inhibit interrupts mask = 3 00016171237i[MEM0 ] allocate_block: block=0x2 used 0x3 of 0x20 00016202818i[MEM0 ] allocate_block: block=0x1 used 0x4 of 0x20 00016246945d[CPU0 ] inhibit interrupts mask = 1 00016263781d[CPU0 ] interrupt(): vector = 08, TYPE = 0, EXT = 1 00016263781e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08) 00016263781d[CPU0 ] exception(0x0d): error_code=0042 00016263781d[CPU0 ] interrupt(): vector = 0d, TYPE = 3, EXT = 1 00016263781e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d) 00016263781d[CPU0 ] exception(0x0d): error_code=006a 00016263781d[CPU0 ] exception(0x08): error_code=0000 00016263781d[CPU0 ] interrupt(): vector = 08, TYPE = 3, EXT = 1 00016263781e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08) 00016263781d[CPU0 ] exception(0x0d): error_code=0042 00016263781i[CPU0 ] CPU is in protected mode (active) 00016263781i[CPU0 ] CS.mode = 32 bit 00016263781i[CPU0 ] SS.mode = 32 bit 00016263781i[CPU0 ] EFER = 0x00000000 00016263781i[CPU0 ] | EAX=00000000 EBX=00000002 ECX=0000006b EDX=0010010f 00016263781i[CPU0 ] | ESP=0000ffe8 EBP=0000fff8 ESI=000110f5 EDI=00210000 00016263781i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf AF PF cf 00016263781i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D 00016263781i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 00016263781i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 00016263781i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 00016263781i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1 00016263781i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 00016263781i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 00016263781i[CPU0 ] | EIP=002003da (002003da) 00016263781i[CPU0 ] | CR0=0x60000011 CR2=0x00000000 00016263781i[CPU0 ] | CR3=0x00000000 CR4=0x00000000 00016263781i[CPU0 ] 0x00000000002003da>> mov dword ptr ss:[ebp-4], 0x00000000 : C745FC00000000 00016263781e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting 00016263781i[SYS ] bx_pc_system_c::Reset(HARDWARE) called 00016263781i[CPU0 ] cpu hardware reset переходничок на си код Код: use32 [EXTERN kernel_main] [GLOBAL _start] _start: mov esp, 0x200000 - 4 call kernel_main и мэин ядра Код: #include "./headers/interrupts.h"
#include "./headers/scancodes.h" #include "./headers/interrupts/keyboard.h" #include "./ktty.h" void kernel_main() { InitTty(); Clear(); PutString("C code running...?\n"); InitInterrupts(); InstallInterrupt(0x20, &irq_timer, 0x8e); InstallInterrupt(0x21, &irq_keyboard, 0x8e); EnableInterrupts(); for(;;); } |
Автор: | pavia [ 08 мар 2013, 09:11 ] |
Заголовок сообщения: | Re: GPF и DF исключения? или внешние прерывания? |
Судя по логу это внешнее прерывание таймера. 1) Ошибка один. Кто-то забыл перепрограммировать PIC и ловит прерывание там где должны быть исключение. 2) Ошибка два. gate descriptor is not valid sys seg. Дескриптор IDT[8] имеет не корректный системный сегмент. 3) Ошибка три. gate descriptor is not valid sys seg. Дескриптор IDT[13] имеет не корректный системный сегмент. 4) далее так как это двойная ошибка вызывается #DF вызывается IDT[8]. 5) Далее идёт тройная ошибка и проц перезагружается. Цитата: режим? что я должен сделать, дабы безопасно поднять флаг IF? IDT корректно настроить. Но я бы посоветовал потратить время и сделать нормальную обработку исключений который переводит ваше ядро в режим отладчика. Код: procedure Init; begin // Устанавливаем для IRQ0-IRQ7 номера прерываний 20h-27h // Устанавливаем для IRQ8-IRQ15 номера прерываний 28h-2Fh PICInit; Set_GDT_IDT; Load_GDTR_IDTR; EnableInt; end; Цитата: Какое минимальное число обработчиков прерываний нужно установить 30h Примерно вот так. Код: procedure exc_0D;
asm test DWord [esp+12],20000h // Проверяем VM флаг jz @err // ошибка исключение @err: PUSH EAX MOV EAX,0Dh CALL dbgAftoException; POP EAX IRETD end; procedure exc_0E; asm PUSH EAX MOV EAX,0Eh CALL dbgAftoException; POP EAX IRETD end; procedure InitIDT; begin // Исключения IDT[$00]:=ExceptionDescriptor(@exc_00); IDT[$01]:=ExceptionDescriptor(@exc_01); IDT[$02]:=ExceptionDescriptor(@exc_02); IDT[$03]:=ExceptionDescriptor(@exc_03); IDT[$04]:=ExceptionDescriptor(@exc_04); IDT[$05]:=ExceptionDescriptor(@exc_05); IDT[$06]:=ExceptionDescriptor(@exc_06); IDT[$07]:=ExceptionDescriptor(@exc_07); IDT[$08]:=ExceptionDescriptor(@exc_08); IDT[$09]:=ExceptionDescriptor(@exc_09); IDT[$0A]:=ExceptionDescriptor(@exc_0A); IDT[$0B]:=ExceptionDescriptor(@exc_0B); IDT[$0C]:=ExceptionDescriptor(@exc_0C); IDT[$0D]:=ExceptionDescriptor(@exc_0D); IDT[$0E]:=ExceptionDescriptor(@exc_0E); IDT[$0F]:=ExceptionDescriptor(@exc_0F); IDT[$10]:=ExceptionDescriptor(@exc_10); IDT[$11]:=ExceptionDescriptor(@exc_11); IDT[$12]:=ExceptionDescriptor(@exc_12); IDT[$13]:=ExceptionDescriptor(@exc_13); IDT[$14]:=ExceptionDescriptor(@exc_14); IDT[$15]:=ExceptionDescriptor(@exc_15); IDT[$16]:=ExceptionDescriptor(@exc_16); IDT[$17]:=ExceptionDescriptor(@exc_17); IDT[$18]:=ExceptionDescriptor(@exc_18); IDT[$19]:=ExceptionDescriptor(@exc_19); IDT[$1A]:=ExceptionDescriptor(@exc_1A); IDT[$1B]:=ExceptionDescriptor(@exc_1B); IDT[$1C]:=ExceptionDescriptor(@exc_1C); IDT[$1D]:=ExceptionDescriptor(@exc_1D); IDT[$1E]:=ExceptionDescriptor(@exc_1E); IDT[$1F]:=ExceptionDescriptor(@exc_1F); // Внешние прерывания IDT[$20]:=ExtDescriptor(@Timer_int); IDT[$21]:=ExtDescriptor(@Keyb_int); IDT[$22]:=ExtDescriptor(@dummy_IRETD0); IDT[$23]:=ExtDescriptor(@dummy_IRETD0); IDT[$24]:=ExtDescriptor(@dummy_IRETD0); IDT[$25]:=ExtDescriptor(@dummy_IRETD0); IDT[$26]:=ExtDescriptor(@dummy_IRETD0); IDT[$27]:=ExtDescriptor(@dummy_IRETD0); IDT[$28]:=ExtDescriptor(@dummy_IRETD1); IDT[$29]:=ExtDescriptor(@dummy_IRETD1); IDT[$2A]:=ExtDescriptor(@dummy_IRETD1); IDT[$2B]:=ExtDescriptor(@dummy_IRETD1); IDT[$2C]:=ExtDescriptor(@dummy_IRETD1); IDT[$2D]:=ExtDescriptor(@dummy_IRETD1); IDT[$2E]:=ExtDescriptor(@dummy_IRETD1); IDT[$2F]:=ExtDescriptor(@dummy_IRETD1); // Програмное прерывание, сервис ОС IDT[$7F]:=ProgDescriptor(@Int_7Fh); end; |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |