OSDev

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

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




Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
СообщениеДобавлено: 08 мар 2013, 03:15 

Зарегистрирован: 08 мар 2013, 03:02
Сообщения: 1
Доброго времени суток. Для начала вопрос. Какое минимальное число обработчиков прерываний нужно установить после перехода в защищенный режим? что я должен сделать, дабы безопасно поднять флаг 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(;;);
}


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

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Судя по логу это внешнее прерывание таймера.
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;



Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

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


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

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


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

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