Author: tkreuzer
Date: Thu Apr 2 09:11:02 2009
New Revision: 40324
URL:
http://svn.reactos.org/svn/reactos?rev=40324&view=rev
Log:
Fix switching from long mode to real mode, by jumping into a compatibility segment first.
This wasn't needed by qemu, but other emulators didn't like it. Now it boots on
Virtualbox, too and VMWare shows at least the blue loading screen before crashing.
Modified:
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S [iso-8859-1]
(original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S [iso-8859-1]
Thu Apr 2 09:11:02 2009
@@ -48,13 +48,28 @@
.code64
+ /* Checkpoint */
+// mov ax, LMODE_DS
+// mov ds, ax
+// mov word ptr ds:[0xb8000], 0x0e00 + '1'
+
/* GO! */
xor rcx, rcx
call _BootMain
+ /* Checkpoint */
+// mov ax, LMODE_DS
+// mov ds, ax
+// mov word ptr ds:[0xb8002], 0x0e00 + '2'
+
/* Return into real mode */
call x86_64_SwitchToReal
.code16
+
+ /* Checkpoint */
+// mov ax, 0xb800
+// mov fs, ax
+// mov word ptr fs:[0xA0], 0x0e00 + '0'
// int 0x19
@@ -203,25 +218,40 @@
/* Save 64-bit stack pointer */
mov stack64, rsp
- /* Step 1 - deactivate long mode, by disabling paging */
- mov rax, cr0
- and rax, 0x000000007fffffff //~0x80000000
- mov cr0, rax
+// mov ax, LMODE_DS
+// mov ds, ax
+// mov word ptr ds:[0xb8004], 0x0e00 + '3'
+
+ /* Step 1 - jump to compatibility segment */
+ ljmp jumpvector
+
+jumpvector:
+ .long SwitchToReal1
+ .word CMODE_CS
+
+SwitchToReal1:
+.code32
+
+// mov word ptr ds:[0xb8006], 0x0e00 + '4'
+
+ /* Step 2 - deactivate long mode, by disabling paging */
+ mov eax, cr0
+ and eax, 0x000000007fffffff //~0x80000000
+ mov cr0, eax
/* Step 2 - disable long mode in EFER MSR */
- mov rcx, 0xC0000080 // Specify EFER MSR
- rdmsr
- and eax, ~0x00000100 // Disable EFER.LME
- wrmsr
-
- .code32
- /* jmp to 16-bit segment to set the limit correctly */
+// mov ecx, 0xC0000080 // Specify EFER MSR
+// rdmsr
+// and eax, ~0x00000100 // Disable EFER.LME
+// wrmsr
+
+ /* Step 3 - jump to 16-bit segment to set the limit correctly */
jmp RMODE_CS: offset SwitchToReal2
SwitchToReal2:
.code16
- /* Step 3 - Disable Protected Mode */
+ /* Step 4 - Disable Protected Mode */
mov eax, cr0
and eax, ~0x00000001
mov cr0, eax
@@ -230,6 +260,11 @@
jmp 0:offset BeReal
BeReal:
+ /* Checkpoint */
+// mov ax, 0xb800
+// mov fs, ax
+// mov word ptr fs:[0x0C], 0x0e00 + '7'
+
/* Restore segment registers */
mov ax, 0
mov ds, ax
@@ -238,7 +273,7 @@
mov gs, ax
mov ss, ax
- /* Rstore 16 bit stack */
+ /* Restore 16 bit stack */
mov sp, stack16
// lidt rmode_idtptr /* Load IDTR with real mode value */
@@ -266,17 +301,19 @@
code64ret:
.quad 0
+.p2align 2
gdt:
.quad 0x0000000000000000 /* 00: NULL descriptor */
.quad 0x0000000000000000 /* 08: */
.quad 0x0020980000000000 /* 10: long mode cs */
- .quad 0x0000900000000000 /* 18: long mode ds */
+ .quad 0x00cff3000000ffff /* 18: long mode ds */
.word 0xFFFF, 0x0000, 0x9E00, 0x0000 /* 16-bit real mode CS */
.word 0xFFFF, 0x0000, 0x9200, 0x0000 /* 16-bit real mode DS */
+ .quad 0x00CF9B000000FFFF /* 30: compat mode cs */
/* GDT table pointer */
gdtptr:
- .word 0x2f /* Limit */
+ .word 0x37 /* Limit */
.long gdt /* Base Address */
Modified:
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
[iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
[iso-8859-1] Thu Apr 2 09:11:02 2009
@@ -28,6 +28,7 @@
#define LMODE_DS 0x18
#define RMODE_CS 0x20 /* RMode code selector, base 0 limit 64k */
#define RMODE_DS 0x28 /* RMode data selector, base 0 limit 64k */
+#define CMODE_CS 0x30
#define VA_MASK 0x0000FFFFFFFFFFFFUL