Autor Thema: probleme mit paging... triple fault  (Gelesen 5441 mal)

VooDoo

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« am: 02. September 2009, 11:15 »
Hallo erstmal

ich habe ein paar probleme, wenn ich das Paging-Bit setze...
ich mach so ziemlich genau das, was in diesem tut steht und habs einfach mal übernommen, um damit ein bisschen rumzuspielen und es zu verstehen
http://wiki.osdev.org/Higher_Half_With_GDT

das läuft auch alles super, bis ich das Paging-Bit setze. Danach schmiert mir das ding mit nem triple fault ab...

ich hab nun versucht (weil ichs irgendwie schöner finde), von dem C-code wieder zurück in die asm datei zu gehen und dort die cr3 und cr0 sachen zu machen...

paging.c
unsigned long kernelpagedir[1024] __attribute__ ((aligned (4096)));
unsigned long lowpagetable[1024] __attribute__ ((aligned (4096)));
 
extern void paging();

void *kernelpagedirPtr = 0;
void init_paging()
{
void *kernelpagedirPtr = 0;
void *lowpagetablePtr = 0;
int k = 0;
 
kernelpagedirPtr = (char *)kernelpagedir + 0x40000000;
lowpagetablePtr = (char *)lowpagetable + 0x40000000;
 
for (k = 0; k < 1024; k++)
{
lowpagetable[k] = (k * 4096) | 0x3;
kernelpagedir[k] = 0;
}
 
 
kernelpagedir[0] = (unsigned long)lowpagetablePtr | 0x3;
kernelpagedir[768] = (unsigned long)lowpagetablePtr | 0x3;
 
paging();
}

der asm abschnitt:
global paging
extern kernelpagedirPtr

paging:
    push eax
    mov eax, [kernelpagedirPtr]
    mov cr3, eax
    mov eax, cr0
    or eax, 0x80000000
    mov cr0, eax
    pop eax
    ret

qemu liefert mir:
IN:
0x00100381: mov %cr0,%eax
0x00100384: or $0x80000000,%eax
0x00100389: mov %eax,%cr0

IN:
0x0010038c: pop %eax
0x0010038d: ret

IN:
0x0010038c: pop %eax
0x0010038d: ret

check_exception old: 0xffffffff new 0xe
    0: v=0e e=0000 i=0 cpl=0 IP=0008:c010038c pc=0010038c SP=0010:ffffffc8 CR2=3fffffc8
EAX=e0000011 EBX=c0106000 ECX=c0105000 EDX=003ff003
ESI=0002c736 EDI=0002c737 EBP=ffffffe8 ESP=ffffffc8
EIPc010038c EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 40000000 ffffffff 40cf9300
CS =0010 40000000 ffffffff 40cf9300
SS =0010 40000000 ffffffff 40cf9300
DS =0010 40000000 ffffffff 40cf9300
FS =0010 40000000 ffffffff 40cf9300
GS =0010 40000000 ffffffff 40cf9300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT=     00100006 00000017
IDT=     00000000 000003ff
CR0=e0000011 CR2=3fffffc8 CR3=00105000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000400 CCD=e0000011 CCO=LOGICL
check_exception old: 0xe new 0xd
    1: v=08 e=0000 i=0 cpl=0 IP=0008:c010038c pc=0010038c SP=0010:ffffffc8 EAX=e0000011
EAX=e0000011 EBX=c0106000 ECX=c0105000 EDX=003ff003
ESI=0002c736 EDI=0002c737 EBP=ffffffe8 ESP=ffffffc8
EIP=c010038c EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 40000000 ffffffff 40cf9300
CS =0010 40000000 ffffffff 40cf9300
SS =0010 40000000 ffffffff 40cf9300
DS =0010 40000000 ffffffff 40cf9300
FS =0010 40000000 ffffffff 40cf9300
GS =0010 40000000 ffffffff 40cf9300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT=     00100006 00000017
IDT=     00000000 000003ff
CR0=e0000011 CR2=3fffffc8 CR3=00105000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000400 CCD=e0000011 CCO=LOGICL
check_exception old: 0x8 new 0xd
Triple Fault

ich vermute, dass er zwar das paging macht und das auch richtig aufsetzt, aber dann irgendwie ein page-fault ensteht, den ich nicht abfange -> double fault -> triple fault
ich weiß allerdings nicht wo, wie oder warum...
wär super, wenn ihr mir nen bisschen helfen könntet...
THX

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. September 2009, 11:30 »
Hi,

Zitat
ich weiß allerdings nicht wo, wie oder warum...
Das wo lässt sich zumindest beantworten: Aus dem Registerdump zum Pagefault kannst du ablesen, dass die Instruktion an der Adresse  EIP=c010038c den Pagefault beim Zugriff auf die Adresse CR2=3fffffc8 verursacht.

Damit ist die schuldige Instruktion pop %eax, und der Fehler ist der Zugriff auf den Stack (und nicht das Holen der Instruktion, sonst wäre CR2=EIP). Das heißt du solltest dir mal anschauen, was mit dem Stack los ist. Der Wert von ESP = ffffffc8 sieht falsch aus. Setzt du den auf sys_stack wie in dem Beispiel?

Ich vermute ESP wird irgendwo auf 0 gesetzt, und durch die Funktionsaufrufe erhält es irgendwann diesen Wert. Das heißt dann vermutlich auch, dass der Stack ins Leere geschrieben wurde  (wenn du nicht gerade 3GB Speicher hast). Das heißt kein pop oder ret würde ein korrektes Ergebnis liefern.
« Letzte Änderung: 02. September 2009, 11:35 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

VooDoo

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 02. September 2009, 11:39 »
den stack setzte ich ganz am anfang, nachdem mich grub lädt
[BITS 32]
global start
start:
    mov esp, _sys_stack
    ...

SECTION .bss
    resb 4096
_sys_stack:


eigentlich genauso wie im tut...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 02. September 2009, 12:02 »
hm ...

dann muss da irgendwo bei der Ausführung was schieflaufen. Kannst du mal mit Bochs oder GDB an Qemu durch den Code durchsteppen und schauen was so alles mit dem Stackpointer bzw. dem Stack geschieht? Oder alternativ die Kernel-Binary und evtl. den Code hochladen und ich schau mir das mal an?
« Letzte Änderung: 02. September 2009, 12:04 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

VooDoo

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 02. September 2009, 16:27 »
ich hab den fehler gefunden...
ich weiß nich warum, aba ich hab nach dem laden der trickgdt den stack verschoben... :oops: noch vor call main

mov esp, [_sys_stack + 2]
eine zeile...
vielen dank

 

Einloggen