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