[FREELDR] Several changes regarding chainloading and Linux boot.
[reactos.git] / boot / freeldr / freeldr / arch / i386 / entry.S
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
4 *
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.
9 *
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.
14 *
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.
18 */
19
20 #include <asm.inc>
21 #include <arch/pc/x86common.h>
22 #include <arch/pc/pcbios.h>
23
24 EXTERN _BootMain:PROC
25 EXTERN _InitIdt:PROC
26 EXTERN _i386Idt:DWORD
27 //EXTERN _i386idtptr:FWORD
28 EXTERN cmdline:DWORD
29
30 EXTERN _DiskStopFloppyMotor:PROC
31
32 #ifdef _USE_ML
33 EXTERN __bss_start__:DWORD
34 EXTERN __bss_end__:DWORD
35 #endif
36
37 .code32
38
39 PUBLIC _RealEntryPoint
40 _RealEntryPoint:
41
42 /* Setup segment selectors */
43 mov ax, PMODE_DS
44 mov ds, ax
45 mov es, ax
46 mov fs, ax
47 mov gs, ax
48 mov ss, ax
49
50 /* Setup protected mode stack */
51 mov esp, dword ptr ds:[stack32]
52
53 /* Load the IDT */
54 #ifdef _USE_ML
55 lidt fword ptr ds:[i386idtptr]
56 #else
57 lidt i386idtptr
58 #endif
59
60 /* Continue execution */
61 jmp dword ptr ds:[ContinueAddress]
62
63 PUBLIC ContinueAddress
64 ContinueAddress:
65 .long _FrldrStartup
66
67 _FrldrStartup:
68
69 /* Store BootDrive and BootPartition */
70 mov byte ptr ds:[_FrldrBootDrive], dl
71 xor eax, eax
72 mov al, dh
73 mov dword ptr ds:[_FrldrBootPartition], eax
74
75 /* Patch long jump with real mode entry point */
76 mov eax, dword ptr ds:[BSS_RealModeEntry]
77 mov dword ptr ds:[SwitchToReal16Address], eax
78
79 /* Clean out BSS */
80 xor eax, eax
81 mov edi, offset __bss_start__
82 mov ecx, offset __bss_end__ + 3
83 sub ecx, edi
84 shr ecx, 2
85 rep stosd
86
87 /* Initialize the idt */
88 call _InitIdt
89
90 /* Pass the command line to BootMain */
91 mov eax, offset cmdline
92
93 /* GO! */
94 push eax
95 call _BootMain
96
97 /* We should never get here */
98 stop:
99 jmp short stop
100 nop
101 nop
102
103
104 PUBLIC _Reboot
105 _Reboot:
106 /* Stop the floppy drive motor */
107 call _DiskStopFloppyMotor
108
109 /* Set the function ID and switch to real mode (we don't return) */
110 mov bx, FNID_Reboot
111 jmp SwitchToReal
112
113
114 /*
115 * VOID __cdecl Relocator16Boot(
116 * IN REGS* In,
117 * IN USHORT StackSegment,
118 * IN USHORT StackPointer,
119 * IN USHORT CodeSegment,
120 * IN USHORT CodePointer);
121 *
122 * RETURNS: Nothing.
123 *
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.
128 */
129 PUBLIC _Relocator16Boot
130 _Relocator16Boot:
131
132 /* Copy input registers */
133 mov esi, dword ptr [esp + 4]
134 mov edi, BSS_RegisterSet
135 mov ecx, REGS_SIZE / 4
136 rep movsd
137
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]
142 shl eax, 16
143 mov ax, word ptr [esp + 12]
144 mov dword ptr ds:[BSS_CallbackReturn], eax
145
146 /*
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.
151 */
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]
155 shl eax, 16
156 mov ax, word ptr [esp + 20]
157 mov dword ptr ds:[BSS_RealModeEntry], eax
158
159 /* Set the function ID and switch to real mode (we don't return) */
160 mov bx, FNID_Relocator16Boot
161 jmp SwitchToReal
162
163
164 /*
165 * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
166 *
167 * RETURNS:
168 */
169 PUBLIC _PxeCallApi
170 _PxeCallApi:
171 /* copy entry point */
172 mov eax, [esp + 4]
173 shl eax, 16
174 mov ax, [esp + 8]
175 mov dword ptr ds:[BSS_PxeEntryPoint], eax
176
177 /* copy function */
178 mov ax, [esp + 12]
179 mov word ptr ds:[BSS_PxeFunction], ax
180
181 /* convert pointer to data buffer to segment/offset */
182 mov eax, [esp + 16]
183 shr eax, 4
184 and eax, HEX(0f000)
185 mov word ptr ds:[BSS_PxeBufferSegment], ax
186 mov eax, [esp + 16]
187 and eax, HEX(0ffff)
188 mov word ptr ds:[BSS_PxeBufferOffset], ax
189
190 pusha
191
192 /* Set the function ID and call realmode */
193 mov bx, FNID_PxeCallApi
194 call i386CallRealMode
195
196 popa
197
198 mov ax, word ptr [BSS_PxeResult]
199
200 ret
201
202
203 PUBLIC i386CallRealMode
204 i386CallRealMode:
205 /* Set continue address and switch to real mode */
206 mov dword ptr ds:[ContinueAddress], offset i386CallRealMode_return
207 jmp SwitchToReal
208 i386CallRealMode_return:
209 ret
210
211
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. */
215 PUBLIC SwitchToReal
216 SwitchToReal:
217 /* Set sane segments */
218 mov ax, PMODE_DS
219 mov ds, ax
220 mov es, ax
221 mov fs, ax
222 mov gs, ax
223 mov ss, ax
224
225 /* Save 32-bit stack pointer */
226 mov dword ptr ds:[stack32], esp
227
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
232 .word RMODE_CS
233 nop
234
235
236 /* 16-bit stack pointer */
237 stack16:
238 .word STACK16ADDR
239
240 /* 32-bit stack pointer */
241 stack32:
242 .long STACKADDR
243
244 .align 4 /* force 4-byte alignment */
245 gdt:
246 /* NULL Descriptor */
247 .word HEX(0000)
248 .word HEX(0000)
249 .word HEX(0000)
250 .word HEX(0000)
251
252 /* 32-bit flat CS */
253 .word HEX(FFFF)
254 .word HEX(0000)
255 .word HEX(9A00)
256 .word HEX(00CF)
257
258 /* 32-bit flat DS */
259 .word HEX(FFFF)
260 .word HEX(0000)
261 .word HEX(9200)
262 .word HEX(00CF)
263
264 /* 16-bit real mode CS */
265 .word HEX(FFFF)
266 .word HEX(0000)
267 .word HEX(9E00)
268 .word HEX(0000)
269
270 /* 16-bit real mode DS */
271 .word HEX(FFFF)
272 .word HEX(0000)
273 .word HEX(9200)
274 .word HEX(0000)
275
276 /* GDT table pointer */
277 gdtptr:
278 .word HEX(27) /* Limit */
279 .long gdt /* Base Address */
280
281 // See _i386IdtDescriptor
282 PUBLIC i386idtptr
283 i386idtptr:
284 .word 255 /* Limit */
285 .long _i386Idt /* Base Address */
286
287 PUBLIC _FrldrBootDrive
288 _FrldrBootDrive:
289 .byte 0
290
291 PUBLIC _FrldrBootPartition
292 _FrldrBootPartition:
293 .long 0
294
295 END