Help: use the bochs to simulate x86_64 mode.

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
rjying
Posts: 22
Joined: Tue Jan 15, 2008 12:52 am

Help: use the bochs to simulate x86_64 mode.

Post by rjying »

I have set the LME flag and the code segment L flag is set
But when I will launch the "movq c_start(%rip),%rax" the prefix "0x48" of the 64bit opertions, But the bochs looks the "0x48" like separate instruction.
:(
How can fix this issue.
Thanks.

Code: Select all

.code32
ProtectMode:
	movw $0x10,%ax
	movw %ax,%ds
	movw %ax,%es
	movw %ax,%ss

	xorl %esi,%esi
	movl $0x00001001,(,%esi,8)
	movl $0x00000000,4(,%esi,8)
	movl $0x100,%esi
	movl $0x00004001,0(,%esi,8)
	movl $0x00000000,4(,%esi,8)

	xorl %esi,%esi
	movl $0x00002001,0x1000(,%esi,8)
	movl $0x00000000,0x1004(,%esi,8)

	movl $0x00003001,0x2000(,%esi,8)
	movl $0x00000000,0x2004(,%esi,8)

	movl $256,%ecx
	movl $0x00000001,%ebx

NextPage_0x0000000000000000:	
	movl %ebx,0x3000(,%esi,8)
	movl $0x00000000,0x3004(,%esi,8)
	
	incl %esi
	addl $0x1000,%ebx
	decl %ecx
	jnz NextPage_0x0000000000000000

	xorl %esi,%esi
	movl $0x00005001,0x4000(,%esi,8)
	movl $0x00000000,0x4004(,%esi,8)

	movl $0x00006001,0x5000(,%esi,8)
	movl $0x00000000,0x5004(,%esi,8)

	movl $256,%ecx
	movl $0x00000001,%ebx

NextPage_0x0000800000000000:	
	movl %ebx,0x6000(,%esi,8)
	movl $0x00000000,0x6004(,%esi,8)
	
	incl %esi
	addl $4096,%ebx
	decl %ecx
	jnz NextPage_0x0000800000000000

	/*Enable PAE*/
	movl %cr4,%eax
	orl $0x20,%eax
	movl %eax,%cr4

	movl $0x0,%eax
	movl %eax,%cr3
	
	movl $0xc0000080,%ecx  /*EFER MSR number*/
	rdmsr                  /*Read EFER*/
	orl $0x100,%eax         /*Set LME=1*/
	wrmsr                  /*Write EFER*/

	/*Page Enable*/
	movl %cr0,%eax
	orl $0x80000001,%eax
	movl %eax, %cr0

	ljmp $0x08,$(0x90000+ProtectMode64)

.code64
ProtectMode64:
	movq $0x80000,%rsp
	movq $0x80000,%rbp

	pushq $0
	popfq

	lgdt gdt_80
	/*lidt idt_80*/
	
	movq	c_start(%rip),%rax
	pushq	$0		# fake return address to stop unwinder
	pushq	$0x10	# set correct cs
	pushq	%rax		# target address in negative space
	lret
       .....
      gdt64:
	.word 0,0,0,0

	.word 0xffff
	.word 0x0000
	.word 0xb000
	.word 0x0020

	.word 0x0000
	.word 0x0000
	.word 0xa000
	.word 0x0000

gdt_80:
	.word 0x8000
	.quad gdt64
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

When you do the jump to ProtectMode64, you are in Compatibility mode, not Long mode. This means, you are still in a 32 bit mode, but I think because of your .code64, you are trying to emit 64 bit instructions (I'm not familiar with the syntax, so I could be wrong!).

Until you actually jump to your 64 bit GDT segment after entering compatibility mode, you should continue to emit 32 bit instructions.

In your final register dump, does Bochs report Long Mode or Compatibility Mode (this can be found just before the register dump starts)?

Cheers,
Adam
User avatar
rjying
Posts: 22
Joined: Tue Jan 15, 2008 12:52 am

Post by rjying »

Thanks
I see.
Perhaps, when in the Compatibility mode, I will reload the segment register.
I have make sure, when crash, the system in the Compatibility mode.

Thank you very much.
Post Reply