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