Autor Thema: paging: Wo muss ich den Fehler suchen?  (Gelesen 3773 mal)

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« am: 22. March 2008, 12:32 »
Hi
Wenn ich in nachträglich reservierten Speicher schreibe, gibts nen pagefault.

Zu beginn (befor paging aktiviert wird) lege ich 3 4MB-Pages an, und der rest wird mit pagetables gefüllt. Nachdem ich dann paging aktiviert habe, kann ich an den entsprechenden stellen dann auch schreiben.
Wenn ich jetzt eine neue page reservieren möchte wird, eine freie gesucht, und alle PTs durchgegangen, bis ein freier Platz für diese page gefunden wurde.

Soweit zur theorie.

Nun zum genauen ablauf:
0x00000000 bis 0x00C00000 sind durch die 3 4MB-Pages reserviert (die adressen sind physikalisch als auch virtuell die selben)
Nun möchte ich eine neue 4KB-Page reservieren. Als freie Page bekomme ich 0x00C00000 - also die 1. Page nach dem 12MB-Block. Das ist soweit richtig. Nachdem ich die Page nun ihre position in der Pagetable gefunden hat, bekomme ich folgende virtuelle adresse: 0x00C00000 - Auch richtig. 4. Pagetable, 1. Eintrag.
Flags für die Pagetable und Page: (PG_PRESENT | PG_WRITEABLE | PG_USERACCRESS) - Flags müssen stimmen, da ich die auch bei den 4MB-Pages verwende.

Zusammengefasst:
Physikalische adresse passt.
Virtuelle adresse passt.

* Warum gibt es jetzt einen Pagefault?
* Ich habe der Pagetable die selben flags gegeben, wie einer presenten page. Das ist doch richtig oder?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 22. March 2008, 15:44 »
wenn du bochs( mit debugger ) benutzt
kannst du dir mit
info tabanzeigen lassen wie die Pages gemapt sind.
Vermutlich wird da der Fehler liegen. Die Flags sehen auf den ersten Blick korrekt aus.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 22. March 2008, 17:03 »
Ansonsten könnten vielleicht cr2 (geht wirklich der Zugriff schief, den du verdächtigst?) und der Fehlercode nützlich sein. Letzteres gibt Hinweise, was denn genau falsch war (Page nicht present? Fehlende Rechte?). Und wenn das nichts bringt, mußt du halt doch mal den Code herzeigen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #3 am: 22. March 2008, 18:14 »
1. Ich habe bochs ohne debugger
2. Ich schaffe es nicht, den neustart nach der exception zu verhindern (deshalb kann ich keine registerinhalte nenen)
Wie kann ich das verhindern?
3. Ich könnte euch den Code zeigen, wenns hilf, ist allerdings ne Menge...
Was ist denn da interessant??

Zunächst mal zum Inhalt des PDs:
Erstellt mit einer REOS-Internen Funktion
---KERNEL-PAGE-DIRECTORY---
PT0000 > 4MB Page
PT0001 > 4MB Page
PT0002 > 4MB Page
PT0003
    0x00C00007
    PG_NULL
    PG_NULL
...
Die 3 4MB-Pages und die hinzugefügte Page

Bochs meldet "exception(): 3rd (13) exception with no resolution..."

Die ursache:
BYTE *byte = paging::kpalloc(1);
 byte[0] = 0x00;
bein =0x00 stürtzt es ab...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 22. March 2008, 18:56 »
2. Ich schaffe es nicht, den neustart nach der exception zu verhindern (deshalb kann ich keine registerinhalte nenen)
Wie kann ich das verhindern?
Du könntest einen aktuellen qemu benutzen. Der bricht nach einem Triple Fault komplett ab und gibt die Registerinhalte aus. An erster Stelle solltest du den Triple Fault vermeiden, dann gibt es auch keinen Reboot. ;)

Zitat
3. Ich könnte euch den Code zeigen, wenns hilf, ist allerdings ne Menge...
Was ist denn da interessant??
Das, was das Mapping macht und die Paging-Initialisierung.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #5 am: 22. March 2008, 19:04 »
So, zunächst die Register... 

Manchmal kann die Lösung soo einfach sein :-D

Und der Code:
PD ist die Adresse des Kernel-Pagedirectorys
page ist die Physikalische Adresse der freien Page
in vaddress wird die Virtuelle adresse zurückgegeben
int InstallPage_4K(DWORD *PD, DWORD page, DWORD *vaddress)
{
 for(DWORD i=0; i<MAX_PD_ENTRYS; i++) //alle PTs durchgehen
 {
  DWORD *PT;
  PT = (DWORD*) PD[i];

  //Prüfen, ob hier ne 4MB page hängt
  if(((DWORD)PT&0x00000087) == PG_REOSDEFAULT_BIG) ///4MB Page, hier ist kein platz
  {
   continue;
  }
  if(((DWORD)PT) == PG_NULL) ///!keine PT? darf beim kernel nicht mehr vorkommen
  {
   return PGERR_INVALIDPT;
  }


  for(DWORD j=0; j<MAX_PT_ENTRYS; j++)//Freien Eintrag in der PT suchen
  {
   if(PT[j] == PG_NULL)
   {
    PT[j] = page | PG_REOSDEFAULT; //4KB Page einfügen
//PG_REOSDEFAULT == (PG_PRESENT | PG_WRITEABLE | PG_USERACCRESS)
    *vaddress = GenerateVirtualAddress((DWORD)i, (DWORD)j); //Und addresse erzeugen
    return PGERR_NOERROR;
   }
  }//PT
 }//PD

 return PGERR_FULLPAGETABLE;
}

---edit---
Ich sehe gerade der der eip unterhalb der 10MB liegt... Der Kernel beginnt bei 10MB...

Auszug aus dem log den ich per RS232 sende:
kpalloc: OK
isr14
EXCEPTION: PageFault

---edit2---
Auch wenn die Falsche adresse im eip es vermuten lässt, kpalloc wird korrekt verlassen. Nach dem Verlassen von kpalloc stimmt der eip noch.

---edit3---
Der eip-wert stimmt nicht. Das ist ein Fehler in der regdump-funktion. Aber alle anderen Werte stimmen
« Letzte Änderung: 23. March 2008, 20:18 von RedEagle »

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #6 am: 23. March 2008, 21:10 »
Fehler gefunden :)
Der Pagetable-eintrag im Pagedirectory ist falsch...


Trotzdem Danke für eure Hilfe

Mist, stimmt doch :(

Eintrag im PD: 0x00404007
und an 0x00404000 (physik.) liegt der Wert  0x00C00007

---
Könnte es damit zusammenhängen, ich eine 4MB-Page habe, die an 0x00400000 liegt? - Also die PT auch eine virtuelle adresse hat?
« Letzte Änderung: 23. March 2008, 21:46 von RedEagle »

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #7 am: 24. March 2008, 16:48 »
So habe die InstallPage_4k etwas geändert:
//...

   if(PT[j] == PG_NULL)
   {
    PT[j] = page | PG_REOSDEFAULT; //4KB Page einfügen
    *vaddress = GenerateVirtualAddress((DWORD)i, (DWORD)j); //Und addresse erzeugen

    __asm__ volatile("invlpg %0"::"m" ((char *)(page))); // DWORD page
    return PGERR_NOERROR;
   }

//...

leider bringt das auch nichts :(

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #8 am: 24. March 2008, 17:30 »
 :-) :-) Ich hab den Fehler endlich Gefunden:

KernelPageDirectory += PG_REOSDEFAULT;
Was 3 Bit so alles anrichten können :D

 

Einloggen