"Einfaches Paging" aktivieren



  • Hallo zusammen,

    ich möchte in meinem Programm Paging aktivieren und wie es zu erwarten war
    streikt die CPU 🙄

    Hier 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 geschrieben

    3. Aufbau der Einträge:

    0. 00000000000000000000 000000000111
    1. 00000000000000000001 000000000111
    2. 00000000000000000010 000000000111
    3. 00000000000000000011 000000000111
    4. 00000000000000000100 000000000111
    5. 00000000000000000101 000000000111
    6. 00000000000000000111 000000000111

    usw... 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/S

    4. 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


Anmelden zum Antworten