Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: FalShen am 03. December 2006, 18:51
-
Und wieder ich :3 Da ich ja alleine nix hinkriege...
Ich will jetzt mal paging nutzen. Dazu muss ich ja erstmal initialisieren. Irgendwie geht der code aber nich...
Ich will den kernel, der an der physikalischen Adresse 0x00100000 liegt, nach 0xC0000000 mappen, das übliche also. Gleich nach dem füllen der Tables und des Directories krieg ich einen Page fault mit cr2 = 0x00000040
Hier der code:
start:
xor eax, eax
; or eax, 2
mov ecx, 0x0400
mov edi, [PAGE_DIR]
rep stosd
or eax, 2
mov ecx, 0x0400
mov edi, [PAGE_TAB1]
rep stosd
mov ecx, 0x0400
mov edi, [PAGE_TAB2]
rep stosd
mov dword [PAGE_DIR], PAGE_TAB1 | 3
mov dword [PAGE_DIR+0xC00], PAGE_TAB2 | 3
mov dword [PAGE_TAB1 + 0xB8*4], 0x000B8000 | 3
mov dword [PAGE_TAB2], 0x00100000 | 3
mov dword [PAGE_TAB2+4], 0x00101000 | 3
mov dword [PAGE_TAB2+8], 0x00102000 | 3
mov dword [PAGE_TAB2+12], 0x00103000 | 3
mov dword [PAGE_TAB2+16], 0x00104000 | 3
mov dword [PAGE_TAB2+20], 0x00105000 | 3
mov dword [PAGE_TAB2+24], 0x00106000 | 3
mov eax, PAGE_DIR
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
jmp dword start2
start2:
mov esp, stack
push ebx
call main
stop:
cli
hlt
und die linkfile
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x00100000;
corr = 0xBFF00000;
virt = 0xC0000000;
SECTIONS
{
. = virt;
.text : AT(ADDR(.text) - corr)
{
code = .; _code = .;
*(.text)
. = ALIGN(0x1000);
}
.data : AT(ADDR(.data) - corr)
{
data = .; _data = .;
*(.data)
*(.rodata*)
. = ALIGN(0x4);
}
.bss : AT(ADDR(.bss) - corr)
{
bss = .; _bss = .;
*(.bss)
*(COMMON)
. = ALIGN(0x1000);
}
end = .; _end = .;
}
Danke im vorraus...
-
Ähm, wie ist es möglich, dass ein PageFault ausgelöst wird, noch bevor Paging überhaupt aktiviert ist?? Da blick ich irgendwie nicht ganz durch...
-
beim jump befehl wird diese exception ausgelöst...
(jmp dword start2)
-
Du schreibst hier in die Variable PAGE_DIR und nicht ins page dir:
mov dword [PAGE_DIR], PAGE_TAB1 | 3
-
Nein PAGE_DIR ist eine symbolische Konstante, die die Adresse seines Page Directory ersetzt ;) konntest du aber nicht wissen, hat er ja nicht angegeben...
Er hat mir nur seinen Source geschickt, deswegen wusste ich das...
Nur ich hab den Fehler noch net gefunden...
-
dann ist aber
mov edi, [PAGE_DIR]
falsch, da du für stosd die Adresse brauchst ;)
-
1. ja das war falsch, hab ich nich gesehen, danke...
aber 2. hat das problem nicht gelöst... weil das war ja eh nur löschung des codes...
-
Hmmm könnte natürlich auch sein, dass die PageTable oder das Directory in einem ungültigen Adressbereich sind.
Dann habe ich noch bemerkt, dass ich das CR0 oder eben EAX mit dieser Zeile änder...: or eax,10000000000000000000000000000000b Ich bin jetz aber zu faul um das auf deine Variante umzrechnen...Probiers einfach mal.
Bist du sicher, dass der Fehler genau nach der Anweisung jmp start2 kommt, oder könnte es auch sein das es bei einer anderen Anweisung an der selben Speicherstelle passiert??
Gruss
Nooooooooooooooos
-
@nos: das mit dem or eax, bla stimmt schon ;)
Was mir noch auffällt: Die "identity-mappst" deinen Code garnicht, dass musst du aber, da nachdem du paging eingeschaltet hast, du immernoch am gleichen cs:eip bist.
-
Ich will aber nach 0xC0000000...
heißt ich müsste eine page nur für diesen einen jmp befehl machen?
-
heißt ich müsste eine page nur für diesen einen jmp befehl machen?
Jo, natürlich... Dein Befehlszeiger ist ja noch bei ~0x1xxxxx und das hast du nicht gemappt -> Pagefault
-
Hab jetze mal probiert zu lösen... hat aber irgendwie nich geklappt...
hier der neue starup-code
[EXTERN main]
[GLOBAL start]
start:
xor eax, eax
or eax, 2
mov ecx, 0x0400
mov edi, PAGE_DIR
rep stosd
or eax, 2
mov ecx, 0x0400
mov edi, PAGE_TAB1
rep stosd
mov ecx, 0x0400
mov edi, PAGE_TAB2
rep stosd
mov dword [PAGE_DIR], PAGE_TAB1 | 3
mov dword [PAGE_DIR+0xC00], PAGE_TAB2 | 3
mov dword [PAGE_TAB1 + 0xB8*4], 0x000B8000 | 3
mov dword [PAGE_TAB1 + 0x100*4], 0x00100000 | 3
mov dword [PAGE_TAB2], 0x00100000 | 3
mov dword [PAGE_TAB2+4], 0x00101000 | 3
mov dword [PAGE_TAB2+8], 0x00102000 | 3
mov dword [PAGE_TAB2+12], 0x00103000 | 3
mov dword [PAGE_TAB2+16], 0x00104000 | 3
mov dword [PAGE_TAB2+20], 0x00105000 | 3
mov dword [PAGE_TAB2+24], 0x00106000 | 3
mov eax, PAGE_DIR
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
jmp dword 0x8:0xc00000c2
start2:
mov esp, stack
push ebx
call main
stop:
cli
hlt
-
Problem gelöst... Ich habe einfach das unterste MB im speicher Mirror-Mapped... Ich vermute es war der Zeiger auf die Memory Map von Bochs, in ebx... naja...
Eine Frage hätte ich noch: Nun is die art und weise wie ich jetzt den speicher mappe ziemlich statisch... müsste also korrigiert werden wenn mein kernel weiter wächst... wie kann ich denn dynamischerweise herausfinden wie groß mein kernel im speicher is?
-
Schau dir mal mein Linkerscript (https://opensvn.csie.org/traccgi/lightOS/browser/trunk/kernel/x86/linkerscript) an. Die Variablen __kernel_start__ und __kernel_end__ kann man im C/C++/Assembler code dann verwenden, zB:
extern unsigned int __kernel_start__;
Die Adresse des Kernelanfangs ist dann &__kernel_start__.