mirror of
https://github.com/reactos/reactos.git
synced 2024-06-25 15:31:47 +00:00
![Hermès Bélusca-Maïto](/assets/img/avatar_default.png)
- Move DiskStopFloppyMotor() calls into the implementations of Boot(New)LinuxKernel() and Reboot() HW functions, and the explanation comments in ChainLoadBiosBootSectorCode(). - Remove unneeded DiskStopFloppyMotor() dummies in ARM and PPC code. - Use more adequate bitmask value to be sent to floppy's Digital Output Register for shutting down its motor (based on OSDev & our floppy controller driver).
288 lines
6.2 KiB
ArmAsm
288 lines
6.2 KiB
ArmAsm
/*
|
|
* FreeLoader
|
|
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include <asm.inc>
|
|
#include <arch/pc/x86common.h>
|
|
#include <arch/pc/pcbios.h>
|
|
|
|
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 protected mode stack */
|
|
mov esp, dword ptr ds:[stack32]
|
|
|
|
/* Load the IDT */
|
|
#ifdef _USE_ML
|
|
lidt fword ptr ds:[i386idtptr]
|
|
#else
|
|
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 al, dh
|
|
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
|
|
|
|
/* Clean out BSS */
|
|
xor eax, eax
|
|
mov edi, offset __bss_start__
|
|
mov ecx, offset __bss_end__ + 3
|
|
sub ecx, edi
|
|
shr ecx, 2
|
|
rep stosd
|
|
|
|
/* Initialize the idt */
|
|
call _InitIdt
|
|
|
|
/* Pass the command line to BootMain */
|
|
mov eax, offset cmdline
|
|
|
|
/* GO! */
|
|
push eax
|
|
call _BootMain
|
|
|
|
/* We should never get here */
|
|
stop:
|
|
jmp short stop
|
|
nop
|
|
nop
|
|
|
|
|
|
PUBLIC _Reboot
|
|
_Reboot:
|
|
/* Stop the floppy drive motor */
|
|
call _DiskStopFloppyMotor
|
|
|
|
/* Set the function ID */
|
|
mov bx, FNID_Reboot
|
|
|
|
/* Switch to real mode (we don't return) */
|
|
jmp SwitchToReal
|
|
|
|
|
|
/*
|
|
* VOID __cdecl ChainLoadBiosBootSectorCode(
|
|
* IN UCHAR BootDrive OPTIONAL,
|
|
* IN ULONG BootPartition OPTIONAL);
|
|
*
|
|
* RETURNS: Nothing
|
|
*/
|
|
PUBLIC _ChainLoadBiosBootSectorCode
|
|
_ChainLoadBiosBootSectorCode:
|
|
/* Set the boot drive */
|
|
mov dl, [esp + 4]
|
|
test dl, dl
|
|
jnz set_part
|
|
mov dl, byte ptr ds:[_FrldrBootDrive]
|
|
|
|
/* Set the boot partition */
|
|
set_part:
|
|
mov eax, [esp + 8]
|
|
test eax, eax
|
|
jnz continue
|
|
mov eax, dword ptr ds:[_FrldrBootPartition]
|
|
continue:
|
|
/* Store the 1-byte truncated partition number in DH */
|
|
mov dh, al
|
|
|
|
/*
|
|
* Don't stop the floppy drive motor when we are just booting a bootsector,
|
|
* a drive, or a partition. If we were to stop the floppy motor, the BIOS
|
|
* wouldn't be informed and if the next read is to a floppy then the BIOS
|
|
* will still think the motor is on and this will result in a read error.
|
|
*/
|
|
// call _DiskStopFloppyMotor
|
|
|
|
/* Set the function ID */
|
|
mov bx, FNID_ChainLoadBiosBootSectorCode
|
|
|
|
/* Switch to real mode (we don't return) */
|
|
jmp SwitchToReal
|
|
|
|
|
|
/*
|
|
* U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
|
|
*
|
|
* RETURNS:
|
|
*/
|
|
PUBLIC _PxeCallApi
|
|
_PxeCallApi:
|
|
/* copy entry point */
|
|
mov eax, [esp + 4]
|
|
shl eax, 16
|
|
mov ax, [esp + 8]
|
|
mov dword ptr ds:[BSS_PxeEntryPoint], eax
|
|
|
|
/* copy function */
|
|
mov ax, [esp + 12]
|
|
mov word ptr ds:[BSS_PxeFunction], ax
|
|
|
|
/* convert pointer to data buffer to segment/offset */
|
|
mov eax, [esp + 16]
|
|
shr eax, 4
|
|
and eax, HEX(0f000)
|
|
mov word ptr ds:[BSS_PxeBufferSegment], ax
|
|
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
|
|
|
|
popa
|
|
|
|
mov ax, word ptr [BSS_PxeResult]
|
|
|
|
ret
|
|
|
|
|
|
PUBLIC i386CallRealMode
|
|
i386CallRealMode:
|
|
/* Set continue address and switch to real mode */
|
|
mov dword ptr ds:[ContinueAddress], offset i386CallRealMode_return
|
|
jmp SwitchToReal
|
|
i386CallRealMode_return:
|
|
ret
|
|
|
|
|
|
/* 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
|
|
|
|
/* Save 32-bit stack pointer */
|
|
mov dword ptr ds:[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
|
|
|
|
|
|
/* 16-bit stack pointer */
|
|
stack16:
|
|
.word STACK16ADDR
|
|
|
|
/* 32-bit stack pointer */
|
|
stack32:
|
|
.long STACKADDR
|
|
|
|
.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)
|
|
|
|
/* GDT table pointer */
|
|
gdtptr:
|
|
.word HEX(27) /* Limit */
|
|
.long gdt /* Base Address */
|
|
|
|
// See _i386IdtDescriptor
|
|
PUBLIC i386idtptr
|
|
i386idtptr:
|
|
.word 255 /* Limit */
|
|
.long _i386Idt /* Base Address */
|
|
|
|
PUBLIC _FrldrBootDrive
|
|
_FrldrBootDrive:
|
|
.byte 0
|
|
|
|
PUBLIC _FrldrBootPartition
|
|
_FrldrBootPartition:
|
|
.long 0
|
|
|
|
END
|