Page 1 of 1

Leaving Compatability, Entering Long Mode

Posted: Mon Nov 20, 2006 6:53 am
by Fear
I can't even say how many bugs I found trying just to enter compatability mode. Now I realized I can't even get into true long mode. The faq says to alter some of the stuff in the GDT. Does this mean I should load a new GDT (which I tried, didn't work) or should I just change stuff in the current GDT (which I don't think is possible)? All Bochs ever says is "(instruction unavailable) page not present". Heres my code (everything to enable long mode):

Code: Select all

	MOV			EAX,			CR4				; Switch CR4 to EAX
	BTS			EAX,			5				; Enable CR4.PAE
	MOV			CR4,			EAX				; Switch Back
	
	MOV			EAX,			100000h			; Set CR3 to 100000h
	MOV			CR3,			EAX				; Switch EAX back to CR3
	
	XOR			EAX,			EAX				; EAX = Addr
	XOR			EBX,			EBX				; EBX = Storage
	XOR			ECX,			ECX				; ECX = Counter
	
	.LoopPD:
		MOV		EBX,			EAX				; Store EAX in EBX
		OR		EBX,			3				; Or it by 3 (Kernel Mode)
		MOV		[101000h+ECX],	EBX				; Assignment
		
		ADD		ECX,			4				; Increase the counter by a DD
		ADD		EAX,			4096			; Increase Address by 4KB
		CMP		ECX,			4096			; Compare to 4KB
		JL		.LoopPD							; Jump back if less
	
	XOR			EAX,			[101000h]		; EAX = Addr = [101000h]
	XOR			EBX,			EBX				; EBX = Storage
	XOR			ECX,			ECX				; ECX = Counter
	
	.LoopPT:
		MOV		EBX,			EAX				; Store EAX in EBX
		OR		EBX,			3				; Or it by 3
		MOV		[100000h+ECX],	EBX				; Assignment
		
		ADD		ECX,			4				; Increase the counter by a DD
		CMP		ECX,			4096			; Compare to 4KB
		JL		.LoopPT							; Jump back if less
	
	MOV			ECX,			0C0000080h		; Load ECX with the MSR
	RDMSR										; Must be used with ECX
	BTS			EAX,			8				; Set Bit 8 of ECX
	WRMSR										; Must be used with ECX		
	
	MOV			EAX,			CR0				; Switch CR0 to EAX
	BTS			EAX,			31				; Set Bit 31 of CR0
	MOV			CR0,			EAX				; Switch CR0 to EAX
I know my paging code is terrible, I just did that so I could actually see Bochs say that I enabled compatability mode without getting errors.

Posted: Mon Nov 20, 2006 9:36 am
by Dex

Posted: Mon Nov 20, 2006 2:07 pm
by Fear
Wow, thanks a ton. That really sums it all up. I wish I had known about that a week ago....

Posted: Mon Nov 20, 2006 2:23 pm
by Dex
Fear wrote:Wow, thanks a ton. That really sums it all up. I wish I had known about that a week ago....
Its only just been posted :wink:

Posted: Wed Nov 22, 2006 9:27 am
by Fear
Well, now I was coding a function to clear the screen, when I hit another roadblock. See, if I do the code the way I normally would:

Code: Select all

PUSH     RBP
MOV      RBP,     RSP
.
.
.
POP      RBP
RET
I get an error from Bochs, saying 'RETnear64: Canonical RIP violation'. Now, I don't even know what that means, let alone what causing it...

Heres the code for the function I think is causing it:

Code: Select all

CLS:
	PUSH		RBP
	MOV			RBP,			RSP

	XOR			RAX,			RAX
	MOV			AH,				[Attr]
	MOV			AL,				32
	MOV			EBX,			EAX
	SHL			EBX,			16
	OR			EAX,			EBX
	MOV			RBX,			RAX
	SHL			RBX,			32
	OR			RAX,			RBX
	XOR			RCX,			RCX

	.Clear:
		MOV		[TMem + RCX],	RAX
		ADD		RCX,			8
		CMP		RCX,			4000
		JL		.Clear
	
	POP			RBP
	RET 
So my question is, what is different about setting up a sub-procedure in long mode versus setting up a sub-procedure in protected mode.

Posted: Wed Nov 22, 2006 11:34 am
by Dex
Just a gess, but have you tryed "retq", as they seem to use "iretq" in the demo code.

Posted: Wed Nov 22, 2006 7:10 pm
by Brendan
Hi,
Fear wrote:I get an error from Bochs, saying 'RETnear64: Canonical RIP violation'. Now, I don't even know what that means, let alone what causing it...
Have a look at this paragraph describing canonical addresses.

Basically, the RIP taken from your stack isn't supported by the CPUs MMU (i.e. isn't canonical). I'd guess something trashed your stack....


Cheers,

Brendan

Posted: Fri Nov 24, 2006 1:39 pm
by Fear
Well, this is bizarre. I tried every solution I could possibly think of (close to 100), and none of them worked. I come back today, tried the most obvious one again and it worked. Wierd, right? So yea, my stack was corrupt because it somehow didn't exist....

Edit: I just realized it only works with internal functions currently, no externals... but I'm getting closer...