[FREELDR] Several changes regarding chainloading and Linux boot.
[reactos.git] / boot / freeldr / freeldr / arch / i386 / entry.S
index 09003cf..9e7090f 100644 (file)
@@ -25,54 +25,58 @@ EXTERN _BootMain:PROC
 EXTERN _InitIdt:PROC
 EXTERN _i386Idt:DWORD
 //EXTERN _i386idtptr:FWORD
+EXTERN cmdline:DWORD
+
+EXTERN _DiskStopFloppyMotor:PROC
+
+#ifdef _USE_ML
+EXTERN __bss_start__:DWORD
+EXTERN __bss_end__:DWORD
+#endif
 
 .code32
 
 PUBLIC _RealEntryPoint
 _RealEntryPoint:
 
-       /* Setup segment selectors */
-       mov ax, PMODE_DS
-       mov ds, ax
-       mov es, ax
-       mov fs, ax
-       mov gs, ax
-       mov ss, ax
+    /* Setup segment selectors */
+    mov ax, PMODE_DS
+    mov ds, ax
+    mov es, ax
+    mov fs, ax
+    mov gs, ax
+    mov ss, ax
 
     /* Setup protected mode stack */
-       mov esp, dword ptr ds:[stack32]
+    mov esp, dword ptr ds:[stack32]
 
-       /* Load the IDT */
+    /* Load the IDT */
 #ifdef _USE_ML
     lidt fword ptr ds:[i386idtptr]
 #else
-       lidt i386idtptr
+    lidt i386idtptr
 #endif
 
     /* Continue execution */
     jmp dword ptr ds:[ContinueAddress]
 
+PUBLIC ContinueAddress
 ContinueAddress:
     .long _FrldrStartup
 
-
 _FrldrStartup:
 
     /* Store BootDrive and BootPartition */
-       mov byte ptr ds:[_FrldrBootDrive], dl
-       xor eax, eax
+    mov byte ptr ds:[_FrldrBootDrive], dl
+    xor eax, eax
     mov al, dh
-       mov dword ptr ds:[_FrldrBootPartition], eax
+    mov dword ptr ds:[_FrldrBootPartition], eax
 
     /* Patch long jump with real mode entry point */
     mov eax, dword ptr ds:[BSS_RealModeEntry]
     mov dword ptr ds:[SwitchToReal16Address], eax
 
-    /* Initialize the idt */
-    call _InitIdt
-
-#ifndef _USE_ML
-    /* Clean out bss */
+    /* Clean out BSS */
     xor eax, eax
     mov edi, offset __bss_start__
     mov ecx, offset __bss_end__ + 3
@@ -80,76 +84,82 @@ _FrldrStartup:
     shr ecx, 2
     rep stosd
 
+    /* Initialize the idt */
+    call _InitIdt
+
     /* Pass the command line to BootMain */
     mov eax, offset cmdline
-#else
-    xor eax, eax
-#endif
 
-       /* GO! */
-       push eax
-       call _BootMain
+    /* GO! */
+    push eax
+    call _BootMain
 
-       /* We should never get here */
+    /* We should never get here */
 stop:
-       jmp     stop
-       nop
-       nop
+    jmp short stop
+    nop
+    nop
+
+
+PUBLIC _Reboot
+_Reboot:
+    /* Stop the floppy drive motor */
+    call _DiskStopFloppyMotor
+
+    /* Set the function ID and switch to real mode (we don't return) */
+    mov bx, FNID_Reboot
+    jmp SwitchToReal
 
-Int386_regsin:
-       .long 0
-Int386_regsout:
-       .long 0
 
 /*
- * int Int386(int ivec, REGS* in, REGS* out);
+ * VOID __cdecl Relocator16Boot(
+ *     IN REGS*  In,
+ *     IN USHORT StackSegment,
+ *     IN USHORT StackPointer,
+ *     IN USHORT CodeSegment,
+ *     IN USHORT CodePointer);
+ *
+ * RETURNS: Nothing.
+ *
+ * NOTE: The implementation of this function is similar to that of Int386(),
+ * with the proviso that no attempt is done to save the original values of
+ * the registers since we will not need them anyway, as we do not return back
+ * to the caller but instead place the machine in a permanent new CPU state.
  */
