Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Osbios am 19. February 2006, 11:06
-
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.
-
Ich habe noch ein bisschen rumprobiert und mal nach org $+0xC0000000 nur jmp $ stehen gelassen. Er benötigt sowohl die Mapings für die virtuelle Adresse 0 als auch für die virtuelle Adresse 0xC0000000, oder es gibt einen pagefault.
Warum? :(
-
Sobald du cr0 setzt, benutzt die CPU Paging um auf den Speicher zuzugreifen. Wenn beim cr0-Setzen die Addresse, auf die EIP zeigt, nicht gemappt ist, gibts natürlich eine Fault, sobald die CPU versucht, die nächste Instruction aus dem Speicher zu lesen.
-
#-o
Und ich suche mir nen Wolf...
THX