Autor Thema: descriptor tables, exceptions und nicht aufloesbare handler  (Gelesen 5119 mal)

hannibal

  • Host
  • Beiträge: 400
    • Profil anzeigen
    • brainsware - the rock.
Gespeichert
hallo,

ich hab ein 'kleines' problem mit meinem kernel. programmiere in C, boote mit grub und versuche gerade GDT und IDT ordentlich zu implementieren. die GDT scheint eigentlich zu funktionieren, aber irgendwie kann ich keine exceptions abfangen..
sch..ustere jetzt schon einige zeit mit diesem problem herum, aber ich kann einfach keinen fehler finden..vielleicht ist es ja nur irgendein denkfehler, den erfahrene leute auf anhieb sehen..

bochs meldet einen triple fault, nachdem ich interrupts aktiviere:

00008144141e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting


desweiteren das registeroutput aus der bochslog:

00008144141i[CPU0 ] protected mode
00008144141i[CPU0 ] CS.d_b = 32 bit
00008144141i[CPU0 ] SS.d_b = 32 bit
00008144141i[CPU0 ] EFER   = 0x00000000
00008144141i[CPU0 ] | RAX=0000000001105fec  RBX=000000000002d100
00008144141i[CPU0 ] | RCX=00000000000000fe  RDX=00000000ff000021
00008144141i[CPU0 ] | RSP=0000000001105fc8  RBP=0000000001105ff0
00008144141i[CPU0 ] | RSI=000000000002d53a  RDI=000000000002d53f
00008144141i[CPU0 ] | IOPL=0 of df IF sf zf af pf cf
00008144141i[CPU0 ] | SEG selector     base    limit G D
00008144141i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00008144141i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00008144141i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00008144141i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00008144141i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00008144141i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00008144141i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00008144141i[CPU0 ] | RIP=00000000011008ff (00000000011008ff)
00008144141i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00008144141i[CPU0 ] | CR3=0x0000000000000000 CR4=0x00000000



von grub aufgerufener code [entry.asm]:
http://80.108.15.143/websvn/filedetails.php?repname=Operating+system+Concept+%27B%27&path=%2Ftrunks%2Fsrc%2Farch%2Fx86%2Fentry.asm&rev=0&sc=0
hier rufe ich kmain auf, nachdem der stack initialisiert wurde und die multiboot infos gepusht sind

kmain.c:
http://80.108.15.143/websvn/filedetails.php?repname=Operating+system+Concept+%27B%27&path=%2Ftrunks%2Fsrc%2Farch%2Fx86%2Fkmain.c&rev=0&sc=0

kmain ( ... ):

void kmain ( MultibootInfo mb ) {
    IDT idt;
    GDT gdt;
    int i;
 
    kinitstdout(WHITE, BLACK);
    initializeGDT(&gdt, 0x90000);
    initializeIDT(&idt, 0x8FF01);
                     
    flushGDT(gdt.pGDT);
   
    for(i = 0; i < 0x0F; i++) {
        addExceptionHandler(&idt, i, exceptionHandler, 0x08);
    }

    for(i = IRQ0; i < 0xFF; i++) {
        addInterruptHandler(&idt, i, interruptHandler, 0x08);
    }

    asm("sti");
   
    i = 0;
    i = 1 / i;
   
        for(;;);
}


die funktion initializeGDT erstellt den GDTpointer mit basisadresse und limit..

void initializeGDT( GDT *gdt, unsigned int base) {
        gdt->pGDT.base = base;
        gdt->pGDT.limit = (sizeof(GDTDescriptor) * 3) - 1;
    gdt->descriptors = (GDTDescriptor *)base;

    // <null descriptor>
    gdt->descriptors[0].limit_low = 0;
    gdt->descriptors[0].base_low = 0;
    gdt->descriptors[0].base_mid = 0;
    gdt->descriptors[0].type_flags = 0;
    gdt->descriptors[0].limit_high_access = 0;
    gdt->descriptors[0].base_high = 0;

    addGDTDescriptor(gdt, 1, 0, 0xFFFFFFFF, SEG_TYPE_CODE_ER, 0,
                                        RING0, 1,
                                        GRANULARITY_4K); // code descriptor
    addGDTDescriptor(gdt, 2, 0, 0xFFFFFFFF, SEG_TYPE_DATA_RW, 0,
                                        RING0, 1,
                                        GRANULARITY_4K); // data descriptor
   
    asm("lgdt %0" : : "m" (gdt->pGDT));

    return;
}


initializeIDT macht im grunde das gleiche, nur eben fuer interrupts..
idt.c:
http://80.108.15.143/websvn/filedetails.php?repname=Operating+system+Concept+%27B%27&path=%2Ftrunks%2Fsrc%2Farch%2Fx86%2Fidt.c&rev=0&sc=0

void initializeIDT ( IDT *idt, unsigned int base ) {
        idt->pIDT.base = base;
        idt->pIDT.limit = 0xFF;
    idt->descriptors = (IDTDescriptor *)base;

        remapPIC(IRQ0);
    asm("lidt %0" : : "m" (idt->pIDT));
}


alles weitere findet sich im websvn in trunks/include/arch/x86 und trunks/src/arch/x86/ ..

waere echt nett, wenn sich das mal jemand ansehen koennte,
danke im vorraus!

lg, hannibal
\\o
o//
\o/

 

Einloggen