Switch i287 fpu, if present, into protected mode (ignored on i387) and
[reactos.git] / reactos / ntoskrnl / ke / main.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: main.c,v 1.138 2002/09/15 10:45:02 guido Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/main.c
23 * PURPOSE: Initalizes the kernel
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * UPDATE HISTORY:
26 * 28/05/98: Created
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include <ddk/ntddk.h>
32 #include <internal/ntoskrnl.h>
33 #include <reactos/resource.h>
34 #include <internal/mm.h>
35 #include <internal/module.h>
36 #include <internal/ldr.h>
37 #include <internal/ex.h>
38 #include <internal/ps.h>
39 #include <internal/ke.h>
40 #include <internal/io.h>
41 #include <internal/po.h>
42 #include <internal/cc.h>
43 #include <internal/se.h>
44 #include <internal/v86m.h>
45 #include <internal/kd.h>
46 #include <internal/trap.h>
47 #include "../dbg/kdb.h"
48 #include <internal/registry.h>
49 #include <reactos/bugcodes.h>
50
51 #ifdef HALDBG
52 #include <internal/ntosdbg.h>
53 #else
54 #define ps(args...)
55 #endif
56
57 #define NDEBUG
58 #include <internal/debug.h>
59
60 /* GLOBALS *******************************************************************/
61
62 ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
63 ULONG EXPORTED NtGlobalFlag = 0;
64 CHAR EXPORTED KeNumberProcessors;
65 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
66 ULONG EXPORTED KeDcacheFlushCount = 0;
67 ULONG EXPORTED KeIcacheFlushCount = 0;
68 static LOADER_MODULE KeLoaderModules[64];
69 static UCHAR KeLoaderModuleStrings[64][256];
70 static UCHAR KeLoaderCommandLine[256];
71 static ADDRESS_RANGE KeMemoryMap[64];
72 static ULONG KeMemoryMapRangeCount;
73 static ULONG FirstKrnlPhysAddr;
74 static ULONG LastKrnlPhysAddr;
75 static ULONG LastKernelAddress;
76 volatile BOOLEAN Initialized = FALSE;
77
78 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
79
80
81 /* FUNCTIONS ****************************************************************/
82
83 static BOOLEAN
84 RtlpCheckFileNameExtension(PCHAR FileName,
85 PCHAR Extension)
86 {
87 PCHAR Ext;
88
89 Ext = strrchr(FileName, '.');
90 if ((Extension == NULL) || (*Extension == 0))
91 {
92 if (Ext == NULL)
93 return TRUE;
94 else
95 return FALSE;
96 }
97 if (*Extension != '.')
98 Ext++;
99
100 if (_stricmp(Ext, Extension) == 0)
101 return TRUE;
102 else
103 return FALSE;
104 }
105
106
107 static VOID
108 InitSystemSharedUserPage (PCSZ ParameterLine)
109 {
110 UNICODE_STRING ArcDeviceName;
111 UNICODE_STRING ArcName;
112 UNICODE_STRING BootPath;
113 UNICODE_STRING DriveDeviceName;
114 UNICODE_STRING DriveName;
115 WCHAR DriveNameBuffer[20];
116 PCHAR ParamBuffer;
117 PWCHAR ArcNameBuffer;
118 PCHAR p;
119 NTSTATUS Status;
120 ULONG Length;
121 OBJECT_ATTRIBUTES ObjectAttributes;
122 HANDLE Handle;
123 ULONG i;
124 BOOLEAN BootDriveFound;
125
126 /*
127 * NOTE:
128 * The shared user page has been zeroed-out right after creation.
129 * There is NO need to do this again.
130 */
131
132 SharedUserData->NtProductType = NtProductWinNt;
133
134 BootDriveFound = FALSE;
135
136 /*
137 * Retrieve the current dos system path
138 * (e.g.: C:\reactos) from the given arc path
139 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
140 * Format: "<arc_name>\<path> [options...]"
141 */
142
143 /* create local parameter line copy */
144 ParamBuffer = ExAllocatePool (PagedPool, 256);
145 strcpy (ParamBuffer, (char *)ParameterLine);
146 DPRINT("%s\n", ParamBuffer);
147
148 /* cut options off */
149 p = strchr (ParamBuffer, ' ');
150 if (p)
151 {
152 *p = 0;
153 }
154 DPRINT("%s\n", ParamBuffer);
155
156 /* extract path */
157 p = strchr (ParamBuffer, '\\');
158 if (p)
159 {
160 DPRINT("Boot path: %s\n", p);
161 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
162 *p = 0;
163 }
164 else
165 {
166 DPRINT("Boot path: %s\n", "\\");
167 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
168 }
169 DPRINT("Arc name: %s\n", ParamBuffer);
170
171 /* Only arc name left - build full arc name */
172 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
173 swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
174 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
175 DPRINT("Arc name: %wZ\n", &ArcName);
176
177 /* free ParamBuffer */
178 ExFreePool (ParamBuffer);
179
180 /* allocate arc device name string */
181 ArcDeviceName.Length = 0;
182 ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
183 ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
184
185 InitializeObjectAttributes (&ObjectAttributes,
186 &ArcName,
187 OBJ_OPENLINK,
188 NULL,
189 NULL);
190
191 Status = NtOpenSymbolicLinkObject (&Handle,
192 SYMBOLIC_LINK_ALL_ACCESS,
193 &ObjectAttributes);
194 RtlFreeUnicodeString (&ArcName);
195 if (!NT_SUCCESS(Status))
196 {
197 RtlFreeUnicodeString (&BootPath);
198 RtlFreeUnicodeString (&ArcDeviceName);
199 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
200 Status);
201
202 KeBugCheck (0x0);
203 }
204
205 Status = NtQuerySymbolicLinkObject (Handle,
206 &ArcDeviceName,
207 &Length);
208 NtClose (Handle);
209 if (!NT_SUCCESS(Status))
210 {
211 RtlFreeUnicodeString (&BootPath);
212 RtlFreeUnicodeString (&ArcDeviceName);
213 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
214 Status);
215
216 KeBugCheck (0x0);
217 }
218 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
219
220
221 /* allocate device name string */
222 DriveDeviceName.Length = 0;
223 DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
224 DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
225
226 for (i = 0; i < 26; i++)
227 {
228 swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
229 RtlInitUnicodeString (&DriveName,
230 DriveNameBuffer);
231
232 InitializeObjectAttributes (&ObjectAttributes,
233 &DriveName,
234 OBJ_OPENLINK,
235 NULL,
236 NULL);
237
238 Status = NtOpenSymbolicLinkObject (&Handle,
239 SYMBOLIC_LINK_ALL_ACCESS,
240 &ObjectAttributes);
241 if (!NT_SUCCESS(Status))
242 {
243 DPRINT("Failed to open link %wZ\n",
244 &DriveName);
245 continue;
246 }
247
248 Status = NtQuerySymbolicLinkObject (Handle,
249 &DriveDeviceName,
250 &Length);
251 if (!NT_SUCCESS(Status))
252 {
253 DPRINT("Failed query open link %wZ\n",
254 &DriveName);
255 continue;
256 }
257 DPRINT("Opened link: %wZ ==> %wZ\n",
258 &DriveName, &DriveDeviceName);
259
260 if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
261 {
262 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
263 swprintf(SharedUserData->NtSystemRoot,
264 L"%C:%wZ", 'A' + i, &BootPath);
265
266 BootDriveFound = TRUE;
267 }
268
269 NtClose (Handle);
270 }
271
272 RtlFreeUnicodeString (&BootPath);
273 RtlFreeUnicodeString (&DriveDeviceName);
274 RtlFreeUnicodeString (&ArcDeviceName);
275
276 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
277
278 if (BootDriveFound == FALSE)
279 {
280 DbgPrint("No system drive found!\n");
281 KeBugCheck (0x0);
282 }
283 }
284
285 VOID
286 ExpInitializeExecutive(VOID)
287 {
288 ULONG BootDriverCount;
289 ULONG i;
290 ULONG start;
291 ULONG length;
292 PCHAR name;
293 CHAR str[50];
294 NTSTATUS Status;
295
296 /*
297 * Fail at runtime if someone has changed various structures without
298 * updating the offsets used for the assembler code.
299 */
300 assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
301 assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
302 assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
303 assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
304 assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
305 assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
306 assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
307 assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
308 KPROCESS_DIRECTORY_TABLE_BASE);
309 assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
310 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
311 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
312
313 assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
314 assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
315 assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
316
317 LdrInit1();
318
319 KeLowerIrql(DISPATCH_LEVEL);
320
321 NtEarlyInitVdm();
322
323 MmInit1(FirstKrnlPhysAddr,
324 LastKrnlPhysAddr,
325 LastKernelAddress,
326 (PADDRESS_RANGE)&KeMemoryMap,
327 KeMemoryMapRangeCount);
328
329 /* create default nls tables */
330 RtlpInitNlsTables();
331
332 /*
333 * Initialize the kernel debugger
334 */
335 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
336
337 MmInit2();
338 KeInit2();
339
340 KeLowerIrql(PASSIVE_LEVEL);
341
342 if (!SeInit1())
343 KeBugCheck(SECURITY_INITIALIZATION_FAILED);
344
345 ObInit();
346
347 if (!SeInit2())
348 KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
349
350 PiInitProcessManager();
351
352 KdInit1();
353
354 if (KdPollBreakIn ())
355 {
356 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
357 }
358
359 /*
360 * Display version number and copyright/warranty message
361 */
362 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
363 KERNEL_VERSION_BUILD_STR")\n");
364 HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
365 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
366 "Public License, and you\n");
367 HalDisplayString("are welcome to change it and/or distribute copies of it "
368 "under certain\n");
369 HalDisplayString("conditions. There is absolutely no warranty for "
370 "ReactOS.\n\n");
371
372 /* Initialize all processors */
373 KeNumberProcessors = 0;
374
375 while (!HalAllProcessorsStarted())
376 {
377 PVOID ProcessorStack;
378
379 if (KeNumberProcessors != 0)
380 {
381 KePrepareForApplicationProcessorInit(KeNumberProcessors);
382 PsPrepareForApplicationProcessorInit(KeNumberProcessors);
383 }
384 /* Allocate a stack for use when booting the processor */
385 /* FIXME: The nonpaged memory for the stack is not released after use */
386 ProcessorStack =
387 ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
388 Ki386InitialStackArray[((int)KeNumberProcessors)] =
389 (PVOID)(ProcessorStack - MM_STACK_SIZE);
390 HalInitializeProcessor(KeNumberProcessors, ProcessorStack);
391 KeNumberProcessors++;
392 }
393
394 if (KeNumberProcessors > 1)
395 {
396 sprintf(str,
397 "Found %d system processors. [%lu MB Memory]\n",
398 KeNumberProcessors,
399 (KeLoaderBlock.MemHigher + 1088)/ 1024);
400 }
401 else
402 {
403 sprintf(str,
404 "Found 1 system processor. [%lu MB Memory]\n",
405 (KeLoaderBlock.MemHigher + 1088)/ 1024);
406 }
407 HalDisplayString(str);
408
409 /*
410 * Initialize various critical subsystems
411 */
412 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
413
414 ExInit();
415 IoInit();
416 PoInit();
417 LdrInitModuleManagement();
418 CmInitializeRegistry();
419 NtInit();
420 MmInit3();
421 CcInit();
422 KdInit2();
423
424 /* Report all resources used by hal */
425 HalReportResourceUsage();
426
427 /*
428 * Initalize services loaded at boot time
429 */
430 DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
431 for (i=0; i < KeLoaderBlock.ModsCount; i++)
432 {
433 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
434 KeLoaderModules[i].String,
435 KeLoaderModules[i].ModStart,
436 KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
437 }
438
439 /* Pass 1: load nls files */
440 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
441 {
442 name = (PCHAR)KeLoaderModules[i].String;
443 if (RtlpCheckFileNameExtension(name, ".nls"))
444 {
445 ULONG Mod2Start = 0;
446 ULONG Mod2End = 0;
447 ULONG Mod3Start = 0;
448 ULONG Mod3End = 0;
449
450 name = (PCHAR)KeLoaderModules[i+1].String;
451 if (RtlpCheckFileNameExtension(name, ".nls"))
452 {
453 Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
454 Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
455
456 name = (PCHAR)KeLoaderModules[i+2].String;
457 if (RtlpCheckFileNameExtension(name, ".nls"))
458 {
459 Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
460 Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
461 }
462 }
463
464 /* Initialize nls sections */
465 RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
466 (ULONG)KeLoaderModules[i].ModEnd,
467 Mod2Start,
468 Mod2End,
469 Mod3Start,
470 Mod3End);
471 break;
472 }
473 }
474
475 /* Pass 2: load registry chunks passed in */
476 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
477 {
478 start = KeLoaderModules[i].ModStart;
479 length = KeLoaderModules[i].ModEnd - start;
480 name = (PCHAR)KeLoaderModules[i].String;
481 if (RtlpCheckFileNameExtension(name, "") ||
482 RtlpCheckFileNameExtension(name, ".hiv"))
483 {
484 CPRINT("Process registry chunk at %08lx\n", start);
485 CmImportHive((PCHAR)start, length);
486 }
487 }
488
489 /* Initialize volatile registry settings */
490 CmInit2((PCHAR)KeLoaderBlock.CommandLine);
491
492 /*
493 * Enter the kernel debugger before starting up the boot drivers
494 */
495 #ifdef KDBG
496 KdbEnter();
497 #endif /* KDBG */
498
499 IoCreateDriverList();
500
501 /* Pass 3: process boot loaded drivers */
502 BootDriverCount = 0;
503 for (i=1; i < KeLoaderBlock.ModsCount; i++)
504 {
505 start = KeLoaderModules[i].ModStart;
506 length = KeLoaderModules[i].ModEnd - start;
507 name = (PCHAR)KeLoaderModules[i].String;
508 if (RtlpCheckFileNameExtension(name, ".sys") ||
509 RtlpCheckFileNameExtension(name, ".sym"))
510 {
511 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
512 name, start, length);
513 LdrInitializeBootStartDriver((PVOID)start, name, length);
514 }
515 if (RtlpCheckFileNameExtension(name, ".sys"))
516 BootDriverCount++;
517 }
518
519 if (BootDriverCount == 0)
520 {
521 DbgPrint("No boot drivers available.\n");
522 KeBugCheck(0);
523 }
524
525 /* Create ARC names for boot devices */
526 IoCreateArcNames();
527
528 /* Create the SystemRoot symbolic link */
529 CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
530 Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
531 if (!NT_SUCCESS(Status))
532 KeBugCheck(INACCESSIBLE_BOOT_DEVICE);
533
534 #ifdef DBGPRINT_FILE_LOG
535 /* On the assumption that we can now access disks start up the debug
536 logger thread */
537 DebugLogInit2();
538 #endif /* DBGPRINT_FILE_LOG */
539
540
541 PiInitDefaultLocale();
542
543 /*
544 * Start the motherboard enumerator (the HAL)
545 */
546 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
547 #if 0
548 /*
549 * Load boot start drivers
550 */
551 IopLoadBootStartDrivers();
552 #else
553 /*
554 * Load Auto configured drivers
555 */
556 LdrLoadAutoConfigDrivers();
557 #endif
558
559 IoDestroyDriverList();
560
561 /*
562 * Assign drive letters
563 */
564 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
565 NULL,
566 NULL,
567 NULL);
568
569 /*
570 * Initialize shared user page:
571 * - set dos system path, dos device map, etc.
572 */
573 InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
574
575 /*
576 * Launch initial process
577 */
578 LdrLoadInitialProcess();
579
580 PsTerminateSystemThread(STATUS_SUCCESS);
581 }
582
583
584 VOID
585 KiSystemStartup(BOOLEAN BootProcessor)
586 {
587 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
588
589 if (BootProcessor)
590 {
591 /* Never returns */
592 ExpInitializeExecutive();
593 KeBugCheck(0);
594 }
595 /* Do application processor initialization */
596 KeApplicationProcessorInit();
597 PsApplicationProcessorInit();
598 KeLowerIrql(PASSIVE_LEVEL);
599 PsIdleThreadMain(NULL);
600 KeBugCheck(0);
601 for(;;);
602 }
603
604 VOID
605 _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
606 /*
607 * FUNCTION: Called by the boot loader to start the kernel
608 * ARGUMENTS:
609 * LoaderBlock = Pointer to boot parameters initialized by the boot
610 * loader
611 * NOTE: The boot parameters are stored in low memory which will become
612 * invalid after the memory managment is initialized so we make a local copy.
613 */
614 {
615 ULONG i;
616 ULONG size;
617 ULONG last_kernel_address;
618 extern ULONG _bss_end__;
619 ULONG HalBase;
620 ULONG DriverBase;
621 ULONG DriverSize;
622
623 /* Low level architecture specific initialization */
624 KeInit1();
625
626 /*
627 * Copy the parameters to a local buffer because lowmem will go away
628 */
629 memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
630 memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
631 sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
632 KeLoaderBlock.ModsCount++;
633 KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
634
635 /*
636 * Convert a path specification in the grub format to one understood by the
637 * rest of the kernel.
638 */
639 if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
640 {
641 ULONG DiskNumber = 0, PartNumber = 0;
642 PCH p;
643 CHAR Temp[256];
644 PCH options;
645 PCH s1;
646
647 if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
648 ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
649 {
650 DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0';
651 PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0';
652 }
653 strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]);
654 if ((options = strchr(Temp, ' ')) != NULL)
655 {
656 *options = 0;
657 options++;
658 }
659 else
660 {
661 options = "";
662 }
663 if ((s1 = strrchr(Temp, '/')) != NULL)
664 {
665 *s1 = 0;
666 if ((s1 = strrchr(Temp, '/')) != NULL)
667 {
668 *s1 = 0;
669 }
670 }
671 sprintf(KeLoaderCommandLine,
672 "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s",
673 DiskNumber, PartNumber + 1, Temp, options);
674
675 p = KeLoaderCommandLine;
676 while (*p != 0 && *p != ' ')
677 {
678 if ((*p) == '/')
679 {
680 (*p) = '\\';
681 }
682 p++;
683 }
684 DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
685 }
686 else
687 {
688 strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine);
689 }
690 KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
691
692 strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
693 KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
694 KeLoaderModules[0].ModStart = 0xC0000000;
695 KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
696 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
697 {
698 strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
699 KeLoaderModules[i].ModStart -= 0x200000;
700 KeLoaderModules[i].ModStart += 0xc0000000;
701 KeLoaderModules[i].ModEnd -= 0x200000;
702 KeLoaderModules[i].ModEnd += 0xc0000000;
703 KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
704 }
705
706 #ifdef HAL_DBG
707 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
708 #endif
709
710 HalBase = KeLoaderModules[1].ModStart;
711 DriverBase =
712 PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
713
714 /*
715 * Process hal.dll
716 */
717 LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
718
719 LdrHalBase = (ULONG_PTR)DriverBase;
720 last_kernel_address = DriverBase + DriverSize;
721
722 /*
723 * Process ntoskrnl.exe
724 */
725 LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
726
727 FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
728 LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
729 LastKernelAddress = last_kernel_address;
730
731 #ifndef ACPI
732 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
733 KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
734 #endif
735
736 KeMemoryMapRangeCount = 0;
737 if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
738 {
739 /* We have a memory map from the nice BIOS */
740 size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
741 i = 0;
742 while (i < KeLoaderBlock.MmapLength)
743 {
744 memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
745 (PVOID)(KeLoaderBlock.MmapAddr + i),
746 sizeof(ADDRESS_RANGE));
747 KeMemoryMapRangeCount++;
748 i += size;
749 }
750 }
751
752 KiSystemStartup(1);
753 }
754
755 /* EOF */
756