mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 13:34:53 +00:00
[FREELDR] Fix an inconsistency bug when switching the CPU state back to 16-bit real mode.
Basically it appeared that without this fix, the CPU was somehow residing in an inconsistent state, that made it crash when a full 16-bit real-mode to 32-bit protected mode transition occurred. (Encountered when trying to load Linux, see problem description below.) In that situation, Bochs reports that the CPU is in "compatibility mode". The fix is based from information from Fig.1-6 "Operating Modes of the AMD64 Architecture" (page 12) and Chapter 14 (pages 429-446) of the "AMD64 Architecture Programmer’s Manual Volume 2: System Programming" https://www.amd.com/system/files/TechDocs/24593.pdf *** THE PROBLEM *** When booting Linux using x86 FreeLdr everything goes well. When trying to do the same using x64 FreeLdr, the Linux code (both the boot sector, the setup sector and the main kernel contents) is all correctly loaded and relocated in memory as in the x86 case. We then pass control to the decompressing code that appears to succeed. However, once it has finished and "Parsing ELF file..." step has been run, the next step "Booting the kernel..." crashes with a CPU Triple-Fault. This problem **DOES NOT HAPPEN** when booting from GRUB. Log excerpt from Bochs: <snip> 00089459736i[BIOS ] Booting from 07c0:0000 00089782775i[SER ] com1: FIFO enabled 00095994535i[BIOS ] int13_harddisk: function 41, unmapped device for ELDL=81 00095998517i[BIOS ] int13_harddisk: function 08, unmapped device for ELDL=81 00397139785i[BIOS ] KBD: unsupported int 16h function 03 00397143625i[BIOS ] *** int 15h function AX=e980, BX=0000 not yet supported! 00523008104e[CPU0 ] interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x0 00523008104e[CPU0 ] interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x0 00523008104i[CPU0 ] CPU is in compatibility mode (active) 00523008104i[CPU0 ] CS.mode = 32 bit 00523008104i[CPU0 ] SS.mode = 32 bit 00523008104i[CPU0 ] EFER = 0x00000500 00523008104i[CPU0 ] | RAX=00000000e0000011 RBX=0000000000000000 00523008104i[CPU0 ] | RCX=0000000000000000 RDX=0000000000000000 00523008104i[CPU0 ] | RSP=00000000004f8000 RBP=000000000082e003 00523008104i[CPU0 ] | RSI=0000000000099800 RDI=00000000c0611000 00523008104i[CPU0 ] | R8=0000000000109000 R9=0000000000009020 00523008104i[CPU0 ] | R10=00000000000007e3 R11=000000000000e958 00523008104i[CPU0 ] | R12=0000000000000000 R13=0000000000000000 00523008104i[CPU0 ] | R14=0000000000000000 R15=0000000000000000 00523008104i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf 00523008104i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D 00523008104i[CPU0 ] | CS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 00523008104i[CPU0 ] | DS:0018( 0003| 0| 0) 00000000 ffffffff 1 1 00523008104i[CPU0 ] | SS:0018( 0003| 0| 0) 00000000 ffffffff 1 1 00523008104i[CPU0 ] | ES:0018( 0003| 0| 0) 00000000 ffffffff 1 1 00523008104i[CPU0 ] | FS:0018( 0003| 0| 0) 00000000 ffffffff 1 1 00523008104i[CPU0 ] | GS:0018( 0003| 0| 0) 00000000 ffffffff 1 1 00523008104i[CPU0 ] | MSR_FS_BASE:0000000000000000 00523008104i[CPU0 ] | MSR_GS_BASE:0000000000000000 00523008104i[CPU0 ] | RIP=0000000000409327 (0000000000409327) 00523008104i[CPU0 ] | CR0=0xe0000011 CR2=0x0000000000409327 00523008104i[CPU0 ] | CR3=0x005b5000 CR4=0x000000a0 00523008104i[CPU0 ] 0x0000000000409327: (instruction unavailable) page not present 00523008104p[CPU0 ] >>PANIC<< exception(): 3rd (13) exception with no resolution <snip>
This commit is contained in:
parent
25badcfbbd
commit
0d6631c2da
|
@ -160,6 +160,12 @@ CheckFor64BitSupport:
|
|||
.ascii "PAE or PGE not set.", CR, LF, NUL
|
||||
|
||||
.CheckForLongMode:
|
||||
/* Check whether extended functions are supported */
|
||||
mov eax, HEX(80000000)
|
||||
cpuid
|
||||
cmp eax, HEX(80000000) // Any function > 0x80000000 ?
|
||||
jbe .NoLongMode // If not, no long mode.
|
||||
/* Check whether the CPU supports Long Mode */
|
||||
xor edx, edx
|
||||
mov eax, HEX(80000001)
|
||||
cpuid
|
||||
|
@ -167,6 +173,7 @@ CheckFor64BitSupport:
|
|||
test edx, edx
|
||||
jnz .Success
|
||||
|
||||
.NoLongMode:
|
||||
mov si, offset .Msg_NoLongMode
|
||||
call writestr
|
||||
popad
|
||||
|
@ -240,6 +247,18 @@ BuildPageTables:
|
|||
|
||||
/* This is the entry point from long mode */
|
||||
RealModeEntryPoint:
|
||||
|
||||
/* Disable long mode */
|
||||
mov ecx, MSR_EFER
|
||||
rdmsr
|
||||
and eax, HEX(0FFFFFEFF) // ~0100
|
||||
wrmsr
|
||||
|
||||
/* Mask PAE and PGE out */
|
||||
mov eax, cr4
|
||||
and eax, HEX(0FFFFFF5F) // ~00A0
|
||||
mov cr4, eax
|
||||
|
||||
/* Disable Protected Mode */
|
||||
mov eax, cr0
|
||||
and eax, HEX(0FFFFFFFE) // ~0x00000001
|
||||
|
@ -295,6 +314,8 @@ ExitToLongMode:
|
|||
mov word ptr ds:[stack16], sp
|
||||
|
||||
/* Set PAE and PGE: 10100000b */
|
||||
// mov eax, cr4
|
||||
// or eax, HEX(00A0)
|
||||
mov eax, HEX(00A0)
|
||||
mov cr4, eax
|
||||
|
||||
|
|
Loading…
Reference in a new issue