Delete all Trailing spaces in code.
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / setupldr.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #define _NTSYSTEM_
22 #include <freeldr.h>
23 #include <debug.h>
24
25 extern ULONG PageDirectoryStart;
26 extern ULONG PageDirectoryEnd;
27
28 ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
29 char reactos_kernel_cmdline[255]; // Command line passed to kernel
30 LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded for the kernel
31 char reactos_module_strings[64][256]; // Array to hold module names
32 unsigned long reactos_memory_map_descriptor_size;
33 memory_map_t reactos_memory_map[32]; // Memory map
34 char szBootPath[256];
35 char szHalName[256];
36 CHAR SystemRoot[255];
37 extern ULONG_PTR KernelBase, KernelEntryPoint;
38
39 extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
40
41 #define USE_UI
42
43 BOOLEAN
44 NTAPI
45 static FrLdrLoadKernel(IN PCHAR szFileName,
46 IN INT nPos)
47 {
48 PFILE FilePointer;
49 PCHAR szShortName;
50 CHAR szBuffer[256];
51 PVOID LoadBase;
52 PIMAGE_NT_HEADERS NtHeader;
53
54 /* Extract Kernel filename without path */
55 szShortName = strrchr(szFileName, '\\');
56 if (!szShortName)
57 {
58 /* No path, leave it alone */
59 szShortName = szFileName;
60 }
61 else
62 {
63 /* Skip the path */
64 szShortName = szShortName + 1;
65 }
66
67 /* Open the Kernel */
68 FilePointer = FsOpenFile(szFileName);
69 if (!FilePointer)
70 {
71 /* Return failure on the short name */
72 strcpy(szBuffer, szShortName);
73 strcat(szBuffer, " not found.");
74 UiMessageBox(szBuffer);
75 return FALSE;
76 }
77
78 /* Update the status bar with the current file */
79 strcpy(szBuffer, "Reading ");
80 strcat(szBuffer, szShortName);
81 UiDrawStatusText(szBuffer);
82
83 /* Do the actual loading */
84 LoadBase = FrLdrMapImage(FilePointer, szShortName, 1);
85
86 /* Get the NT header, kernel base and kernel entry */
87 NtHeader = RtlImageNtHeader(LoadBase);
88 KernelBase = NtHeader->OptionalHeader.ImageBase;
89 KernelEntryPoint = KernelBase + NtHeader->OptionalHeader.AddressOfEntryPoint;
90 LoaderBlock.KernelBase = KernelBase;
91
92 /* Update Processbar and return success */
93 return TRUE;
94 }
95
96 static BOOLEAN
97 LoadDriver(PCSTR szSourcePath, PCSTR szFileName)
98 {
99 return FrLdrLoadDriver((PCHAR)szFileName, 0);
100 }
101
102
103 static BOOLEAN
104 LoadNlsFile(PCSTR szSourcePath, PCSTR szFileName, PCSTR szModuleName)
105 {
106 CHAR szFullName[256];
107 #ifdef USE_UI
108 CHAR szBuffer[80];
109 #endif
110 PFILE FilePointer;
111 PCSTR szShortName;
112
113 if (szSourcePath[0] != '\\')
114 {
115 strcpy(szFullName, "\\");
116 strcat(szFullName, szSourcePath);
117 }
118 else
119 {
120 strcpy(szFullName, szSourcePath);
121 }
122
123 if (szFullName[strlen(szFullName)] != '\\')
124 {
125 strcat(szFullName, "\\");
126 }
127
128 if (szFileName[0] != '\\')
129 {
130 strcat(szFullName, szFileName);
131 }
132 else
133 {
134 strcat(szFullName, szFileName + 1);
135 }
136
137 szShortName = strrchr(szFileName, '\\');
138 if (szShortName == NULL)
139 szShortName = szFileName;
140 else
141 szShortName = szShortName + 1;
142
143
144 FilePointer = FsOpenFile(szFullName);
145 if (FilePointer == NULL)
146 {
147 printf("Could not find %s\n", szFileName);
148 return(FALSE);
149 }
150
151 /*
152 * Update the status bar with the current file
153 */
154 #ifdef USE_UI
155 sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
156 UiDrawStatusText(szBuffer);
157 #else
158 printf("Reading %s\n", szShortName);
159 #endif
160
161 /* Load the driver */
162 FrLdrLoadModule(FilePointer, szModuleName, NULL);
163
164 return(TRUE);
165 }
166
167 VOID RunLoader(VOID)
168 {
169 ULONG_PTR Base;
170 ULONG Size, i;
171 const char *SourcePath;
172 const char *LoadOptions = "", *DbgLoadOptions = "";
173 const char *sourcePaths[] = {
174 "", /* Only for floppy boot */
175 #if defined(_M_IX86)
176 "\\I386",
177 #elif defined(_M_MPPC)
178 "\\PPC",
179 #elif defined(_M_MRX000)
180 "\\MIPS",
181 #endif
182 "\\reactos",
183 NULL };
184 char szKernelName[256];
185
186 HINF InfHandle;
187 ULONG ErrorLine;
188 INFCONTEXT InfContext;
189
190 /* Setup multiboot information structure */
191 LoaderBlock.CommandLine = reactos_kernel_cmdline;
192 LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
193 LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
194 LoaderBlock.ModsCount = 0;
195 LoaderBlock.ModsAddr = reactos_modules;
196 LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
197 if (LoaderBlock.MmapLength)
198 {
199 ULONG i;
200
201 LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
202 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
203 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
204 {
205 if (BiosMemoryUsable == reactos_memory_map[i].type &&
206 0 == reactos_memory_map[i].base_addr_low)
207 {
208 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
209 if (640 < LoaderBlock.MemLower)
210 {
211 LoaderBlock.MemLower = 640;
212 }
213 }
214 if (BiosMemoryUsable == reactos_memory_map[i].type &&
215 reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
216 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
217 {
218 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
219 }
220 }
221 }
222
223 #ifdef USE_UI
224 SetupUiInitialize();
225 UiDrawStatusText("");
226 #endif
227
228 extern BOOLEAN FrLdrBootType;
229 FrLdrBootType = TRUE;
230
231 /* Initialize registry */
232 RegInitializeRegistry();
233
234 /* Detect hardware */
235 #ifdef USE_UI
236 UiDrawStatusText("Detecting hardware...");
237 #else
238 printf("Detecting hardware...\n\n");
239 #endif
240 MachHwDetect();
241 #ifdef USE_UI
242 UiDrawStatusText("");
243 #endif
244
245 /* set boot device */
246 MachDiskGetBootDevice(&LoaderBlock.BootDevice);
247
248 /* Open boot drive */
249 if (!FsOpenBootVolume())
250 {
251 #ifdef USE_UI
252 UiMessageBox("Failed to open boot drive.");
253 #else
254 printf("Failed to open boot drive.");
255 #endif
256 return;
257 }
258
259 /* Open 'txtsetup.sif' */
260 for (i = MachDiskBootingFromFloppy() ? 0 : 1; ; i++)
261 {
262 SourcePath = sourcePaths[i];
263 if (!SourcePath)
264 {
265 printf("Failed to open 'txtsetup.sif'\n");
266 return;
267 }
268 strcpy(szKernelName, SourcePath);
269 strcat(szKernelName, "\\txtsetup.sif");
270 if (InfOpenFile (&InfHandle, szKernelName, &ErrorLine))
271 break;
272 }
273 if (!*SourcePath)
274 SourcePath = "\\";
275
276 #ifdef DBG
277 /* Get load options */
278 if (InfFindFirstLine (InfHandle,
279 "SetupData",
280 "DbgOsLoadOptions",
281 &InfContext))
282 {
283 if (!InfGetDataField (&InfContext, 1, &DbgLoadOptions))
284 DbgLoadOptions = "";
285 }
286 #endif
287 if (!strlen(DbgLoadOptions) && !InfFindFirstLine (InfHandle,
288 "SetupData",
289 "OsLoadOptions",
290 &InfContext))
291 {
292 printf("Failed to find 'SetupData/OsLoadOptions'\n");
293 return;
294 }
295
296 if (!InfGetDataField (&InfContext,
297 1,
298 &LoadOptions))
299 {
300 printf("Failed to get load options\n");
301 return;
302 }
303 #if 0
304 printf("LoadOptions: '%s'\n", LoadOptions);
305 #endif
306
307 /* Set kernel command line */
308 MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
309 strcat(strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
310 LoadOptions), DbgLoadOptions);
311
312 strcpy(SystemRoot, SourcePath);
313 strcat(SystemRoot, "\\");
314
315 /* Setup the boot path and kernel path */
316 strcpy(szBootPath, SourcePath);
317 strcpy(szKernelName, szBootPath);
318 strcat(szKernelName, "\\ntoskrnl.exe");
319
320 /* Setup the HAL path */
321 strcpy(szHalName, szBootPath);
322 strcat(szHalName, "\\hal.dll");
323
324 /* Load the kernel */
325 if (!FrLdrLoadKernel(szKernelName, 5)) return;
326
327 /* Export the hardware hive */
328 Base = FrLdrCreateModule ("HARDWARE");
329 RegExportBinaryHive (L"\\Registry\\Machine\\HARDWARE", (PVOID)Base, &Size);
330 FrLdrCloseModule (Base, Size);
331
332 #if 0
333 printf("Base: %x\n", Base);
334 printf("Size: %u\n", Size);
335 printf("*** System stopped ***\n");
336 for(;;);
337 #endif
338
339 /* Insert boot disk 2 */
340 if (MachDiskBootingFromFloppy())
341 {
342 #ifdef USE_UI
343 UiMessageBox("Please insert \"ReactOS Boot Disk 2\" and press ENTER");
344 #else
345 printf("\n\n Please insert \"ReactOS Boot Disk 2\" and press ENTER\n");
346 MachConsGetCh();
347 #endif
348
349 /* Open boot drive */
350 if (!FsOpenBootVolume())
351 {
352 #ifdef USE_UI
353 UiMessageBox("Failed to open boot drive.");
354 #else
355 printf("Failed to open boot drive.");
356 #endif
357 return;
358 }
359
360 /* FIXME: check volume label or disk marker file */
361 }
362
363
364 /* Get ANSI codepage file */
365 if (!InfFindFirstLine (InfHandle,
366 "NLS",
367 "AnsiCodepage",
368 &InfContext))
369 {
370 printf("Failed to find 'NLS/AnsiCodepage'\n");
371 return;
372 }
373
374 if (!InfGetDataField (&InfContext,
375 1,
376 &LoadOptions))
377 {
378 printf("Failed to get load options\n");
379 return;
380 }
381
382 /* Load ANSI codepage file */
383 if (!LoadNlsFile(SourcePath, LoadOptions, "ansi.nls"))
384 {
385 #ifdef USE_UI
386 UiMessageBox("Failed to load the ANSI codepage file.");
387 #else
388 printf("Failed to load the ANSI codepage file.");
389 #endif
390 return;
391 }
392
393 /* Get OEM codepage file */
394 if (!InfFindFirstLine (InfHandle,
395 "NLS",
396 "OemCodepage",
397 &InfContext))
398 {
399 printf("Failed to find 'NLS/AnsiCodepage'\n");
400 return;
401 }
402
403 if (!InfGetDataField (&InfContext,
404 1,
405 &LoadOptions))
406 {
407 printf("Failed to get load options\n");
408 return;
409 }
410
411 /* Load OEM codepage file */
412 if (!LoadNlsFile(SourcePath, LoadOptions, "oem.nls"))
413 {
414 #ifdef USE_UI
415 UiMessageBox("Failed to load the OEM codepage file.");
416 #else
417 printf("Failed to load the OEM codepage file.");
418 #endif
419 return;
420 }
421
422 /* Get Unicode Casemap file */
423 if (!InfFindFirstLine (InfHandle,
424 "NLS",
425 "UnicodeCasetable",
426 &InfContext))
427 {
428 printf("Failed to find 'NLS/AnsiCodepage'\n");
429 return;
430 }
431
432 if (!InfGetDataField (&InfContext,
433 1,
434 &LoadOptions))
435 {
436 printf("Failed to get load options\n");
437 return;
438 }
439
440 /* Load Unicode casemap file */
441 if (!LoadNlsFile(SourcePath, LoadOptions, "casemap.nls"))
442 {
443 #ifdef USE_UI
444 UiMessageBox("Failed to load the Unicode casemap file.");
445 #else
446 printf("Failed to load the Unicode casemap file.");
447 #endif
448 return;
449 }
450
451 #if 0
452 /* Load acpi.sys */
453 if (!LoadDriver(SourcePath, "acpi.sys"))
454 return;
455 #endif
456
457 #if 0
458 /* Load isapnp.sys */
459 if (!LoadDriver(SourcePath, "isapnp.sys"))
460 return;
461 #endif
462
463 #if 0
464 /* Load pci.sys */
465 if (!LoadDriver(SourcePath, "pci.sys"))
466 return;
467 #endif
468
469 /* Load scsiport.sys */
470 if (!LoadDriver(SourcePath, "scsiport.sys"))
471 return;
472
473 /* Load atapi.sys (depends on hardware detection) */
474 if (!LoadDriver(SourcePath, "atapi.sys"))
475 return;
476
477 /* Load buslogic.sys (depends on hardware detection) */
478 if (!LoadDriver(SourcePath, "buslogic.sys"))
479 return;
480
481 /* Load class2.sys */
482 if (!LoadDriver(SourcePath, "class2.sys"))
483 return;
484
485 /* Load cdrom.sys */
486 if (!LoadDriver(SourcePath, "cdrom.sys"))
487 return;
488
489 /* Load cdfs.sys */
490 if (!LoadDriver(SourcePath, "cdfs.sys"))
491 return;
492
493 /* Load disk.sys */
494 if (!LoadDriver(SourcePath, "disk.sys"))
495 return;
496
497 /* Load floppy.sys */
498 if (!LoadDriver(SourcePath, "floppy.sys"))
499 return;
500
501 /* Load vfatfs.sys (could be loaded by the setup prog!) */
502 if (!LoadDriver(SourcePath, "vfatfs.sys"))
503 return;
504
505
506 /* Load keyboard driver */
507 if (!LoadDriver(SourcePath, "i8042prt.sys"))
508 return;
509 if (!LoadDriver(SourcePath, "kbdclass.sys"))
510 return;
511
512 /* Load screen driver */
513 if (!LoadDriver(SourcePath, "blue.sys"))
514 return;
515
516 #ifdef USE_UI
517 UiUnInitialize("Booting ReactOS...");
518 #endif
519
520 /* Now boot the kernel */
521 DiskStopFloppyMotor();
522 MachVideoPrepareForReactOS(TRUE);
523 FrLdrStartup(0x2badb002);
524 }
525
526 /* EOF */