paging..

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
mr. x

paging..

Post 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;
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:paging..

Post 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 ...
mr. x

Re:paging..

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:paging..

Post 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

Code: Select all

EIP=ff80024a
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.
mr. x

Re:paging..

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:paging..

Post 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

Code: Select all

   popa
   add esp,4
   iret
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

Code: Select all

   objdump -drSl kernel.o | less
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 ...
mr. x

Re:paging..

Post by mr. x »

Okey, I've got an infinitive loop with page faults now... (No General Protection Fault, hurray!)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:paging..

Post 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 ...
Post Reply