-PUBLIC _Int386
-_Int386:
-
-       /* Get the function parameters */
-       mov eax, dword ptr [esp + 4]
-    mov dword ptr ds:[BSS_IntVector], eax
-       mov eax, dword ptr [esp + 8]
-       mov dword ptr [Int386_regsin], eax
-       mov eax, dword ptr [esp + 12]
-       mov dword ptr [Int386_regsout], eax
-
-       /* Save all registers + segment registers */
-       push ds
-       push es
-       push fs
-       push gs
-       pusha
+PUBLIC _Relocator16Boot
+_Relocator16Boot:
 
     /* Copy input registers */
-    mov esi, dword ptr [Int386_regsin]
+    mov esi, dword ptr [esp + 4]
     mov edi, BSS_RegisterSet
     mov ecx, REGS_SIZE / 4
     rep movsd
 
-    /* Set the function ID */
-    mov bx, FNID_Int386
+    /* Set the stack segment/offset */
+    // Since BSS_CallbackReturn contains a ULONG, store in its high word
+    // the stack segment and in its low word the stack offset.
+    mov ax, word ptr [esp + 8]
+    shl eax, 16
+    mov ax, word ptr [esp + 12]
+    mov dword ptr ds:[BSS_CallbackReturn], eax
+
+    /*
+     * Set the code segment/offset (Copy entry point)
+     * NOTE: We permanently *ERASE* the contents of ds:[BSS_RealModeEntry]
+     * but it is not a problem since we are going to place the machine in
+     * a permanent new CPU state.
+     */
+    // Since BSS_RealModeEntry contains a ULONG, store in its high word
+    // the code segment and in its low word the code offset.
+    mov ax, word ptr [esp + 16]
+    shl eax, 16
+    mov ax, word ptr [esp + 20]
+    mov dword ptr ds:[BSS_RealModeEntry], eax
 
-    /* Set continue address and switch to real mode */
-    mov dword ptr [ContinueAddress], offset Int386_return
+    /* Set the function ID and switch to real mode (we don't return) */
+    mov bx, FNID_Relocator16Boot
     jmp SwitchToReal
 
-Int386_return:
-
-    /* Copy output registers */
-    mov esi, BSS_RegisterSet
-    mov edi, dword ptr [Int386_regsout]
-    mov ecx, REGS_SIZE / 4
-    rep movsd
-
-    popa
-    pop gs
-    pop fs
-    pop es
-    pop ds
-    ret
-
 
 /*
  * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
@@ -158,71 +168,42 @@ Int386_return:
  */
 PUBLIC _PxeCallApi
 _PxeCallApi:
-    push ebp
-    mov ebp, esp
-
-    pusha
-    push es
-
     /* copy entry point */
-    mov eax, [ebp + 8]
+    mov eax, [esp + 4]
     shl eax, 16
-    mov ax, [ebp + 12]
+    mov ax, [esp + 8]
     mov dword ptr ds:[BSS_PxeEntryPoint], eax
 
     /* copy function */
-    mov ax, [ebp + 16]
+    mov ax, [esp + 12]
     mov word ptr ds:[BSS_PxeFunction], ax
 
     /* convert pointer to data buffer to segment/offset */
-    mov eax, [ebp + 20]
+    mov eax, [esp + 16]
     shr eax, 4
     and eax, HEX(0f000)
     mov word ptr ds:[BSS_PxeBufferSegment], ax
-    mov eax, [ebp + 20]
+    mov eax, [esp + 16]
     and eax, HEX(0ffff)
     mov word ptr ds:[BSS_PxeBufferOffset], ax
 
+    pusha
+
     /* Set the function ID and call realmode */
     mov bx, FNID_PxeCallApi
     call i386CallRealMode
 
-    pop es
     popa
 
-    mov esp, ebp
-    pop ebp
-
     mov ax, word ptr [BSS_PxeResult]
 
     ret
 
 
