Autor Thema: Triple Fault bei Division By Zero  (Gelesen 4897 mal)

Drako

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« am: 22. October 2008, 14:46 »
hallöchen,

also, mit Hilfe dieser beiden Seiten:
http://www.osdever.net/bkerndev/Docs/idt.htm
http://www.osdever.net/bkerndev/Docs/isrs.htm

hab ich versucht mir eine IDT und die ersten 32 ISRs einzurichten.

bis auf geringfügige Namensänderungen hab ich die Sachen aus den Tuts weitestgehend übernommen.
zum Test hab ich ans Ende der main() ein 10 / 0 stehen.
Aber anstatt, dass mein fault_handler() mir die Fehlermeldung zeigt,
startet der Rechner/Bochs einfach neu.

Hier mein Kernel:
#include "screen.h"
#include "multiboot.h"
#include "gdt.h"
#include "idt.h"

int main(struct mbs* pMBS)
{
int div_by_zero;
gdt_install();
idt_install();
clrscr();
set_color(COLOR_LIGHTGREEN);
printstr("DrakOS Version 1.0\n");
printstr("Copyright (C) 2008, Felix Bytow\n\n");
set_color(COLOR_LIGHTGREY);
printstr("Gebootet von: ");
printstr((char*)(pMBS->mbs_boot_loader_name));
div_by_zero = 10 / 0; // Hier bricht alles zusammen
while(true);
return 0;
}

meine IDT:
// idt.h
#if !defined(IDT_H)
#define IDT_H

#include "types.h"

struct idt_entry
{
word offset_low;
word selector;
byte null;
byte flags;
byte offset_high;
} __attribute__((packed));

struct idt_ptr
{
word limit;
dword base;
} __attribute__((packed));

#define IDT_SIZE 256

void idt_fill_descriptor(byte entry, dword base, word sel, byte flags);
void idt_install(void);
void idt_load(void);

void enable_interrupts(void);
void disable_interrupts(void);

#endif


// idt.c
#include "idt.h"
#include "memory.h"
#include "isr.h"

struct idt_entry idt[IDT_SIZE];
struct idt_ptr idtp;

void idt_fill_descriptor(byte entry, dword base, word sel, byte flags)
{
idt[entry].offset_low = (base & 0xFFFF);
idt[entry].selector = sel;
idt[entry].null = 0;
idt[entry].flags = flags;
idt[entry].offset_high = ((base >> 16) & 0xFFFF);
}

void idt_install(void)
{
idtp.limit = (sizeof(struct idt_entry) * IDT_SIZE) - 1;
idtp.base = (dword)&idt;

memset(&idt, 0, sizeof(struct idt_entry) * IDT_SIZE);

isrs_install();
// TODO: Neue Interrupts setzen

idt_load();
}

void enable_interrupts(void)
{
asm("sti");
}

void disable_interrupts(void)
{
asm("cli");
}

und hier die isrs (gekürzt)
// isr.h
#if !defined(ISR_H)
#define ISR_H

#include "types.h"

void isr0(void);
// ...
void isr31(void);

struct regs
{
dword gs, fs, es, ds;
dword edi, esi, ebp, esp, ebx, edx, ecx, eax;
dword int_no, err_code;
dword eip, cs, eflags, useresp, ss;
} __attribute__((packed));

void isrs_install(void);
void fault_handler(struct regs *r);

#endif

// isr.c
#include "isr.h"
#include "idt.h"
#include "screen.h"

void isrs_install(void)
{
idt_fill_descriptor(0, (dword)&isr0, 0x08, 0x8E);
// ...
idt_fill_descriptor(31, (dword)&isr31, 0x08, 0x8E);
}

char *exception_messages[] =
{
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out Of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
// ...
"Reserved"
};

void fault_handler(struct regs *r)
{
if (r->int_no < 32)
{
set_color(COLOR_RED);
printstr(exception_messages[r->int_no]);
printstr(" Exception. System Halted!");
while (true);
}
}

und das Stückchen asm dazu:
global idt_load
extern idtp

idt_load:
    lidt [idtp]
    ret

ich kann beim besten Willen nichts finden, wo meine idt kaputt wäre...

würde mich freuen, wenn mir hier jmd weiterhelfen könnte.

MfG Drako
« Letzte Änderung: 22. October 2008, 15:04 von Drako »

Drako

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 22. October 2008, 14:54 »
auf Grund der geschulten Augen der Leute im IRC ergab sich folgende Korrektur:

// ...
struct idt_entry
{
    word offset_low;
    word selector;
    byte null;
    byte flags;
    word offset_high;
} __attribute__((packed));
// ...

Leider stürzt der Kernel immer noch ab.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #2 am: 28. October 2008, 08:16 »
Nun...
Ich weiß ja nicht, ob das Problem noch besteht...
Folgenden Code hast du gepostet:
void idt_install(void)
{
idtp.limit = (sizeof(struct idt_entry) * IDT_SIZE) - 1;
idtp.base = (dword)&idt;

memset(&idt, 0, sizeof(struct idt_entry) * IDT_SIZE);

isrs_install();
// TODO: Neue Interrupts setzen

idt_load();
}
Allerdings solltest du erst die Funktion zum laden der idt "idt_load" und dann die Funktion zum setzen der ISRs "isrs_install" aufrufen.

Nach dem Tutorial musst du erst die IDT initialisieren und dann die ISRs setzen (so steht das dort). Also müsste die Funktion wie folgt aussehen:
void idt_install(void)
{
idtp.limit = (sizeof(struct idt_entry) * IDT_SIZE) - 1;
idtp.base = (dword)&idt;

memset(&idt, 0, sizeof(struct idt_entry) * IDT_SIZE);

// TODO: Neue Interrupts setzen

idt_load();
isrs_install();
}

Ich hoffe, ich konnte dir damit weiterhelfen.
Gruß Christian

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 28. October 2008, 11:08 »
Nein, nein. Das stimmt schon so.
Das idt_load sollte erst aufgerufen werden, wenn die IDT fertig ist. Und die ISRs werden ja dierekt in die IDT eingetragen(sie ist also noch nicht fertig). Mit initialisieren ist nur die memset-Zeile gemeint.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #4 am: 29. October 2008, 12:04 »
Nun ich mache das wie im Tutorial, da ich dieses auch gelesen habe.  :roll:
Ich rufe bei mir zuerst idt_install() und dann isrs_install() auf und das funktioniert tadellos.
Ich dachte nur, dass es vielleicht daran liegt...

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 29. October 2008, 13:02 »
@Drako:
was sagt denn eigentlich das log von bochs zu der ganzen sache

die logdatei ganzt du mit "log: <file>" in der bochsrc festlegen

„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen