Author: tkreuzer Date: Tue Jun 14 12:17:28 2011 New Revision: 52226
URL: http://svn.reactos.org/svn/reactos?rev=52226&view=rev Log: [FREELDR] Start implementing a realmode callback mechanism
Added: trunk/reactos/boot/freeldr/freeldr/arch/realmode/int386.inc Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S trunk/reactos/boot/freeldr/freeldr/arch/realmode/i386.S trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S [iso-8859-1] Tue Jun 14 12:17:28 2011 @@ -44,9 +44,9 @@ lidt i386idtptr
/* Continue execution */ - jmp dword ptr [_ContinueAddress] - -_ContinueAddress: + jmp dword ptr [ContinueAddress] + +ContinueAddress: .long _FrldrStartup
@@ -58,6 +58,12 @@ mov dword ptr [_FrldrBootDrive], eax 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 @@ -215,6 +221,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
Modified: trunk/reactos/boot/freeldr/freeldr/arch/realmode/i386.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/r... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/realmode/i386.S [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/realmode/i386.S [iso-8859-1] Tue Jun 14 12:17:28 2011 @@ -30,6 +30,9 @@ /* 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 @@ 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 @@ -64,6 +121,7 @@ .word 0 // receives address of PE entry point .word PMODE_CS nop +
@@ -109,8 +167,14 @@ .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)
Added: trunk/reactos/boot/freeldr/freeldr/arch/realmode/int386.inc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/r... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/realmode/int386.inc (added) +++ trunk/reactos/boot/freeldr/freeldr/arch/realmode/int386.inc [iso-8859-1] Tue Jun 14 12:17:28 2011 @@ -1,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 + + +
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] Tue Jun 14 12:17:28 2011 @@ -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