-PUBLIC _Reboot
-_Reboot:
-    /* Set the function ID */
-    mov bx, FNID_Reboot
-
-    /*Switch to real mode (We don't return) */
-    jmp SwitchToReal
-
-
-PUBLIC _ChainLoadBiosBootSectorCode
-_ChainLoadBiosBootSectorCode:
-    /* Set the boot drive */
-    mov dl, byte ptr [_FrldrBootDrive]
-
-    /* Set the function ID */
-    mov bx, FNID_ChainLoadBiosBootSectorCode
-
-    /*Switch to real mode (We don't return) */
-    jmp SwitchToReal
-
-
 PUBLIC i386CallRealMode
 i386CallRealMode:
     /* Set continue address and switch to real mode */
-    mov dword ptr [ContinueAddress], offset i386CallRealMode_return
+    mov dword ptr ds:[ContinueAddress], offset i386CallRealMode_return
     jmp SwitchToReal
 i386CallRealMode_return:
     ret
@@ -231,19 +212,20 @@ i386CallRealMode_return:
 /* Entrypoint for realmode function calls
  * ContinueAddress must be set to the return point from realmode
  * bx must be set to the ID of the realmode function to call. */
+PUBLIC SwitchToReal
 SwitchToReal:
     /* Set sane segments */
-       mov ax, PMODE_DS
-       mov ds, ax
-       mov es, ax
-       mov fs, ax
-       mov gs, ax
-       mov ss, ax
+    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
+    /* Save 32-bit stack pointer */
+    mov dword ptr ds:[stack32], esp
 
-       /* jmp to 16-bit segment to set the limit correctly */
+    /* 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
@@ -251,60 +233,56 @@ SwitchToReal16Address:
     nop
 
 
-       /* 16-bit stack pointer */
+    /* 16-bit stack pointer */
 stack16:
-       .word   STACK16ADDR
+    .word STACK16ADDR
 
-       /* 32-bit stack pointer */
+    /* 32-bit stack pointer */
 stack32:
-       .long   STACKADDR
+    .long STACKADDR
 
-    .align 4   /* force 4-byte alignment */
+    .align 4    /* force 4-byte alignment */
 gdt:
-       /* NULL Descriptor */
-       .word HEX(0000)
-       .word HEX(0000)
-       .word HEX(0000)
-       .word HEX(0000)
-
-       /* 32-bit flat CS */
-       .word HEX(FFFF)
-       .word HEX(0000)
-       .word HEX(9A00)
-       .word HEX(00CF)
-
-       /* 32-bit flat DS */
-       .word HEX(FFFF)
-       .word HEX(0000)
-       .word HEX(9200)
-       .word HEX(00CF)
-
-       /* 16-bit real mode CS */
-       .word HEX(FFFF)
-       .word HEX(0000)
-       .word HEX(9E00)
-       .word HEX(0000)
-
-       /* 16-bit real mode DS */
-       .word HEX(FFFF)
-       .word HEX(0000)
-       .word HEX(9200)
-       .word HEX(0000)
+    /* NULL Descriptor */
+   .word HEX(0000)
+   .word HEX(0000)
+   .word HEX(0000)
+   .word HEX(0000)
+
+    /* 32-bit flat CS */
+    .word HEX(FFFF)
+    .word HEX(0000)
+    .word HEX(9A00)
+    .word HEX(00CF)
+
+    /* 32-bit flat DS */
+    .word HEX(FFFF)
+    .word HEX(0000)
+    .word HEX(9200)
+    .word HEX(00CF)
+
+    /* 16-bit real mode CS */
+    .word HEX(FFFF)
+    .word HEX(0000)
+    .word HEX(9E00)
+    .word HEX(0000)
+
+    /* 16-bit real mode DS */
+    .word HEX(FFFF)
+    .word HEX(0000)
+    .word HEX(9200)
+    .word HEX(0000)
 
 /* GDT table pointer */
 gdtptr:
-       .word HEX(27)           /* Limit */
-       .long gdt                       /* Base Address */
-
-/* Real-mode IDT pointer */
-rmode_idtptr:
-       .word HEX(3ff)          /* Limit */
-       .long 0                 /* Base Address */
+    .word HEX(27)       /* Limit */
+    .long gdt           /* Base Address */
 
+// See _i386IdtDescriptor
 PUBLIC i386idtptr
 i386idtptr:
-    .word 255                  /* Limit */
-    .long _i386Idt             /* Base Address */
+    .word 255           /* Limit */
+    .long _i386Idt      /* Base Address */
 
 PUBLIC _FrldrBootDrive
 _FrldrBootDrive: