Paging funktioniert in meinem System schon wunderbar, bin jetzt aber auf ein seltsames Problem gestoßen:
Anfänglich habe ich immer die echten Adressen meines Kernels gemapt, also der Kernel wurder direkt hinter dem Bootsektor geladen (0x7E00) und die Pages wurden auf die echten Adressen gesetzt. (Virtuelle Adresse 0x7E00 = Phy. Adresse 0x7E00)
Ich habe dann auch ein par andere Sachen getestet, wie etwa den Videospeicher über eine andere Virtuelle Adresse zu benutzen. Es funktionierte bis hierhin alles wunderbar!
Jetzt sollte der Adressbereich des Kernel (ganz der Mode nach) auf den 3. GiB gelegt werden. (Virtuelle Adresse: 0xC0000000)
Das einschalten und springen soll natürlich in einem Rutsch passieren:
- DT, PTs erstellen
- CR3 und CR0 setzen
- Sprung zur neuen Adresse
first_DT_rm=0x100000
first_PT_rm=0x101000
;Virtuelle Adresse 0 zeigt über PT auf 0
;Wenn dieser Abschnitt auskommentiert wird, funktioniert es nicht mehr! :/
mov dword[first_DT_rm ],first_PT_rm
or dword[first_DT_rm ],111b
;Virtuelle Adresse 0xC0000000 zeigt über PT auf 0
mov dword[first_DT_rm+0xC00],first_PT_rm
or dword[first_DT_rm+0xC00],111b
;erstellen der PT-Einträge
mov eax,first_PT_rm
mov ebx,111b
more:
mov [eax],ebx
add ebx,0x1000
add eax,4
cmp ebx,(0x1000*0x100)+111b
jne more
;setzen von CR3 und CR0
mov eax,first_DT_rm
mov cr3,eax
;enable pagingbit in cr0
mov eax,cr0
or eax,0x80000000
mov cr0,eax
;Pagin aktivieren indem auf die neue Adresse gesprungen wird
mov eax,proceed_paging
push cs
push eax
retf
org $+0xC0000000 ;3 GiB Kernelspace
proceed_paging:
;Über die Virtuelle Adr auf den Bildschirm zugreifen
mov byte[es:0xB8000+0xC0000000],'X'
jmp $
Das seltsame ist: wenn ich die Virtuelle Adresse 0 nicht auch auf 0 umleite gibt es einen Pagefault. Aber anhand des Zugriffs auf den Grafikspeicher kann ich sehen, dass das Paging über 0xC0000000 funktioniert.
Als Assembler benutze ich FASM.