Page fault, anything above 2mb [Another Problem]

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
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Page fault, anything above 2mb [Another Problem]

Post by sngskunk »

I am currently working on setting up a temporary page table so I can jump to long mode then start executing my 64-bit code. The problem is, anything above 2mb causes a page fault, which make a triple fault, restarting bochs.

The code is below:

Code: Select all

[BITS 32]
pMode:
	; Setup Stack Pointer
	mov 	ax, 0x10
	mov		ds, ax
	mov		ss, ax
	mov		esp, 0x090000
	
	; Setup Registers
	mov		eax, 0x10
	xor		ecx, ecx
	mov 	ds, ax
	mov		es, ax
	mov		ss, ax
	mov		fs, cx
	mov		gs, cx
	
	; Clear Page Tables
	xor		eax, eax
	mov		edi, 0x200000
	mov		ecx, 512*8
	rep		stosd
	
	; Setup Temp Page Tables
	mov		dword [0x200000], 0x201000 | 111b ; PML4
	mov		dword [0x201000], 0x202000 | 111b ; PDP (Entry 1)
	mov		dword [0x202000], 0x0 | 010000111b ;1st PD Entry points to 0-2MB
	mov		dword [0x203000], 0x200000 | 010000111b ;2st PD Entry points to 2-4MB
	mov		dword [0x204000], 0x400000 | 010000111b ;3st PD Entry points to 4-6MB
	mov		dword [0x205000], 0x600000 | 010000111b ;4st PD Entry points to 6-8MB
	mov		dword [0x206000], 0x800000 | 010000111b ;5st PD Entry points to 8-10MB
	
	; Setup CR3
	mov		eax, 0x200000
	mov		cr3, eax
		
	; Enable CR4.PAE=1
	mov		eax, cr4
	bts		eax, 5
	mov		cr4, eax
	
	; Enable EFER.LME=1
	mov		ecx, 0C0000080h
	rdmsr
	bts		eax, 8
	wrmsr
	
	; Enable Paging
	mov		eax, cr0
	bts		eax, 31
	mov		cr0, eax
		
	mov		dword [0x1000], 0x4 ; This doesn't triple fault
	mov		dword [0x10000], 0x3 ; This doesn't triple fault
	mov		dword [0x100000], 0x6 ; This doesn't triple fault
	mov		dword [0x20C000], 0x6 ; This does triple fault
It is like anything above 0x200000 causes fault, and i am just trying to setup 1:1 paging, till i jump to 64-bit mode.

Bochs gets this error and restarts:

interrupt(long mode): gate descriptor is not valid sys seg

How can I fix this?

Thanks in advance.
Last edited by sngskunk on Tue Jun 03, 2008 9:44 pm, edited 1 time in total.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

You're setting up your PD wrong. Its base address is 0x202000, such that:

entry 0 is at 0x202000
entry 1 is at 0x202008 (64-bit PD entries)
entry 2 is at 0x202010
entry 3 is at 0x202018
...

rather that at every 4kiB boundary like you're doing (0x202000, 0x203000, 0x204000 etc). I'm presuming you're trying to use large pages (I haven't checked the actual flags you're OR'ing with against the Intel manuals but given the context that looks like what you're trying to do).

Regards,
John.
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

Thank you very much, that worked. I feel stupid for try to make them in 4kb pages.
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

Okay now, i have another problem, the pages work, i think.

Then I load the 64bit gdt, which i located at the beginning of the file, which looks like this:

Code: Select all

[BITS 16]

startGDT64:
	
	; Null
	dd		0
	dd		0
	
	; Ring 0 Code
	dw		0FFFFh
	dw		0
	db		0
	db		10011010b
	db		10101111b
	db		0
	
	; Data
	dw		0FFFFh
	dw		0
	db		0
	db		10010010b
	db		11001111b
	db		0
	
endGDT64:
rangeGDT64:
	dw		endGDT64 - startGDT64 - 1
	dq		startGDT64
	
%endif
Then i load the gdt:

Code: Select all

; Setup Temp Page Tables
	mov      dword [0x200000], 0x201000 | 111b ; PML4
	mov      dword [0x201000], 0x202000 | 111b ; PDP (Entry 1)
	mov      dword [0x202000], 0x0 | 010000111b ;1st PD Entry points to 0-2MB
	mov      dword [0x202008], 0x200000 | 010000111b ;2st PD Entry points to 2-4MB
	mov      dword [0x202010], 0x400000 | 010000111b ;3st PD Entry points to 4-6MB
	mov      dword [0x202018], 0x600000 | 010000111b ;4st PD Entry points to 6-8MB
	mov      dword [0x202020], 0x800000 | 010000111b ;5st PD Entry points to 8-10MB
	
	; Setup CR3
	mov		eax, 0x200000
	mov		cr3, eax
		
	; Enable CR4.PAE=1
	mov		eax, cr4
	bts		eax, 5
	mov		cr4, eax
	
	; Enable EFER.LME=1
	mov		ecx, 0C0000080h
	rdmsr
	bts		eax, 8
	wrmsr
	
	; Enable Paging
	mov		eax, cr0
	bts		eax, 31
	mov		cr0, eax
	
	; Load GDT
	lgdt	[rangeGDT64]
	
	; Jump to Long Mode
	jmp		0x08:0x10000 ; fails to jump to where kernel is loaded
At the far jmp is fails to jmp to the kernel which is loaded at that address, it just triple faults.

The kernel is an elf file, which i just load don't parse anything, is that why, or is it something else that I am doing.
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

I made my kernel which is load at 0x10000, into a binary file, and I get the same error, so I don't think it is the file type, being the problem.

I think that it have to do with the 64-bit code selector, either I am calling the selector wrong or I initialized it the wrong way.
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

bochs error - interrupt(long mode): gate descriptor is not valid sys seg
blound
Member
Member
Posts: 70
Joined: Sat Dec 01, 2007 1:36 pm

Post by blound »

in the latest volume 3a of the intel manuals, look at Figure 4-1 and the following text.

from your gdt setup, the second db of your 'ring 0 code'

Code: Select all

db      10101111b 
the 1010 is setting the G bit of the code descriptor, which you do not want. change this to 00101111b. Also the limits do not matter so you can make them zero and have it easier on yourself.

similary the 'db in your data gdt thats 11001111 is setting the G and D bit of the data descriptor which you do not want for 64 bit code. I did not look at the rest of your stuff but you need to fix the gdt descriptors first
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

Okay i fixed that part, but I am still getting the same error:

Here is what my GDT looks like now:

Code: Select all

	; Ring 0 Code
	dw		0
	dw		0
	db		0
	db		10011010b
	db		00101111b
	db		0
	
	; Data
	dw		0
	dw		0
	db		0
	db		10010010b
	db		00001111b
	db		0
blound
Member
Member
Posts: 70
Joined: Sat Dec 01, 2007 1:36 pm

Post by blound »

sngskunk wrote:

Code: Select all

	; Ring 0 Code
	db		10011010b
you are setting the second bit which should not be set. Are you still getting the same error when you lgdt or is it different now?
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

I dont understand, what you mean, I am looking at the code discriptor for longmode in the amd manual and i think it is correct, becuase most of the bits are ignored anyway.

But i am getting the same error. It only does it at the jmp statement:

Code: Select all

jmp     0x08:0x10000
User avatar
sngskunk
Member
Member
Posts: 47
Joined: Mon Mar 31, 2008 1:00 pm
Location: Louisville, KY, USA

Post by sngskunk »

Created a new topic, for problem:

http://www.osdev.org/phpBB2/viewtopic.php?p=128714
Post Reply