Paging - far jump doesn't work

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
N43
Posts: 2
Joined: Sun Apr 30, 2006 11:00 pm

Paging - far jump doesn't work

Post by N43 »

Hi,
I started implementing paging in my os. Everything works fine, except for far jumps. The cpu generates a page fault, when I try to perform a far jump.

The far jump works, when I leave the first entry of the page directory mapped to the first 4MB.

Here's my code:

Code: Select all

		;prepare paging
		mov eax, cr3
		and eax, 0xFFF
		or eax, 0x105000		;addr of page dir
		mov cr3, eax
		
		;map the first 4MB of the 3GB to the 1GB
		mov edi, 0x105C00		;3GB entry in page dir
		mov eax, 0x106000		;addr of page table
		or eax, 0x3				;present & super user
		stosd

		;map the first 4MB of the 1GB to the 1GB
		mov edi, 0x105000
		mov eax, 0x106000
		or eax, 0x3
		stosd

		
		;page table at 0x106000
		mov edi, 0x106000
		mov ecx, 1024
		mov eax, 0x3
		
		fill_page_table:
			stosd
			add eax, 0x1000			;prepare next run (next 4KB)
			loop fill_page_table
		
		;enable paging
		mov eax, cr0
		or eax, 0x80000000
		mov cr0, eax

		jmp 0x8:(next + 0xC0010000)	;jump to 3GB
		
		next:

		;remove first entry from the page directory
		mov edi, 0xC0105000
		mov eax, 0x0
		stosd

		mov esp, 0xC0090000
		
		;;;;;; everything works fine till here
		
		jmp 0x8:(here + 0xC0010000)		;this causes a page fault

		
		here:		
			jmp $
The code also works perfectly, when I replace the far jump with a near jump.

Thanks for your replies in advance.

N43
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: Paging - far jump doesn't work

Post by JAAman »

im not sure why you are performing the second jmp, but i dont see why it should not work, as the jump isnt actually changing anything (even if you were overwriting the wrong page table entry, the old one should still be in the TLB (since your not invalidating)

however

you do need to invalidate your old page -- any time you alter the page tables you must invalidate the appropriate TLBs, (intel CPUs dont store non-present entries, but some other brands do) otherwise, the page will still be mapped -- it isnt actually unmapped until either the CPU removes/implicitly invalidates, or you explicitly invalidate the entry
N43
Posts: 2
Joined: Sun Apr 30, 2006 11:00 pm

Re: Paging - far jump doesn't work

Post by N43 »

I tried out some different code fragments to see what happens and the following code doesn't work, too:

Code: Select all

mov eax, 0x10
mov ds, eax
It seems to be a problem with the gdt. I thaught the gdt base is defined by it's physical address and doesn't has to be changed when activating paging.

edit: I reloaded the gdt with the virtual address and it's working now.

N43
Last edited by N43 on Mon May 01, 2006 11:00 pm, edited 1 time in total.
Debuggers don't remove Bugs, they only show them in Slow-Motion.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: Paging - far jump doesn't work

Post by JAAman »

no, LGDT requires a linear address (that is, it is affected by paging but not segmentation)
Loads the values in the source operand into the global descriptor table register (GDTR) or the interrupt table register (IDTR). The source operand specifies a 6-byte memory location that contains the base address (a linear address)...
The LGDT and LIDT instructions are used only in operating-system software; they are not used in application programs. They are the only instructions that directly load a linear address (that is, not a segment-reletive address) and a limit in protected mode. They are commonly executed in real-address mode to allow processor initialization prior to switching to protected mode.
Intel, Vol2a (rev.16us) page 3-526, section: LGDT/LIDT, emphasis supplied


be careful to note it does not use a virtual address, but a linear address -- this is important, as it is easy to forget because for most people most of the time, they will be the same (when using flat segments) but if you ever use base!=0 segments, this will be different
Last edited by JAAman on Tue May 02, 2006 11:00 pm, edited 1 time in total.
Post Reply