Long mode, far jump to memory location, triple fault

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

Long mode, far jump to memory location, triple fault

Post by sngskunk »

Okay I had this in another forum, but it was about another topic, so I decided to move it to a new topic.

I have got paging enabled, and i am in long mode, and I load GDT for long mode, all works great, I can print a little test string to the screen, everything works fine until, I jump to my kernel which is located at 0x100000. At that point it triple faults, if i put a hlt command in front of that line, everything runs fine, until the halt, so it is far jump.

My code descriptor is second after the null descriptor so it is 0x08.

Code below is in 32 bit, trying to jump to long mode (64-bit):

Code: Select all

; 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 [0x202008], 0x200000 | 010000111b ;2nd PD Entry points to 2-4MB
   	mov     dword [0x202010], 0x400000 | 010000111b ;3rd PD Entry points to 4-6MB
   	mov     dword [0x202018], 0x600000 | 010000111b ;4th PD Entry points to 6-8MB
   	mov     dword [0x202020], 0x800000 | 010000111b ;5th PD Entry points to 8-10MB
   	mov		dword [0x202028], 0xA00000 | 010000111b ;6th PD Entry points to 10-12MB
   	mov     dword [0x202030], 0xC00000 | 010000111b ;7th PD Entry points to 12-14MB
   	mov     dword [0x202038], 0xE00000 | 010000111b ;8th PD Entry points to 14-16MB
   	mov     dword [0x202040], 0x1000000 | 010000111b ;9th PD Entry points to 16-18MB
   	mov     dword [0x202048], 0x1200000 | 010000111b ;10th PD Entry points to 18-20MB
   	mov     dword [0x202050], 0x1400000 | 010000111b ;11th PD Entry points to 20-22MB
   	mov     dword [0x202058], 0x1600000 | 010000111b ;12th PD Entry points to 22-24MB
   	mov     dword [0x202060], 0x1800000 | 010000111b ;13th PD Entry points to 24-26MB
   	mov     dword [0x202068], 0x1A00000 | 010000111b ;14th PD Entry points to 26-28MB
   	mov     dword [0x202070], 0x1C00000 | 010000111b ;15th PD Entry points to 28-30MB
   	mov     dword [0x202078], 0x1E00000 | 010000111b ;16th PD Entry points to 30-32MB
   	mov     dword [0x202080], 0x2000000 | 010000111b ;17th PD Entry points to 32-34MB
   	
	
	; 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:0x100000 ; <-- failure
My GDT looks like this, which is also in 32-bits:

Code: Select all

[BITS 32]
; GDT For Long Mode
startGDT64:
	
	; Null
	dd		0
	dd		0
	
	; 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
	
endGDT64:
rangeGDT64:
	dw		endGDT64 - startGDT64 - 1
	dq 		startGDT64
Bochs returns this error:

Code: Select all

00024216445e[CPU0 ] interrupt(long mode): gate descriptor is not valid sys seg
00024216445e[CPU0 ] interrupt(long mode): gate descriptor is not valid sys seg

What am I missing, any help would be great full, this is driving me crazy. :?
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

What's the initial error that bochs reports? Its normally somewhere before the register dump. Also, is the faulting EIP within your kernel or bootloader? One possibility is that you've jumped to the kernel but are executing bogus code and so getting invalid opcodes, or that the kernel itself tries to access an invalid location. Final question: is your kernel a flat binary? If not, then jumping to the start of the image won't work. If it is, then the entry point needs to be at offset 0.

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

Post by sngskunk »

Okay i found the error, I had the wrong address in the jump, but now I have the right one and if i load my kernel as a flat binary file, it works. But I want it to be an elf64 file so that it can be linked to other objects.

How do I go about processing an elf file, to run the code.
zerosum
Member
Member
Posts: 63
Joined: Wed Apr 09, 2008 6:57 pm

Post by zerosum »

Search google for the specification. It's not hard to do what you're wanting.... even I managed to do it ;-)

Cheers,
Lee
Post Reply