3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <arch/pc/x86common.h>
22 #include <arch/pc/pcbios.h>
27 //EXTERN _i386idtptr:FWORD
30 EXTERN _DiskStopFloppyMotor:PROC
33 EXTERN __bss_start__:DWORD
34 EXTERN __bss_end__:DWORD
39 PUBLIC _RealEntryPoint
42 /* Setup segment selectors */
50 /* Setup protected mode stack */
51 mov esp, dword ptr ds:[stack32]
55 lidt fword ptr ds:[i386idtptr]
60 /* Continue execution */
61 jmp dword ptr ds:[ContinueAddress]
63 PUBLIC ContinueAddress
69 /* Store BootDrive and BootPartition */
70 mov byte ptr ds:[_FrldrBootDrive], dl
73 mov dword ptr ds:[_FrldrBootPartition], eax
75 /* Patch long jump with real mode entry point */
76 mov eax, dword ptr ds:[BSS_RealModeEntry]
77 mov dword ptr ds:[SwitchToReal16Address], eax
81 mov edi, offset __bss_start__
82 mov ecx, offset __bss_end__ + 3
87 /* Initialize the idt */
90 /* Pass the command line to BootMain */
91 mov eax, offset cmdline
97 /* We should never get here */
106 /* Stop the floppy drive motor */
107 call _DiskStopFloppyMotor
109 /* Set the function ID and switch to real mode (we don't return) */
115 * VOID __cdecl Relocator16Boot(
117 * IN USHORT StackSegment,
118 * IN USHORT StackPointer,
119 * IN USHORT CodeSegment,
120 * IN USHORT CodePointer);
124 * NOTE: The implementation of this function is similar to that of Int386(),
125 * with the proviso that no attempt is done to save the original values of
126 * the registers since we will not need them anyway, as we do not return back
127 * to the caller but instead place the machine in a permanent new CPU state.
129 PUBLIC _Relocator16Boot
132 /* Copy input registers */
133 mov esi, dword ptr [esp + 4]
134 mov edi, BSS_RegisterSet
135 mov ecx, REGS_SIZE / 4
138 /* Set the stack segment/offset */
139 // Since BSS_CallbackReturn contains a ULONG, store in its high word
140 // the stack segment and in its low word the stack offset.
141 mov ax, word ptr [esp + 8]
143 mov ax, word ptr [esp + 12]
144 mov dword ptr ds:[BSS_CallbackReturn], eax
147 * Set the code segment/offset (Copy entry point)
148 * NOTE: We permanently *ERASE* the contents of ds:[BSS_RealModeEntry]
149 * but it is not a problem since we are going to place the machine in
150 * a permanent new CPU state.
152 // Since BSS_RealModeEntry contains a ULONG, store in its high word
153 // the code segment and in its low word the code offset.
154 mov ax, word ptr [esp + 16]
156 mov ax, word ptr [esp + 20]
157 mov dword ptr ds:[BSS_RealModeEntry], eax
159 /* Set the function ID and switch to real mode (we don't return) */
160 mov bx, FNID_Relocator16Boot
165 * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
171 /* copy entry point */
175 mov dword ptr ds:[BSS_PxeEntryPoint], eax
179 mov word ptr ds:[BSS_PxeFunction], ax
181 /* convert pointer to data buffer to segment/offset */
185 mov word ptr ds:[BSS_PxeBufferSegment], ax
188 mov word ptr ds:[BSS_PxeBufferOffset], ax
192 /* Set the function ID and call realmode */
193 mov bx, FNID_PxeCallApi
194 call i386CallRealMode
198 mov ax, word ptr [BSS_PxeResult]
203 PUBLIC i386CallRealMode
205 /* Set continue address and switch to real mode */
206 mov dword ptr ds:[ContinueAddress], offset i386CallRealMode_return
208 i386CallRealMode_return:
212 /* Entrypoint for realmode function calls
213 * ContinueAddress must be set to the return point from realmode
214 * bx must be set to the ID of the realmode function to call. */
217 /* Set sane segments */
225 /* Save 32-bit stack pointer */
226 mov dword ptr ds:[stack32], esp
228 /* jmp to 16-bit segment to set the limit correctly */
229 .byte HEX(0ea) // jmp far RMODE_CS:switch_to_real16
230 SwitchToReal16Address:
231 .long 0 // receives address of switch_to_real16
236 /* 16-bit stack pointer */
240 /* 32-bit stack pointer */
244 .align 4 /* force 4-byte alignment */
246 /* NULL Descriptor */
264 /* 16-bit real mode CS */
270 /* 16-bit real mode DS */
276 /* GDT table pointer */
278 .word HEX(27) /* Limit */
279 .long gdt /* Base Address */
281 // See _i386IdtDescriptor
284 .word 255 /* Limit */
285 .long _i386Idt /* Base Address */
287 PUBLIC _FrldrBootDrive
291 PUBLIC _FrldrBootPartition