I'm currently working on my loader, and I'm having trouble entering long mode. Actually, I can enter long mode, but something weird is happening to the segment registers. I use the following code to enter long mode:
Code: Select all
# JumpToKernel(void*,multiboot_info_t*)
.global JumpToKernel
.type JumpToKernel, @function
JumpToKernel:
pushl %ebp
movl %esp,%ebp
# Disable paging
movl %CR0,%eax
andl $0x7FFFFFFF,%eax
movl %eax,%CR0
# Enable PAE
movl %CR4,%eax
orl $0x20,%eax
movl %eax,%CR4
# Load PML4
movl $IdentityL4,%eax
movl %eax,%CR3
# Enable Long Mode
movl $0xC0000080,%ecx
rdmsr
orl $0x100,%eax
wrmsr
# Load GDT
lgdt (gdtr)
# Move multiboot info pointer to ebx
movl 12(%ebp),%ebx
# Enable paging (and long mode)
movl %CR0,%eax
orl $0x8000000,%eax
movl %eax,%CR0
# Move the kernel's entry point to ecx
movl 8(%ebp),%ecx
# Jump to long mode
pushl $0x8
pushl $code64start
retfl
.code64
.global code64start
.align 8
code64start:
movw $0x10,%ax # Data descriptor
# Update the segment registers
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movw %ax,%ss
# Zero the high 32 bits of the kernel's starting address
xorq %rax,%rax
movl %ecx,%eax
# Jump to kernel
jmpq %rax
Code: Select all
check_exception old: 0xffffffff new 0xd
0: v=0d e=0010 i=0 cpl=0 IP=0008:000000000010007c pc=000000000010007c SP=0018:0000000000102f54 env->regs[R_EAX]=00000000d88e0010
EAX=d88e0010 EBX=00010000 ECX=0020f2bb EDX=00000000
ESI=0000000d EDI=00000000 EBP=00102f54 ESP=00102f54
EIP=0010007c EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 00000000 00009100 DPL=0 DS16 [--A]
CS =0008 00000000 00000000 00209a00 DPL=0 CS64 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 00000000 00009100 DPL=0 DS16 [--A]
GS =0010 00000000 00000000 00009100 DPL=0 DS16 [--A]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 00107000 00000047
IDT= 00000000 00000000
CR0=08000011 CR2=00000000 CR3=00106000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000008 CCD=08000011 CCO=LOGICL
EFER=0000000000000100
Does anyone have an idea what am I doing wrong?
Thanks in advance.