mirror of
https://github.com/reactos/reactos.git
synced 2025-07-08 17:47:52 +00:00
[FREELDR]
- Implement switching back to real mode - use a symbolic name for the size of the REGGS structure svn path=/trunk/; revision=53451
This commit is contained in:
parent
b9ae58dc0d
commit
82454038b9
5 changed files with 183 additions and 26 deletions
|
@ -9,20 +9,118 @@ EXTERN BootMain:PROC
|
||||||
|
|
||||||
PUBLIC RealEntryPoint
|
PUBLIC RealEntryPoint
|
||||||
RealEntryPoint:
|
RealEntryPoint:
|
||||||
//mov ax, LMODE_DS
|
/* Setup segment selectors */
|
||||||
//mov ds, ax
|
mov ax, LMODE_DS
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
// mov ss, ax
|
||||||
|
|
||||||
//mov word ptr [HEX(b8000)], HEX(0e00) + '1'
|
//mov word ptr [HEX(b8000)], HEX(0e00) + '1'
|
||||||
|
|
||||||
|
/* Setup long mode stack */
|
||||||
|
mov rsp, qword ptr [stack64]
|
||||||
|
|
||||||
|
/* Continue execution */
|
||||||
|
jmp qword ptr [ContinueAddress]
|
||||||
|
|
||||||
|
ContinueAddress:
|
||||||
|
.double offset FrldrStartup
|
||||||
|
|
||||||
|
|
||||||
|
FrldrStartup:
|
||||||
|
|
||||||
|
/* Store BootDrive and BootPartition */
|
||||||
|
mov byte ptr [FrldrBootDrive], dl
|
||||||
|
xor eax, eax
|
||||||
|
mov al, dh
|
||||||
|
mov dword ptr [FrldrBootPartition], eax
|
||||||
|
|
||||||
|
/* Patch long jump with real mode entry point */
|
||||||
|
mov eax, dword ptr [BSS_RealModeEntry]
|
||||||
|
mov dword ptr [AddressOfRealModeEntryPoint], eax
|
||||||
|
|
||||||
/* GO! */
|
/* GO! */
|
||||||
xor rcx, rcx
|
xor rcx, rcx
|
||||||
call BootMain
|
call BootMain
|
||||||
|
|
||||||
|
/* We should never get here */
|
||||||
|
stop:
|
||||||
|
jmp stop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal function for realmode calls
|
||||||
|
* bx must be set to the ID of the realmode function to call. */
|
||||||
|
PUBLIC CallRealMode
|
||||||
|
CallRealMode:
|
||||||
|
/* Save current stack pointer */
|
||||||
|
mov qword ptr [stack64], rsp
|
||||||
|
|
||||||
|
/* Set continue address and switch to real mode */
|
||||||
|
lea rax, [CallRealMode_return]
|
||||||
|
mov qword ptr [ContinueAddress], rax
|
||||||
|
|
||||||
|
SwitchToReal:
|
||||||
|
/* Set sane segments */
|
||||||
|
mov ax, LMODE_DS
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
//mov ss, ax
|
||||||
|
|
||||||
|
mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
|
||||||
|
|
||||||
|
/* Save 64-bit stack pointer */
|
||||||
|
mov qword ptr [stack64], rsp
|
||||||
|
|
||||||
|
/* Step 1 - jump to compatibility segment */
|
||||||
|
jmp fword ptr [jumpvector]
|
||||||
|
|
||||||
|
jumpvector:
|
||||||
|
.long offset SwitchToRealCompSegment
|
||||||
|
.word CMODE_CS
|
||||||
|
|
||||||
|
SwitchToRealCompSegment:
|
||||||
|
/* Note: In fact the CPU is in 32 bit mode here. But it will interprete
|
||||||
|
the generated instructions accordingly. rax will become eax */
|
||||||
|
|
||||||
|
/* Step 2 - deactivate long mode, by disabling paging */
|
||||||
|
mov rax, cr0
|
||||||
|
and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
|
||||||
|
mov cr0, rax
|
||||||
|
|
||||||
|
// mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
|
||||||
|
|
||||||
|
/* Step 3 - jump to 16-bit segment to set the limit correctly */
|
||||||
|
.byte HEX(0EA) // 32bit long jmp
|
||||||
|
AddressOfRealModeEntryPoint:
|
||||||
|
.long 0 // receives address of RealModeEntryPoint
|
||||||
|
.word HEX(20)//RMODE_CS
|
||||||
|
nop
|
||||||
|
|
||||||
|
CallRealMode_return:
|
||||||
|
/* restore stack pointer */
|
||||||
|
mov rsp, qword ptr [stack64]
|
||||||
|
ret
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/* 64-bit stack pointer */
|
||||||
|
stack64:
|
||||||
|
.double STACK64ADDR
|
||||||
|
|
||||||
PUBLIC FrldrBootDrive
|
PUBLIC FrldrBootDrive
|
||||||
FrldrBootDrive:
|
FrldrBootDrive:
|
||||||
|
.byte 0
|
||||||
|
|
||||||
PUBLIC FrldrBootPartition
|
PUBLIC FrldrBootPartition
|
||||||
FrldrBootPartition:
|
FrldrBootPartition:
|
||||||
|
.long 0
|
||||||
|
|
||||||
PUBLIC PageDirectoryEnd
|
PUBLIC PageDirectoryEnd
|
||||||
PageDirectoryEnd:
|
PageDirectoryEnd:
|
||||||
|
@ -34,8 +132,57 @@ PUBLIC PnpBiosGetDeviceNodeCount
|
||||||
PnpBiosGetDeviceNodeCount:
|
PnpBiosGetDeviceNodeCount:
|
||||||
PUBLIC PnpBiosSupported
|
PUBLIC PnpBiosSupported
|
||||||
PnpBiosSupported:
|
PnpBiosSupported:
|
||||||
|
|
||||||
|
/* int Int386(int ivec<ecx>, REGS* in<rdx>, REGS* out<r8>); */
|
||||||
PUBLIC Int386
|
PUBLIC Int386
|
||||||
Int386:
|
Int386:
|
||||||
|
|
||||||
|
/* Save home registers */
|
||||||
|
mov r11, rsp
|
||||||
|
mov qword ptr [r11 + 8], rcx
|
||||||
|
mov qword ptr [r11 + 16], rdx
|
||||||
|
mov qword ptr [r11 + 24], r8
|
||||||
|
|
||||||
|
/* Save non-volatile registers */
|
||||||
|
push rbx
|
||||||
|
push rbp
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
|
||||||
|
/* Alloc stack space for home registers */
|
||||||
|
sub rsp, 40
|
||||||
|
//.ENDPROLOG
|
||||||
|
|
||||||
|
mov word ptr [HEX(0b8006)], HEX(0e00) + '3'
|
||||||
|
|
||||||
|
/* Copy the int vector to shared memory */
|
||||||
|
mov dword ptr [BSS_IntVector], ecx
|
||||||
|
|
||||||
|
/* Copy input registers */
|
||||||
|
mov rsi, rdx
|
||||||
|
mov rdi, BSS_RegisterSet
|
||||||
|
mov rcx, REGS_SIZE / 4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
/* Set the function ID and call real mode */
|
||||||
|
mov bx, FNID_Int386
|
||||||
|
call CallRealMode
|
||||||
|
|
||||||
|
/* Copy output registers */
|
||||||
|
mov rsi, BSS_RegisterSet
|
||||||
|
mov rdi, [r11 + 16]
|
||||||
|
mov rcx, REGS_SIZE / 4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
/* cleanup and return */
|
||||||
|
add rsp, 40
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rbp
|
||||||
|
pop rbx
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
PUBLIC PxeCallApi
|
PUBLIC PxeCallApi
|
||||||
PxeCallApi:
|
PxeCallApi:
|
||||||
PUBLIC __lgdt
|
PUBLIC __lgdt
|
||||||
|
|
|
@ -110,7 +110,7 @@ _Int386:
|
||||||
/* Copy input registers */
|
/* Copy input registers */
|
||||||
mov esi, dword ptr [Int386_regsin]
|
mov esi, dword ptr [Int386_regsin]
|
||||||
mov edi, BSS_RegisterSet
|
mov edi, BSS_RegisterSet
|
||||||
mov ecx, 9
|
mov ecx, REGS_SIZE / 4
|
||||||
rep movsd
|
rep movsd
|
||||||
|
|
||||||
/* Set the function ID */
|
/* Set the function ID */
|
||||||
|
@ -125,7 +125,7 @@ Int386_return:
|
||||||
/* Copy output registers */
|
/* Copy output registers */
|
||||||
mov esi, BSS_RegisterSet
|
mov esi, BSS_RegisterSet
|
||||||
mov edi, dword ptr [Int386_regsout]
|
mov edi, dword ptr [Int386_regsout]
|
||||||
mov ecx, 9
|
mov ecx, REGS_SIZE / 4
|
||||||
rep movsd
|
rep movsd
|
||||||
|
|
||||||
popa
|
popa
|
||||||
|
|
|
@ -100,14 +100,14 @@ Msg_LongModeSupported:
|
||||||
Msg_SwitchToLongMode:
|
Msg_SwitchToLongMode:
|
||||||
.ascii "Switching to long mode....", CR, LF, NUL
|
.ascii "Switching to long mode....", CR, LF, NUL
|
||||||
|
|
||||||
.align 4
|
.align 8
|
||||||
gdt:
|
gdt:
|
||||||
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
|
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
|
||||||
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 08: */
|
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 08: */
|
||||||
.word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 10: long mode cs */
|
.word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 10: long mode cs */
|
||||||
.word HEX(ffff), HEX(0000), HEX(f300), HEX(00cf) /* 18: long mode ds */
|
.word HEX(ffff), HEX(0000), HEX(f300), HEX(00cf) /* 18: long mode ds */
|
||||||
.word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 16-bit real mode CS */
|
.word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 20: 16-bit real mode CS */
|
||||||
.word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 16-bit real mode DS */
|
.word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 28: 16-bit real mode DS */
|
||||||
.word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode cs */
|
.word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode cs */
|
||||||
|
|
||||||
/* GDT table pointer */
|
/* GDT table pointer */
|
||||||
|
@ -232,7 +232,20 @@ BuildPageTables:
|
||||||
|
|
||||||
/* This is the entry point from long mode */
|
/* This is the entry point from long mode */
|
||||||
RealModeEntryPoint:
|
RealModeEntryPoint:
|
||||||
|
/* Disable Protected Mode */
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, HEX(0fffffffe) // ~0x00000001
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
/* Clear prefetch queue & correct CS */
|
||||||
|
ljmp16 0, offset InRealMode
|
||||||
|
|
||||||
|
InRealMode:
|
||||||
|
|
||||||
|
mov ax, HEX(0b800)
|
||||||
|
mov es, ax
|
||||||
|
mov word ptr es:[12], HEX(0e00) + '6'
|
||||||
|
jmp $
|
||||||
|
|
||||||
|
|
||||||
ExitToLongMode:
|
ExitToLongMode:
|
||||||
|
|
|
@ -26,12 +26,6 @@
|
||||||
#undef KIP0PCRADDRESS
|
#undef KIP0PCRADDRESS
|
||||||
#define KIP0PCRADDRESS 0xFFFFF78000001000ULL /* FIXME!!! */
|
#define KIP0PCRADDRESS 0xFFFFF78000001000ULL /* FIXME!!! */
|
||||||
|
|
||||||
#define STACK64ADDR 0x74000 /* The 64-bit stack top will be at 0x74000 */
|
|
||||||
|
|
||||||
/* Long mode selectors */
|
|
||||||
#define LMODE_CS 0x10
|
|
||||||
#define LMODE_DS 0x18
|
|
||||||
|
|
||||||
#define VA_MASK 0x0000FFFFFFFFFFFFUL
|
#define VA_MASK 0x0000FFFFFFFFFFFFUL
|
||||||
|
|
||||||
#define PtrToPfn(p) \
|
#define PtrToPfn(p) \
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define FREELDR_BASE HEX(F800)
|
#define FREELDR_BASE HEX(F800)
|
||||||
#define FREELDR_PE_BASE HEX(10000)
|
#define FREELDR_PE_BASE HEX(10000)
|
||||||
#define STACK32ADDR HEX(98000) /* The 32-bit stack top will be at 9000:8000, or 0xA8000 */
|
#define STACK32ADDR HEX(98000) /* The 32-bit stack top will be at 9000:8000, or 0xA8000 */
|
||||||
|
#define STACK64ADDR HEX(98000) /* The 64-bit stack top will be at 98000 */
|
||||||
#define BIOSCALLBUFFER HEX(98000) /* Buffer to store temporary data for any Int386() call */
|
#define BIOSCALLBUFFER HEX(98000) /* Buffer to store temporary data for any Int386() call */
|
||||||
#define FILESYSBUFFER HEX(80000) /* Buffer to store file system data (e.g. cluster buffer for FAT) */
|
#define FILESYSBUFFER HEX(80000) /* Buffer to store file system data (e.g. cluster buffer for FAT) */
|
||||||
#define DISKREADBUFFER HEX(90000) /* Buffer to store data read in from the disk via the BIOS */
|
#define DISKREADBUFFER HEX(90000) /* Buffer to store data read in from the disk via the BIOS */
|
||||||
|
@ -22,6 +23,20 @@
|
||||||
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */
|
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */
|
||||||
#define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */
|
#define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */
|
||||||
|
|
||||||
|
/* Layout of the REGS structure */
|
||||||
|
#define REGS_EAX 0
|
||||||
|
#define REGS_EBX 4
|
||||||
|
#define REGS_ECX 8
|
||||||
|
#define REGS_EDX 12
|
||||||
|
#define REGS_ESI 16
|
||||||
|
#define REGS_EDI 20
|
||||||
|
#define REGS_DS 24
|
||||||
|
#define REGS_ES 26
|
||||||
|
#define REGS_FS 28
|
||||||
|
#define REGS_GS 30
|
||||||
|
#define REGS_EFLAGS 32
|
||||||
|
#define REGS_SIZE 36
|
||||||
|
|
||||||
/* These addresses specify the realmode "BSS section" layout */
|
/* These addresses specify the realmode "BSS section" layout */
|
||||||
#define BSS_RealModeEntry (BSS_START + 0)
|
#define BSS_RealModeEntry (BSS_START + 0)
|
||||||
#define BSS_CallbackAddress (BSS_START + 4)
|
#define BSS_CallbackAddress (BSS_START + 4)
|
||||||
|
@ -52,19 +67,6 @@
|
||||||
#define FNID_PnpBiosGetDeviceNode 5
|
#define FNID_PnpBiosGetDeviceNode 5
|
||||||
#define FNID_BootLinuxKernel 6
|
#define FNID_BootLinuxKernel 6
|
||||||
|
|
||||||
/* Layout of the REGS structure */
|
|
||||||
#define REGS_EAX 0
|
|
||||||
#define REGS_EBX 4
|
|
||||||
#define REGS_ECX 8
|
|
||||||
#define REGS_EDX 12
|
|
||||||
#define REGS_ESI 16
|
|
||||||
#define REGS_EDI 20
|
|
||||||
#define REGS_DS 24
|
|
||||||
#define REGS_ES 26
|
|
||||||
#define REGS_FS 28
|
|
||||||
#define REGS_GS 30
|
|
||||||
#define REGS_EFLAGS 32
|
|
||||||
|
|
||||||
/* Flag Masks */
|
/* Flag Masks */
|
||||||
#define CR0_PE_SET HEX(00000001) /* OR this value with CR0 to enable pmode */
|
#define CR0_PE_SET HEX(00000001) /* OR this value with CR0 to enable pmode */
|
||||||
#define CR0_PE_CLR HEX(FFFFFFFE) /* AND this value with CR0 to disable pmode */
|
#define CR0_PE_CLR HEX(FFFFFFFE) /* AND this value with CR0 to disable pmode */
|
||||||
|
@ -80,6 +82,7 @@
|
||||||
/* Long mode selectors */
|
/* Long mode selectors */
|
||||||
#define LMODE_CS HEX(10)
|
#define LMODE_CS HEX(10)
|
||||||
#define LMODE_DS HEX(18)
|
#define LMODE_DS HEX(18)
|
||||||
|
#define CMODE_CS HEX(30)
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
/* Makes "x" a global variable or label */
|
/* Makes "x" a global variable or label */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue