mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 19:26:16 +00:00
[FREELDR]
Start implementing a realmode callback mechanism svn path=/trunk/; revision=52226
This commit is contained in:
@@ -44,9 +44,9 @@ _RealEntryPoint:
|
||||
lidt i386idtptr
|
||||
|
||||
/* Continue execution */
|
||||
jmp dword ptr [_ContinueAddress]
|
||||
jmp dword ptr [ContinueAddress]
|
||||
|
||||
_ContinueAddress:
|
||||
ContinueAddress:
|
||||
.long _FrldrStartup
|
||||
|
||||
|
||||
@@ -59,6 +59,12 @@ _FrldrStartup:
|
||||
mov al, dh
|
||||
mov dword ptr [_FrldrBootPartition], eax
|
||||
|
||||
/* Patch long jump with real mode entry point */
|
||||
mov eax, dword ptr ds:[BSS_RealModeEntry]
|
||||
mov dword ptr ds:[SwitchToReal16Address], eax
|
||||
|
||||
call _Int386_ // test
|
||||
|
||||
/* GO! */
|
||||
xor eax, eax
|
||||
push eax
|
||||
@@ -216,6 +222,51 @@ PUBLIC _EnableA20
|
||||
_EnableA20:
|
||||
ret
|
||||
|
||||
PUBLIC _Int386_
|
||||
_Int386_:
|
||||
/* Save all registers + segment registers */
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
pusha
|
||||
|
||||
/* Set the callback index */
|
||||
mov cx, 1234
|
||||
|
||||
/* Set continue address and switch to real mode */
|
||||
mov dword ptr [ContinueAddress], offset Int386_return
|
||||
jmp SwitchToReal
|
||||
|
||||
Int386_return:
|
||||
|
||||
popa
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
ret
|
||||
|
||||
|
||||
SwitchToReal:
|
||||
/* Set sane segments */
|
||||
mov ax, PMODE_DS
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
/* Save 32-bit stack pointer */
|
||||
mov dword ptr [stack32], esp
|
||||
|
||||
/* jmp to 16-bit segment to set the limit correctly */
|
||||
.byte HEX(0ea) // jmp far RMODE_CS:switch_to_real16
|
||||
SwitchToReal16Address:
|
||||
.long 0 // receives address of switch_to_real16
|
||||
.word RMODE_CS
|
||||
nop
|
||||
|
||||
|
||||
/* Multiboot support
|
||||
*
|
||||
|
||||
@@ -30,6 +30,9 @@ RealModeEntryPoint:
|
||||
/* Enable A20 address line */
|
||||
call EnableA20
|
||||
|
||||
/* Safe real mode entry point in shared memory */
|
||||
mov dword ptr [BSS_RealModeEntry], offset switch_to_real16
|
||||
|
||||
/* Get address of optional header */
|
||||
mov eax, dword ptr ds:[FREELDR_PE_BASE + IMAGE_DOS_HEADER_e_lfanew]
|
||||
add eax, FREELDR_PE_BASE + 4 + IMAGE_FILE_HEADER_SIZE
|
||||
@@ -38,20 +41,74 @@ RealModeEntryPoint:
|
||||
mov eax, dword ptr ds:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
|
||||
add eax, FREELDR_PE_BASE
|
||||
|
||||
/* Safe the entry point */
|
||||
mov dword ptr [BSS_EntryPoint], eax
|
||||
|
||||
/* Patch the long jump instruction */
|
||||
mov word ptr [pm_offset], ax
|
||||
|
||||
jmp exit_to_protected
|
||||
|
||||
|
||||
/* This is the entry point from protected mode */
|
||||
switch_to_real16:
|
||||
|
||||
/* Restore segment registers to correct limit */
|
||||
mov ax, RMODE_DS
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
/* Disable Protected Mode */
|
||||
mov eax, cr0
|
||||
and eax, CR0_PE_CLR
|
||||
mov cr0, eax
|
||||
|
||||
/* Clear prefetch queue & correct CS */
|
||||
ljmp16 0, inrmode
|
||||
|
||||
inrmode:
|
||||
/* Set real mode segments */
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
/* Clear out the high 16-bits of ESP */
|
||||
/* This is needed because I have one */
|
||||
/* machine that hangs when booted to dos if */
|
||||
/* anything other than 0x0000 is in the high */
|
||||
/* 16-bits of ESP. Even though real-mode */
|
||||
/* code should only use SP and not ESP. */
|
||||
xor esp, esp
|
||||
|
||||
/* Restore real mode stack */
|
||||
mov sp, word ptr ds:[stack16]
|
||||
|
||||
/* Load IDTR with real mode value */
|
||||
lidt rmode_idtptr
|
||||
|
||||
sti /* These are ok now */
|
||||
|
||||
/* Do the callback, specified by cx */
|
||||
// call word ptr CallbackTable[cx * 4]
|
||||
mov ax, cx
|
||||
call writehex4
|
||||
|
||||
/*
|
||||
* Switches the processor to protected mode
|
||||
* it destroys eax
|
||||
*/
|
||||
switch_to_prot:
|
||||
exit_to_protected:
|
||||
|
||||
cli
|
||||
|
||||
/* Safe current stack pointer */
|
||||
mov word ptr ds:[stack16], sp
|
||||
|
||||
/* Load the GDT */
|
||||
lgdt gdtptr
|
||||
lgdt gdtptr
|
||||
|
||||
/* Enable Protected Mode */
|
||||
mov eax, cr0
|
||||
@@ -67,6 +124,7 @@ pm_offset:
|
||||
|
||||
|
||||
|
||||
|
||||
/* 16-bit stack pointer */
|
||||
stack16:
|
||||
.word STACK16ADDR
|
||||
@@ -109,8 +167,14 @@ gdtptr:
|
||||
.word HEX(27) /* Limit */
|
||||
.long gdt /* Base Address */
|
||||
|
||||
.org 1024
|
||||
/* Real-mode IDT pointer */
|
||||
rmode_idtptr:
|
||||
.word HEX(3ff) /* Limit */
|
||||
.long 0 /* Base Address */
|
||||
|
||||
//.org 1024
|
||||
|
||||
#include "int386.inc"
|
||||
#include "helpers.inc"
|
||||
|
||||
.org (FREELDR_PE_BASE - FREELDR_BASE)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
Int386:
|
||||
/* Get the interupt vector and patch the opcode */
|
||||
mov al, byte ptr ds:[BSS_IntVector]
|
||||
mov byte ptr ds:[Int386_vector_opcode], al
|
||||
|
||||
/* Setup the registers */
|
||||
mov ax, word ptr cs:[BSS_RegisterSet + REGS_DS]
|
||||
mov ds, ax /* DS register */
|
||||
mov ax, word ptr cs:[BSS_RegisterSet + REGS_ES]
|
||||
mov es, ax /* ES register */
|
||||
mov ax, word ptr cs:[BSS_RegisterSet + REGS_FS]
|
||||
mov fs, ax /* FS register */
|
||||
mov ax, word ptr cs:[BSS_RegisterSet + REGS_GS]
|
||||
mov gs, ax /* GS register */
|
||||
|
||||
mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EAX] /* EAX register */
|
||||
mov ebx, dword ptr cs:[BSS_RegisterSet + REGS_EBX] /* EBX register */
|
||||
mov ecx, dword ptr cs:[BSS_RegisterSet + REGS_ECX] /* ECX register */
|
||||
mov edx, dword ptr cs:[BSS_RegisterSet + REGS_EDX] /* EDX register */
|
||||
mov esi, dword ptr cs:[BSS_RegisterSet + REGS_ESI] /* ESI register */
|
||||
mov edi, dword ptr cs:[BSS_RegisterSet + REGS_EDI] /* EDI register */
|
||||
|
||||
/* Do not set the flags register */
|
||||
/* only return its value in regsout */
|
||||
|
||||
/* Call the interrupt vector */
|
||||
/*int Int386_vector*/
|
||||
.byte 0xcd
|
||||
Int386_vector_opcode:
|
||||
.byte 0x00
|
||||
|
||||
/* Save the registers */
|
||||
mov dword ptr cs:[BSS_RegisterSet + REGS_EAX], eax /* EAX register */
|
||||
mov dword ptr cs:[BSS_RegisterSet + REGS_EBX], ebx /* EBX register */
|
||||
mov dword ptr cs:[BSS_RegisterSet + REGS_ECX], ecx /* ECX register */
|
||||
mov dword ptr cs:[BSS_RegisterSet + REGS_EDX], edx /* EDX register */
|
||||
mov dword ptr cs:[BSS_RegisterSet + REGS_ESI], esi /* ESI register */
|
||||
mov dword ptr cs:[BSS_RegisterSet + REGS_EDI], edi /* EDI register */
|
||||
|
||||
mov ax, ds /* DS register */
|
||||
mov word ptr cs:[BSS_RegisterSet + REGS_DS], ax
|
||||
mov ax, es /* ES register */
|
||||
mov word ptr cs:[BSS_RegisterSet + REGS_ES], ax
|
||||
mov ax, fs /* FS register */
|
||||
mov word ptr cs:[BSS_RegisterSet + REGS_FS], ax
|
||||
mov ax, gs /* GS register */
|
||||
mov word ptr cs:[BSS_RegisterSet + REGS_GS], ax
|
||||
|
||||
pushf
|
||||
pop dword ptr cs:[BSS_RegisterSet + REGS_EFLAGS] /* EFLAGS register */
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@@ -17,11 +17,26 @@
|
||||
#define DISKREADBUFFER_SIZE 512
|
||||
|
||||
/* These addresses specify the realmode "BSS section" layout */
|
||||
#define BSS_EntryPoint (BSS_START + 0)
|
||||
#define BSS_RealModeEntry (BSS_START + 0)
|
||||
#define BSS_CallbackAddress (BSS_START + 4)
|
||||
#define BSS_CallbackReturn (BSS_START + 8)
|
||||
#define BSS_BootDrive (BSS_START + 12)
|
||||
#define BSS_BootPartition (BSS_START + 16)
|
||||
|
||||
#define BSS_RegisterSet (BSS_START + 16) /* size = 36 */
|
||||
#define BSS_IntVector (BSS_START + 52)
|
||||
// next 52
|
||||
|
||||
/* 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
|
||||
|
||||
Reference in New Issue
Block a user