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