mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +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
|
||||
RealEntryPoint:
|
||||
//mov ax, LMODE_DS
|
||||
//mov ds, ax
|
||||
/* Setup segment selectors */
|
||||
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'
|
||||
|
||||
/* 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! */
|
||||
xor rcx, rcx
|
||||
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
|
||||
FrldrBootDrive:
|
||||
.byte 0
|
||||
|
||||
PUBLIC FrldrBootPartition
|
||||
FrldrBootPartition:
|
||||
.long 0
|
||||
|
||||
PUBLIC PageDirectoryEnd
|
||||
PageDirectoryEnd:
|
||||
|
@ -34,8 +132,57 @@ PUBLIC PnpBiosGetDeviceNodeCount
|
|||
PnpBiosGetDeviceNodeCount:
|
||||
PUBLIC PnpBiosSupported
|
||||
PnpBiosSupported:
|
||||
|
||||
/* int Int386(int ivec<ecx>, REGS* in<rdx>, REGS* out<r8>); */
|
||||
PUBLIC 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
|
||||
PxeCallApi:
|
||||
PUBLIC __lgdt
|
||||
|
|
|
@ -110,7 +110,7 @@ _Int386:
|
|||
/* Copy input registers */
|
||||
mov esi, dword ptr [Int386_regsin]
|
||||
mov edi, BSS_RegisterSet
|
||||
mov ecx, 9
|
||||
mov ecx, REGS_SIZE / 4
|
||||
rep movsd
|
||||
|
||||
/* Set the function ID */
|
||||
|
@ -125,7 +125,7 @@ Int386_return:
|
|||
/* Copy output registers */
|
||||
mov esi, BSS_RegisterSet
|
||||
mov edi, dword ptr [Int386_regsout]
|
||||
mov ecx, 9
|
||||
mov ecx, REGS_SIZE / 4
|
||||
rep movsd
|
||||
|
||||
popa
|
||||
|
|
|
@ -100,14 +100,14 @@ Msg_LongModeSupported:
|
|||
Msg_SwitchToLongMode:
|
||||
.ascii "Switching to long mode....", CR, LF, NUL
|
||||
|
||||
.align 4
|
||||
.align 8
|
||||
gdt:
|
||||
.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(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(9E00), HEX(0000) /* 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(9E00), HEX(0000) /* 20: 16-bit real mode CS */
|
||||
.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 */
|
||||
|
||||
/* GDT table pointer */
|
||||
|
@ -232,7 +232,20 @@ BuildPageTables:
|
|||
|
||||
/* This is the entry point from long mode */
|
||||
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:
|
||||
|
|
|
@ -26,12 +26,6 @@
|
|||
#undef KIP0PCRADDRESS
|
||||
#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 PtrToPfn(p) \
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define FREELDR_BASE HEX(F800)
|
||||
#define FREELDR_PE_BASE HEX(10000)
|
||||
#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 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 */
|
||||
|
@ -22,6 +23,20 @@
|
|||
#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 */
|
||||
|
||||
/* 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 */
|
||||
#define BSS_RealModeEntry (BSS_START + 0)
|
||||
#define BSS_CallbackAddress (BSS_START + 4)
|
||||
|
@ -52,19 +67,6 @@
|
|||
#define FNID_PnpBiosGetDeviceNode 5
|
||||
#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 */
|
||||
#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 */
|
||||
|
@ -80,6 +82,7 @@
|
|||
/* Long mode selectors */
|
||||
#define LMODE_CS HEX(10)
|
||||
#define LMODE_DS HEX(18)
|
||||
#define CMODE_CS HEX(30)
|
||||
//#endif
|
||||
|
||||
/* Makes "x" a global variable or label */
|
||||
|
|
Loading…
Reference in a new issue