help: I can't enter fully 64bit mode in the bochs.

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: I can't enter fully 64bit mode in the bochs.

Post by rjying »

Hello:
I using the bochs for x86-64 version. I tried to let the code run under the fully 64bit mode, But when the system enter the compatibility mode, code jump to the
.code64 area execute the instruction. But the 64bit opcode can't correct execute.
The system look like not enter 64bit mode, just always in the compatibility mode.
Who can help me to fix this issue?
Thanks.

Code: Select all

.code16
.text
.global _start
_start:
	movw %cs,%ax
	movw %ax,%ds
	movw %ax,%es
#Enable A20
	call empty_8042
	movb $0xd1,%al
	outb %al,$0x64
	call empty_8042
	movb $0xdf,%al
	outb %al,$0x60
	call empty_8042

	cli
	lgdt gdt_48
	movl $0x00000001,%eax
	movl %eax,%cr0
		
	.byte 0x66,0xea
	.long 0x90000+ProtectMode
	.word 0x08
	
.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*/
	xorl %eax,%eax
	btsl $5,%eax
	movl %eax,%cr4

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

	/*Page Enable*/
	xorl %eax,%eax
	btsl $31,%eax
	btsl $0,%eax
	movl %eax,%cr0

	ljmp $0x08,$(0x90000+ProtectMode64)
		
.org 0x200
.code64
.globl ProtectMode64
ProtectMode64:
[color=red]/*the 64bit instruction opcode is detached two opcode to execute, one is "0x48" just "DEC %eax", the other is "xor %eax,%eax"*/[/color]
	/*Enable PAE*/
	xorq %rax,%rax 
	btsq $5,%rax
	btsq $7,%rax
	movq %rax,%cr4

	movq $0x0,%rax
	movq %rax,%cr3


        movl $1|(1<<1)|(1<<4)|(1<<5)|(1<<16)|(1<<18)|(1<<31),%eax
	movq %rax, %cr0

	movq $0x80000,%rsp
	movq $0x80000,%rbp
	
	lgdt gdt_80
	
	movq	c_start(%rip),%rax
	pushq	$0		# fake return address to stop unwinder
	pushq	$0x08	# set correct cs
	pushq	%rax		# target address in negative space
	lretq

idt_48:
	.word 0
	.word 0,0

idt_80:
	.word 0
	.quad 0
	
gdt32:
	.word 0,0,0,0
		 
	.word 0xffff #Segment limit 15:0
	.word 0x0000 #Base address 15:0
	.word 0x9800
	.word 0x00CF

	.word 0xffff
	.word 0x0000
	.word 0x9200
	.word 0x00CF

gdt_48:	
	.word 0x8000
	.long gdt32+0x90000

gdt64:
	.quad 0x0000000000000000 /*NULL descriptor*/
	.quad 0x00af9a000000ffff /*CS*/
	.quad 0x00cf92000000ffff /*DS,SS*/
	
gdt_80:
	.word 0x8000
	.quad gdt64+0x90000

.code16	
empty_8042:
	inb $0x64,%al
	testb $0x1,%al
	jz outbuff_empty
	inb $0x60,%al
	jmp empty_8042

.code64
c_start:
.end
User avatar
rjying
Posts: 22
Joined: Tue Jan 15, 2008 12:52 am

Re: help: I can't enter fully 64bit mode in the bochs.

Post by rjying »

I have fixed this issue.

I read the linux source code, It use a gdt to be shared to the 32bit and 64bit mode, So it can jump from the 32bit to the 64bit without change the gdt.

:)
Post Reply