long mode activation and VMware Fusion vs VirtualBox
Posted: Sun May 01, 2011 12:39 am
I am in the 32 bit protected mode with paging enabled and have the following problem.
I set up long mode as follows:
1. disable paging in CR0
2. enable PAE in CR4
3. load CR3 with PML4 root
4. enable long mode in Extended Feature MSR
5. enable paging
This should leave me in compatibility mode. It works in VMware Fusion but it does not in Virtual Box.
I identity map only the first 1GB. The PD with 2MB pages is located at 0x100000.
The PDPT is located at 0x101000, and the PML4 is located at 0x102000.
I set CR3 to 0x102000, here's memory dump for PML4
VBoxDbg> dq 0x102000
%0000000000102000: 0000000000101001 0000000000000000
VBoxDbg> dq 0x101000
%0000000000101000: 0000000000100001 0000000000000000
VBoxDbg> dq 0x100000
%0000000000100000: 0000000000000081 0000000000200081
%0000000000100010: 0000000000400081 0000000000600081
...
After enabling a paging bit in CR0 in Virtualbox the code stops to run.
I can only access memory up to 0x1FFFFF but it appears as everything is zeroed out.
EIP has value of 0x82cc which in my case is the address where a dummy interrupt handler is located.
In addition, ESP is set to 0 after the problem occurs.
I've done this in the past but I'm doing something wrong now and I can't figure out what.
Suggestions are welcome. I'm really stuck on this one now.
Here is a register dump right before enabling paging:
eax=00000000 ebx=00000048 ecx=c0000080 edx=00000000 esi=00000a48 edi=9e1c0000
eip=0000837c esp=00000900 ebp=00000900 iopl=0 nv up di pl zr na po nc
cs={0008 base=00000000 limit=ffffffff flags=c09a} dr0=00000000 dr1=00000000
ds={0010 base=00000000 limit=ffffffff flags=c093} dr2=00000000 dr3=00000000
es={0010 base=00000000 limit=ffffffff flags=c093} dr6=ffff0ff0 dr7=00000400
fs={0010 base=00000000 limit=ffffffff flags=c093} cr0=00000011 cr2=00000000
gs={0010 base=00000000 limit=ffffffff flags=c093} cr3=00102000 cr4=00000020
ss={0018 base=00000000 limit=ffffffff flags=c093} cr8=00000000
gdtr=00000a90:001f idtr=00000ab0:00ff eflags=00000046
ldtr={0000 base=00000000 limit=0000ffff flags=0082}
tr ={0000 base=00000000 limit=0000ffff flags=008b}
sysenter={cs=0000 eip=00000000 esp=00000000}
fcw=037f fsw=0000 ftw=ffff mxcsr=1f80 mxcsr_mask=0000
0008:0000837c 0f 20 c0 mov eax, cr0
Here is register dump after the problem occurs:
eax=80000011 ebx=00000048 ecx=c0000080 edx=00000000 esi=00000a48 edi=9e1c0000
eip=000082cc esp=00000000 ebp=00000900 iopl=0 nv up di ng nz na po nc
cs={0008 base=00000000 limit=ffffffff flags=c09a} dr0=00000000 dr1=00000000
ds={0010 base=00000000 limit=ffffffff flags=c093} dr2=00000000 dr3=00000000
es={0010 base=00000000 limit=ffffffff flags=c093} dr6=ffff0ff0 dr7=00000400
fs={0010 base=00000000 limit=ffffffff flags=c093} cr0=80000011 cr2=80000011
gs={0010 base=00000000 limit=ffffffff flags=c093} cr3=00102000 cr4=00000020
ss={0018 base=00000000 limit=ffffffff flags=c093} cr8=00000000
gdtr=00000a90:001f idtr=00000ab0:00ff eflags=00000086
ldtr={0000 base=00000000 limit=0000ffff flags=0082}
tr ={0000 base=00000000 limit=0000ffff flags=008b}
sysenter={cs=0000 eip=00000000 esp=00000000}
fcw=037f fsw=0000 ftw=ffff mxcsr=1f80 mxcsr_mask=0000
Here is GDT dump
VBoxDbg> Guest GDT (GCAddr=0000000000000a90 limit=1f):
0008 - 0000ffff 00cf9a00 - base=00000000 limit=ffffffff dpl=0 CodeER Present Page 32-bit
0010 - 0000ffff 00cf9300 - base=00000000 limit=ffffffff dpl=0 DataRW Accessed Present Page 32-bit
0018 - 0000ffff 00cf9300 - base=00000000 limit=ffffffff dpl=0 DataRW Accessed Present Page 32-bit
I set up long mode as follows:
1. disable paging in CR0
2. enable PAE in CR4
3. load CR3 with PML4 root
4. enable long mode in Extended Feature MSR
5. enable paging
This should leave me in compatibility mode. It works in VMware Fusion but it does not in Virtual Box.
I identity map only the first 1GB. The PD with 2MB pages is located at 0x100000.
The PDPT is located at 0x101000, and the PML4 is located at 0x102000.
I set CR3 to 0x102000, here's memory dump for PML4
VBoxDbg> dq 0x102000
%0000000000102000: 0000000000101001 0000000000000000
VBoxDbg> dq 0x101000
%0000000000101000: 0000000000100001 0000000000000000
VBoxDbg> dq 0x100000
%0000000000100000: 0000000000000081 0000000000200081
%0000000000100010: 0000000000400081 0000000000600081
...
After enabling a paging bit in CR0 in Virtualbox the code stops to run.
I can only access memory up to 0x1FFFFF but it appears as everything is zeroed out.
EIP has value of 0x82cc which in my case is the address where a dummy interrupt handler is located.
In addition, ESP is set to 0 after the problem occurs.
I've done this in the past but I'm doing something wrong now and I can't figure out what.
Suggestions are welcome. I'm really stuck on this one now.
Here is a register dump right before enabling paging:
eax=00000000 ebx=00000048 ecx=c0000080 edx=00000000 esi=00000a48 edi=9e1c0000
eip=0000837c esp=00000900 ebp=00000900 iopl=0 nv up di pl zr na po nc
cs={0008 base=00000000 limit=ffffffff flags=c09a} dr0=00000000 dr1=00000000
ds={0010 base=00000000 limit=ffffffff flags=c093} dr2=00000000 dr3=00000000
es={0010 base=00000000 limit=ffffffff flags=c093} dr6=ffff0ff0 dr7=00000400
fs={0010 base=00000000 limit=ffffffff flags=c093} cr0=00000011 cr2=00000000
gs={0010 base=00000000 limit=ffffffff flags=c093} cr3=00102000 cr4=00000020
ss={0018 base=00000000 limit=ffffffff flags=c093} cr8=00000000
gdtr=00000a90:001f idtr=00000ab0:00ff eflags=00000046
ldtr={0000 base=00000000 limit=0000ffff flags=0082}
tr ={0000 base=00000000 limit=0000ffff flags=008b}
sysenter={cs=0000 eip=00000000 esp=00000000}
fcw=037f fsw=0000 ftw=ffff mxcsr=1f80 mxcsr_mask=0000
0008:0000837c 0f 20 c0 mov eax, cr0
Here is register dump after the problem occurs:
eax=80000011 ebx=00000048 ecx=c0000080 edx=00000000 esi=00000a48 edi=9e1c0000
eip=000082cc esp=00000000 ebp=00000900 iopl=0 nv up di ng nz na po nc
cs={0008 base=00000000 limit=ffffffff flags=c09a} dr0=00000000 dr1=00000000
ds={0010 base=00000000 limit=ffffffff flags=c093} dr2=00000000 dr3=00000000
es={0010 base=00000000 limit=ffffffff flags=c093} dr6=ffff0ff0 dr7=00000400
fs={0010 base=00000000 limit=ffffffff flags=c093} cr0=80000011 cr2=80000011
gs={0010 base=00000000 limit=ffffffff flags=c093} cr3=00102000 cr4=00000020
ss={0018 base=00000000 limit=ffffffff flags=c093} cr8=00000000
gdtr=00000a90:001f idtr=00000ab0:00ff eflags=00000086
ldtr={0000 base=00000000 limit=0000ffff flags=0082}
tr ={0000 base=00000000 limit=0000ffff flags=008b}
sysenter={cs=0000 eip=00000000 esp=00000000}
fcw=037f fsw=0000 ftw=ffff mxcsr=1f80 mxcsr_mask=0000
Here is GDT dump
VBoxDbg> Guest GDT (GCAddr=0000000000000a90 limit=1f):
0008 - 0000ffff 00cf9a00 - base=00000000 limit=ffffffff dpl=0 CodeER Present Page 32-bit
0010 - 0000ffff 00cf9300 - base=00000000 limit=ffffffff dpl=0 DataRW Accessed Present Page 32-bit
0018 - 0000ffff 00cf9300 - base=00000000 limit=ffffffff dpl=0 DataRW Accessed Present Page 32-bit