[ros-diffs] [tkreuzer] 52226: [FREELDR] Start implementing a realmode callback mechanism

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Tue Jun 14 12:17:29 UTC 2011


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/i386/entry.S?rev=52226&r1=52225&r2=52226&view=diff
==============================================================================
--- 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/realmode/i386.S?rev=52226&r1=52225&r2=52226&view=diff
==============================================================================
--- 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/realmode/int386.inc?rev=52226&view=auto
==============================================================================
--- 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/include/arch/pc/x86common.h?rev=52226&r1=52225&r2=52226&view=diff
==============================================================================
--- 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




More information about the Ros-diffs mailing list