Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - errorM

Seiten: [1]
1
Lowlevel-Coding / Re: Fehler bei GDT: Triple fault
« am: 03. October 2008, 17:02 »
Der Triple Fault wird bei der Ausführung das lgdt-Befehls gemeldet. Ich bin mir aber zu 99% sicher, dass der Fehler nicht im Assembler-Part liegt.
Die GDT-Einträge und der Zeiger sind bei mir Klassenelemente, aber das sollte keine Rolle spielen, da sie ja trotzdem als zusammenhängende Speicherbereiche stehen.

Die Funktion, die einen GDT-Eintrag setzt, sieht folgendermaßen aus:
inline void GDT::set_entry(byte numb,u_dword base,u_dword size,byte access,byte granularity)
{
//move bits...
this->entries[numb].base_1 = (base & 0xFFFF);
this->entries[numb].base_2 = (base >> 16) & 0xFF;
this->entries[numb].base_3 = (base >> 24) & 0xFF;

this->entries[numb].size_1 = (size & 0xFFFF);
this->entries[numb].size_2 = (size >> 16) & 0x0F;

this->entries[numb].size_2 |= granularity & 0xF0;
this->entries[numb].access = access;
return;
}
Der Setup-Code ist der hier:
void GDT::init(void)
{
this->set_entry(0,0,0,0,0);//Null entry
this->set_entry(1,0,0xFFFFFFFF,0x9A,0xCF);//kernel code segment
this->set_entry(2,0,0xFFFFFFFF,0x92,0xCF);//kernel data segment
this->set_entry(3,0,0xFFFFFFFF,0xFA,0xCF);//user code segment
this->set_entry(4,0,0xFFFFFFFF,0xF2,0xCF);//user data segment
return;
}

Der Konstruktor der Klasse:
GDT::GDT(void)
{
//set pointer
this->pointer.limit = (sizeof(gdt_entry_t) * 5) - 1;
this->pointer.base = (u_dword)&entries;

this->init();
setup_gdt((u_dword)&this->pointer);
}
2
Lowlevel-Coding / Fehler bei GDT: Triple fault
« am: 02. October 2008, 16:00 »
Hallo,
ich bin gerade dabei, die GDT zu initialisieren (verwende GRUB, bin also schon im 32bit-Modus). Compiler/Linker meldet auch keinen Fehler. Wenn ich den Kernel dann aber in QEMU starte, bekomme ich einen Triple Fault gemeldet und das Programm beendet sich. Die exakte Fehlermeldung sieht folgendermaßen aus:
qemu: fatal: triple fault
EAX=001f0010 EBX=0002cfe0 ECX=0000000f EDX=001fffae
ESI=0002d147 EDI=0002d14c EBP=001fff68 ESP=001fff5c
EIP=0010066b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     f200ffff 00000027
IDT=     00000000 000003ff
CR0=60000011 CR2=00000000 CR3=00000000 CR4=00000000
CCS=00000028 CCD=001fffd6 CCO=ADDL   
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Aborted

Ich vermute stark, dass es daran liegt, dass ich die von GRUB bereitgestellte GDT irgendwie falsch überschreibe. Irgendwo habe ich mal gelesen, dass man dann einen Triple Fault gemeldet bekommt und der Kernel abstürzt. Leider stand da nicht, wie man es beheben kann.

Die Funktion zum Laden der GDT sieht so aus:
global setup_gdt

setup_gdt:
mov eax,[esp + 4]
lgdt [eax]

mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
jmp 0x08:.ret

.ret
ret
(Als Sprache benutze ich aber C++, diese Funktion wird nur aus einem C++-Programm aufgerufen.) Compiler ist gcc/g++, Assembler nasm und Linker ld.

Der Code für die Struktur eines GDT-Eintrages:
struct gdt_entry_t
{
u_word base_1;
u_word size_1;
byte base_2;
byte access;
byte size_2;
byte base_3;
}__attribute__((packed));
und für den GDT pointer:
struct gdt_pointer_t
{
u_word limit;
u_dword base;
}__attribute__((packed));
Seiten: [1]

Einloggen