Page 1 of 1
paging..
Posted: Sun Feb 15, 2004 6:32 pm
by mr. x
I've been trying to fix paging for days now! Can't make it work :/
I have one page directory working, but that lets me only access 4 mb.
When I get a page fault, I get a General Protection Fault right after.
And two other things: When I try to enter 4 GB as the limit for my code segment and data segment, bochs returns this: "jump_protected: IP > limit".
Sometimes I get an error telling me "LDTR.valid = 0", can this be caused by beeing in a bogus segment?
Here's the page fault handler:
Code: Select all
uint32 iVirtualAddress = ReadCR2();
uint32 iOffset = 0, iPageTable = 0, iPageDirectory = 0;
iOffset = iVirtualAddress & 0x3ff;
iPageTable = (iVirtualAddress >> 12) & 0x3FF;
iPageDirectory = (iVirtualAddress >> 22) & 0x3FF;
pPageDirectory[iPageDirectory] = pPageTable[iPageTable + iPageDirectory * 0x400] + 0x1000 | 7;
pPageDirectory[iPageDirectory] |= 3;
pPageTable[iPageTable + iPageDirectory * 0x400] = (iVirtualAddress - iOffset) | 7;
Re:paging..
Posted: Mon Feb 16, 2004 2:04 am
by Pype.Clicker
LDTR.valid=0 usually means that you have filled a segment register with some garbage. This garbage appears to have the TI bit set (stating that your selector is local and not global), but as you have no LDT, the BOCHS complains ...
look out for your stack operation and make sure pushes and pops pairs nicely together ... don't forget to remove the CPU-pushed error code for handlers that have one (like GPF) and not to remove it for handlers that don't (like PF).
Seeing the bochs output (registers, etc) could help us to figure out what's wrong more in details ...
Re:paging..
Posted: Mon Feb 16, 2004 2:54 am
by mr. x
Code: Select all
00002889433i[CPU ] -----------------------------------
00002889433i[CPU ] selector->index*8 + 7 = 24311
00002889433i[CPU ] gdtr.limit = 140
00002889433i[CPU ] fetch_raw_descriptor: GDT: index > limit
00002889433i[CPU ] | EAX=00400000 EBX=00000000 ECX=0009c020 EDX=0009e000
00002889433i[CPU ] | ESP=0000ffc8 EBP=0000ffe8 ESI=00000000 EDI=00000000
00002889433i[CPU ] | IOPL=0 NV UP DI PL NZ NA PE NC
00002889433i[CPU ] | SEG selector base limit G D
00002889433i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00002889433i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00002889433i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00002889433i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00002889433i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00002889433i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00002889433i[CPU ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00002889433i[CPU ] | EIP=ff80024a (ff800249)
00002889433i[CPU ] | CR0=0xe0000011 CR1=0x00000000 CR2=0x00400000
00002889433i[CPU ] | CR3=0x0009e000 CR4=0x00000000
Re:paging..
Posted: Mon Feb 16, 2004 3:39 am
by Pype.Clicker
yup. diagnostic confirmed: you certainly have something wrong in your handler's stub that doesn't handle stack as it should.
btw, is the
pointer 'normal' for your memory layout ? One thing that usually helps is finding what ASM instruction is under that pointer, so that you can figure out why things went wrong.
Re:paging..
Posted: Mon Feb 16, 2004 4:42 am
by mr. x
Code: Select all
[extern _PageFaultHandler]
[global _int14]
_int14:
pusha
push ds
push es
push fs
push gs
mov eax, 0x10
mov ds, eax
mov es, eax
cld
call _PageFaultHandler
pop gs
pop fs
pop es
pop ds
popa
iret
- My PF stub.
How do I get which instruction is located at that position then?
I tried another location of the page dir (somewhere else than the bootloader's page dir), and I got this error:
Code: Select all
exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
Re:paging..
Posted: Mon Feb 16, 2004 5:55 am
by Pype.Clicker
according to my locally-available info, the Page Fault *does* have an error code, but that error code is 0 (should be checked in the Holy Manuals, though -- which i do not have here
)
so
is likely to work better.
How do I get which instruction is located at that position then?
the simplest way is to ask Objdump ... provided that you have line numbers in your kernel.o object, you can invoke
and then look for the appropriate location.
The way i do is that i ask LD to generate a map of my kernel and i use that map to locate the component.o file on which i'll run objdump ... this is a bit longer process but it avoid the generation of a too long disassembly output ...
Re:paging..
Posted: Mon Feb 16, 2004 6:24 am
by mr. x
Okey, I've got an infinitive loop with page faults now... (No General Protection Fault, hurray!)
Re:paging..
Posted: Mon Feb 16, 2004 1:36 pm
by Pype.Clicker
that's natural: as long as you don't fix the *cause* of the page fault (for instance changing the entry to "present"), the handler will return to the faulty instruction, which will fault again ...