"Einfaches Paging" aktivieren
-
Hallo zusammen,
ich möchte in meinem Programm Paging aktivieren und wie es zu erwarten war
streikt die CPUHier mal mein Vorgehen:
1. Die Page Tabelle muss an einer 4096 KByte Grenze ausgerichtet sein.
dazu habe ich die Einträge beginnend ab Adresse 0x2.000.000 geschrieben.2. Um den gesamten 4GB abzubilden habe ich in einer Schleife 1.000.000
Einträge a 4 Byte geschrieben3. Aufbau der Einträge:
0. 00000000000000000000 000000000111
1. 00000000000000000001 000000000111
2. 00000000000000000010 000000000111
3. 00000000000000000011 000000000111
4. 00000000000000000100 000000000111
5. 00000000000000000101 000000000111
6. 00000000000000000111 000000000111usw... die oberen 20 Bit werden immer mit 4096 addiert, bei den unteren 12 Bit
sind nur BIT 0 - 2 gesetzt.
Bit 0 = Page Present
Bit 1 = R/W
Bit 2 = U/S4. Im CR3 Register setze ich das 25. BIT für die Adresse von 32MB
5. Im CR0 aktiviere ich das 31. BIT für die Pagingeinheit
enable_paging: mov edi, 0x2000000 ;EDI mit 32MB laden als Beginn der Pages mov edx, 0x7 ;EDX mit den letzten 3 gesetzten BIT laden (7) mov esi, 0x1000 ;ESI mit 4096 laden = Steigerungswert mov ecx, 0xF4240 ;ECX ist der Zähler mit 1.000.000 xor eax, eax ;EAX löschen .write_entry: or eax, edx ;letzten 3 BIT in EAX setzen stosd ;Eintrag schreiben and eax, 0xFFFFFFF8 ;letzten 3 BIT wieder löschen add eax, esi ;EAX + ESI = EAX = EAX + 4096 loop .write_entry mov ebx, cr3 ;CR3 nach EBX and ebx, 0xFFF ;von EBX nur die letzten 12 BIT behalten, Rest löschen mov eax, 0x2000000 ;EAX mit 32MB laden or eax, ebx ;untere 12 BIT von EBX (= reserviert) eintragen mov cr3, eax ;CR3 zurückschreiben mov eax, cr0 or eax, 0x80000000 ;BIT 31 setzen für PG Einheit mov cr0, eax ret
Das Unterprogramm selbst ist in CLI und STI eingeschlossen...
Zur Zeit des einschaltens habe ich nur zwei Segmente zu je 4GB für Code und
Daten. Mein vorhandener physischer Speicher ist 1024MB.Ist der Aufbau der Einträge richtig?
Wo liegt hier der Fehler beim einschalten?
Bevor ich mich und euch hier abmühe hier noch der Grund für Paging in meinem
Programm.Es geht mir um den LFB der VESA Grafikmodi.
Dieser LFB wird beim einschalten eines solchen knapp unter die 4GB Marke
eingeblendet. Mit 1024 MB ist dieser nicht zu erreichen.
Ist es überhaupt möglich diesen Speicherbereich "umzulenken" auf z.B. 64MB?Den DMA Controller interessiert Paging nämlich überhaupt nicht.
Danke und Gruß
Nicky
-
Hallo nochmal,
habe die 1024 Einträge für das Page Directory vergessen...
enable_paging: ; 1 Mio Page Frames anlegen mit einem Steigerungswert von 4096 ; ab Adresse 32MB mov edi, 0x2000000 ;EDI mit 32MB laden als Beginn der Pages mov edx, 0x7 ;EDX mit den letzten 3 gesetzten BIT laden (7) mov esi, 0x1000 ;ESI mit 4096 laden = Steigerungswert mov ecx, 0xF4240 ;ECX ist der Zähler mit 1.000.000 xor eax, eax ;EAX löschen .write_entry: or eax, edx ;letzten 3 BIT in EAX setzen stosd ;Eintrag schreiben and eax, 0xFFFFFFF8 ;letzten 3 BIT wieder löschen add eax, esi ;EAX = EAX + 4096 loop .write_entry ;ab hier das Page Directory anlegen Size = 4KByte mit einem Steigerungswert von 4096 ;als Inhalt wird bei Adresse 32MB begonnen an der die Page Tables liegen mov edi, 0x1800000 ;Page Directory ab Adresse 24MB xor eax, eax mov edx, 0x2000000 ;Inhalt beginnend mit 32MB mov esi, 0x1000 ;Steigerungswert von 4096 mov ecx, 0x400 ;1024 Durchläufe .write_pd: mov eax, edx or eax, 3 ;OR 3 = BIT 0 und 1 setzen damit die Page für die CPU im Speicher liegt und keine Fehler erzeugt wird stosd add edx, esi loop .write_pd ;ab hier werden CR0 und CR3 mit Basisadresse der Page Directorys beschrieben (24MB) ;und BIT 31 für Paging gesetzt mov eax, 0x1800000 ;EAX mit 24MB laden mov cr3, eax ;CR3 zurückschreiben mov eax, cr0 or eax, 0x80000000 ;BIT 31 setzen für PG Einheit mov cr0, eax ret
Nun funktioniert mein Programm wie vor aktivem Paging
Nicky