Fixed some bugs.
[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.129 2002/07/17 21:04:55 dwelch 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 static LOADER_MODULE KeLoaderModules[64];
67 static UCHAR KeLoaderModuleStrings[64][256];
68 static UCHAR KeLoaderCommandLine[256];
69 static ADDRESS_RANGE KeMemoryMap[64];
70 static ULONG KeMemoryMapRangeCount;
71 static ULONG FirstKrnlPhysAddr;
72 static ULONG LastKrnlPhysAddr;
73 static ULONG LastKernelAddress;
74 volatile BOOLEAN Initialized = FALSE;
75
76 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
77
78
79 /* FUNCTIONS ****************************************************************/
80
81 static BOOLEAN
82 RtlpCheckFileNameExtension(PCHAR FileName,
83 PCHAR Extension)
84 {
85 PCHAR Ext;
86
87 Ext = strrchr(FileName, '.');
88 if ((Extension == NULL) || (*Extension == 0))
89 {
90 if (Ext == NULL)
91 return TRUE;
92 else
93 return FALSE;
94 }
95 if (*Extension != '.')
96 Ext++;
97
98 if (_stricmp(Ext, Extension) == 0)
99 return TRUE;
100 else
101 return FALSE;
102 }
103
104
105 static VOID
106 InitSystemSharedUserPage (PCSZ ParameterLine)
107 {
108 UNICODE_STRING ArcDeviceName;
109 UNICODE_STRING ArcName;
110 UNICODE_STRING BootPath;
111 UNICODE_STRING DriveDeviceName;
112 UNICODE_STRING DriveName;
113 WCHAR DriveNameBuffer[20];
114 PCHAR ParamBuffer;
115 PWCHAR ArcNameBuffer;
116 PCHAR p;
117 NTSTATUS Status;
118 ULONG Length;
119 OBJECT_ATTRIBUTES ObjectAttributes;
120 HANDLE Handle;
121 ULONG i;
122 BOOLEAN BootDriveFound;
123
124 /*
125 * NOTE:
126 * The shared user page has been zeroed-out right after creation.
127 * There is NO need to do this again.
128 */
129
130 SharedUserData->NtProductType = NtProductWinNt;
131
132 BootDriveFound = FALSE;
133
134 /*
135 * Retrieve the current dos system path
136 * (e.g.: C:\reactos) from the given arc path
137 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
138 * Format: "<arc_name>\<path> [options...]"
139 */
140
141 /* create local parameter line copy */
142 ParamBuffer = ExAllocatePool (PagedPool, 256);
143 strcpy (ParamBuffer, (char *)ParameterLine);
144 DPRINT("%s\n", ParamBuffer);
145
146 /* cut options off */
147 p = strchr (ParamBuffer, ' ');
148 if (p)
149 {
150 *p = 0;
151 }
152 DPRINT("%s\n", ParamBuffer);
153
154 /* extract path */
155 p = strchr (ParamBuffer, '\\');
156 if (p)
157 {
158 DPRINT("Boot path: %s\n", p);
159 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
160 *p = 0;
161 }
162 else
163 {
164 DPRINT("Boot path: %s\n", "\\");
165 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
166 }
167 DPRINT("Arc name: %s\n", ParamBuffer);
168
169 /* Only arc name left - build full arc name */
170 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
171 swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
172 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
173 DPRINT("Arc name: %wZ\n", &ArcName);
174
175 /* free ParamBuffer */
176 ExFreePool (ParamBuffer);
177
178 /* allocate arc device name string */
179 ArcDeviceName.Length = 0;
180 ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
181 ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
182
183 InitializeObjectAttributes (&ObjectAttributes,
184 &ArcName,
185 OBJ_OPENLINK,
186 NULL,
187 NULL);
188
189 Status = NtOpenSymbolicLinkObject (&Handle,
190 SYMBOLIC_LINK_ALL_ACCESS,
191 &ObjectAttributes);
192 RtlFreeUnicodeString (&ArcName);
193 if (!NT_SUCCESS(Status))
194 {
195 RtlFreeUnicodeString (&BootPath);
196 RtlFreeUnicodeString (&ArcDeviceName);
197 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
198 Status);
199
200 KeBugCheck (0x0);
201 }
202
203 Status = NtQuerySymbolicLinkObject (Handle,
204 &ArcDeviceName,
205 &Length);
206 NtClose (Handle);
207 if (!NT_SUCCESS(Status))
208 {
209 RtlFreeUnicodeString (&BootPath);
210 RtlFreeUnicodeString (&ArcDeviceName);
211 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
212 Status);
213
214 KeBugCheck (0x0);
215 }
216 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
217
218
219 /* allocate device name string */
220 DriveDeviceName.Length = 0;
221 DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
222 DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
223
224 for (i = 0; i < 26; i++)
225 {
226 swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
227 RtlInitUnicodeString (&DriveName,
228 DriveNameBuffer);
229
230 InitializeObjectAttributes (&ObjectAttributes,
231 &DriveName,
232 OBJ_OPENLINK,
233 NULL,
234 NULL);
235
236 Status = NtOpenSymbolicLinkObject (&Handle,
237 SYMBOLIC_LINK_ALL_ACCESS,
238 &ObjectAttributes);
239 if (!NT_SUCCESS(Status))
240 {
241 DPRINT("Failed to open link %wZ\n",
242 &DriveName);
243 continue;
244 }
245
246 Status = NtQuerySymbolicLinkObject (Handle,
247 &DriveDeviceName,
248 &Length);
249 if (!NT_SUCCESS(Status))
250 {
251 DPRINT("Failed query open link %wZ\n",
252 &DriveName);
253 continue;
254 }
255 DPRINT("Opened link: %wZ ==> %wZ\n",
256 &DriveName, &DriveDeviceName);
257
258 if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
259 {
260 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
261 swprintf(SharedUserData->NtSystemRoot,
262 L"%C:%wZ", 'A' + i, &BootPath);
263
264 BootDriveFound = TRUE;
265 }
266
267 NtClose (Handle);
268 }
269
270 RtlFreeUnicodeString (&BootPath);
271 RtlFreeUnicodeString (&DriveDeviceName);
272 RtlFreeUnicodeString (&ArcDeviceName);
273
274 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
275
276 if (BootDriveFound == FALSE)
277 {
278 DbgPrint("No system drive found!\n");
279 KeBugCheck (0x0);
280 }
281 }
282
283 #ifndef NDEBUG
284
285 VOID DumpBIOSMemoryMap(VOID)
286 {
287 ULONG i;
288
289 DbgPrint("Dumping BIOS memory map:\n");
290 DbgPrint("Memory map base: %d\n", KeLoaderBlock.MmapAddr);
291 DbgPrint("Memory map size: %d\n", KeLoaderBlock.MmapLength);
292 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount);
293 for (i = 0; i < KeMemoryMapRangeCount; i++)
294 {
295 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
296 KeMemoryMap[i].BaseAddrLow,
297 KeMemoryMap[i].LengthLow,
298 KeMemoryMap[i].Type);
299 }
300 for (;;);
301 }
302
303 #endif /* !NDEBUG */
304
305 #if 1
306 // SEH Test
307
308 static ULONG Scratch;
309
310 EXCEPTION_DISPOSITION
311 ExpUnhandledException1(
312 PEXCEPTION_RECORD ExceptionRecord,
313 PEXCEPTION_REGISTRATION ExceptionRegistration,
314 PCONTEXT Context,
315 PVOID DispatcherContext)
316 {
317 DbgPrint("ExpUnhandledException1() called\n");
318 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
319 DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
320 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
321 DbgPrint("Context 0x%X\n", Context);
322 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
323
324 Context->Eax = (ULONG)&Scratch;
325
326 return ExceptionContinueExecution;
327 }
328
329
330 EXCEPTION_DISPOSITION
331 ExpUnhandledException2(
332 PEXCEPTION_RECORD ExceptionRecord,
333 PEXCEPTION_REGISTRATION ExceptionRegistration,
334 PCONTEXT Context,
335 PVOID DispatcherContext)
336 {
337 DbgPrint("ExpUnhandledException2() called\n");
338 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
339 DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
340 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
341 DbgPrint("Context 0x%X\n", Context);
342 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
343
344 #if 1
345 Context->Eax = (ULONG)&Scratch;
346
347 return ExceptionContinueExecution;
348
349 #else
350
351 return ExceptionContinueSearch;
352
353 #endif
354 }
355
356
357 #if 1
358 // Put in mingw headers
359 extern VOID
360 CDECL
361 _local_unwind2(
362 PEXCEPTION_REGISTRATION RegistrationFrame,
363 DWORD TryLevel);
364
365 extern VOID
366 CDECL
367 _global_unwind2(
368 PVOID RegistrationFrame);
369
370 extern EXCEPTION_DISPOSITION
371 CDECL
372 _except_handler2(
373 PEXCEPTION_RECORD ExceptionRecord,
374 PEXCEPTION_REGISTRATION RegistrationFrame,
375 PCONTEXT Context,
376 PVOID DispatcherContext);
377
378 extern EXCEPTION_DISPOSITION
379 CDECL
380 _except_handler3(
381 PEXCEPTION_RECORD ExceptionRecord,
382 PEXCEPTION_REGISTRATION RegistrationFrame,
383 PCONTEXT Context,
384 PVOID DispatcherContext);
385
386 #endif
387
388 PRTL_EXCEPTION_REGISTRATION
389 CurrentRER(VOID)
390 {
391 ULONG Value;
392
393 __asm__("movl %%ebp, %0\n\t" : "=a" (Value));
394
395 return((PRTL_EXCEPTION_REGISTRATION)Value) - 1;
396 }
397
398 PULONG x;
399 PRTL_EXCEPTION_REGISTRATION TestER;
400 SCOPETABLE_ENTRY ScopeTable;
401 PEXCEPTION_REGISTRATION OSPtr;
402
403
404 DWORD CDECL SEHFilterRoutine(VOID)
405 {
406 DbgPrint("Within filter routine.\n");
407 return EXCEPTION_EXECUTE_HANDLER;
408 //return EXCEPTION_CONTINUE_EXECUTION;
409 }
410
411 VOID CDECL SEHHandlerRoutine(VOID)
412 {
413 DbgPrint("Within exception handler.\n");
414 DbgPrint("System halted.\n");
415 for (;;);
416 }
417
418
419 VOID SEHTest()
420 {
421 RTL_EXCEPTION_REGISTRATION ER;
422 LPEXCEPTION_POINTERS ExceptionPointers;
423 PVOID StandardESPInFrame;
424
425 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame));
426 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame);
427
428 ExceptionPointers = NULL;
429
430 ER.OS.handler = _except_handler3;
431 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER.OS.prev));
432 DbgPrint("ER.OS.prev: 0x%X\n", ER.OS.prev);
433
434 ER.ScopeTable = &ScopeTable;
435 DbgPrint("ER.ScopeTable: 0x%X\n", ER.ScopeTable);
436 ER.TryLevel = -1;
437 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER.Ebp));
438 DbgPrint("ER.Ebp: 0x%X\n", ER.Ebp);
439
440 ScopeTable.PreviousTryLevel = -1;
441 ScopeTable.FilterRoutine = SEHFilterRoutine;
442 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable.FilterRoutine);
443 ScopeTable.HandlerRoutine = SEHHandlerRoutine;
444 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable.HandlerRoutine);
445
446
447 OSPtr = &ER.OS;
448 DbgPrint("OSPtr: 0x%X\n", OSPtr);
449
450 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr));
451
452 /*__try1(__except_handler3)*/ if(1) {
453 ER.TryLevel = 0; // Entered first try... block
454
455 DbgPrint("Within guarded section.\n");
456 x = (PULONG)0xf2000000; *x = 0;
457 DbgPrint("After exception.\n");
458 } /* __except1 */ if(0) {
459 }
460
461 DbgPrint("After exception2.\n");
462
463 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER.OS.prev));
464 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
465
466 DbgPrint("Exiting.\n");
467 }
468
469 #endif
470
471 VOID
472 ExpInitializeExecutive(VOID)
473 {
474 ULONG BootDriverCount;
475 ULONG i;
476 ULONG start;
477 ULONG length;
478 PCHAR name;
479 CHAR str[50];
480 NTSTATUS Status;
481
482 /*
483 * Fail at runtime if someone has changed various structures without
484 * updating the offsets used for the assembler code.
485 */
486 assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
487 assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
488 assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
489 assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
490 assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
491 assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
492 assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
493 assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
494 KPROCESS_DIRECTORY_TABLE_BASE);
495 assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
496 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
497 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
498
499 assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
500 assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
501 assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
502
503 LdrInit1();
504
505 KeLowerIrql(DISPATCH_LEVEL);
506
507 NtEarlyInitVdm();
508
509 MmInit1(FirstKrnlPhysAddr,
510 LastKrnlPhysAddr,
511 LastKernelAddress,
512 (PADDRESS_RANGE)&KeMemoryMap,
513 KeMemoryMapRangeCount);
514
515 /* create default nls tables */
516 RtlpInitNlsTables();
517
518 /*
519 * Initialize the kernel debugger
520 */
521 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
522
523 MmInit2();
524 KeInit2();
525
526 KeLowerIrql(PASSIVE_LEVEL);
527
528 if (!SeInit1())
529 KeBugCheck(SECURITY_INITIALIZATION_FAILED);
530
531 ObInit();
532
533 if (!SeInit2())
534 KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
535
536 PiInitProcessManager();
537
538 KdInit1();
539
540 if (KdPollBreakIn ())
541 {
542 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
543 }
544
545 /*
546 * Display version number and copyright/warranty message
547 */
548 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
549 KERNEL_VERSION_BUILD_STR")\n");
550 HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
551 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
552 "Public License, and you\n");
553 HalDisplayString("are welcome to change it and/or distribute copies of it "
554 "under certain\n");
555 HalDisplayString("conditions. There is absolutely no warranty for "
556 "ReactOS.\n\n");
557
558 /* Initialize all processors */
559 KeNumberProcessors = 0;
560
561 while (!HalAllProcessorsStarted())
562 {
563 PVOID ProcessorStack;
564
565 if (KeNumberProcessors != 0)
566 {
567 KePrepareForApplicationProcessorInit(KeNumberProcessors);
568 PsPrepareForApplicationProcessorInit(KeNumberProcessors);
569 }
570 /* Allocate a stack for use when booting the processor */
571 /* FIXME: The nonpaged memory for the stack is not released after use */
572 ProcessorStack =
573 ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
574 Ki386InitialStackArray[((int)KeNumberProcessors)] =
575 (PVOID)(ProcessorStack - MM_STACK_SIZE);
576 HalInitializeProcessor(KeNumberProcessors, ProcessorStack);
577 KeNumberProcessors++;
578 }
579
580 if (KeNumberProcessors > 1)
581 {
582 sprintf(str,
583 "Found %d system processors. [%lu MB Memory]\n",
584 KeNumberProcessors,
585 (KeLoaderBlock.MemHigher + 1088)/ 1024);
586 }
587 else
588 {
589 sprintf(str,
590 "Found 1 system processor. [%lu MB Memory]\n",
591 (KeLoaderBlock.MemHigher + 1088)/ 1024);
592 }
593 HalDisplayString(str);
594
595 /*
596 * Initialize various critical subsystems
597 */
598 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
599
600 ExInit();
601 IoInit();
602 PoInit();
603 LdrInitModuleManagement();
604 CmInitializeRegistry();
605 NtInit();
606 MmInit3();
607 CcInit();
608 KdInit2();
609
610 /* Report all resources used by hal */
611 HalReportResourceUsage();
612
613 /*
614 * Initalize services loaded at boot time
615 */
616 *(PULONG)0 = 0;
617 DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
618 for (i=0; i < KeLoaderBlock.ModsCount; i++)
619 {
620 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
621 KeLoaderModules[i].String,
622 KeLoaderModules[i].ModStart,
623 KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
624 }
625
626 /* Pass 1: load nls files */
627 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
628 {
629 name = (PCHAR)KeLoaderModules[i].String;
630 if (RtlpCheckFileNameExtension(name, ".nls"))
631 {
632 ULONG Mod2Start = 0;
633 ULONG Mod2End = 0;
634 ULONG Mod3Start = 0;
635 ULONG Mod3End = 0;
636
637 name = (PCHAR)KeLoaderModules[i+1].String;
638 if (RtlpCheckFileNameExtension(name, ".nls"))
639 {
640 Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
641 Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
642
643 name = (PCHAR)KeLoaderModules[i+2].String;
644 if (RtlpCheckFileNameExtension(name, ".nls"))
645 {
646 Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
647 Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
648 }
649 }
650
651 /* Initialize nls sections */
652 RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
653 (ULONG)KeLoaderModules[i].ModEnd,
654 Mod2Start,
655 Mod2End,
656 Mod3Start,
657 Mod3End);
658 break;
659 }
660 }
661
662 /* Pass 2: load registry chunks passed in */
663 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
664 {
665 start = KeLoaderModules[i].ModStart;
666 length = KeLoaderModules[i].ModEnd - start;
667 name = (PCHAR)KeLoaderModules[i].String;
668 if (RtlpCheckFileNameExtension(name, "") ||
669 RtlpCheckFileNameExtension(name, ".hiv"))
670 {
671 CPRINT("Process registry chunk at %08lx\n", start);
672 CmImportHive((PCHAR)start, length);
673 }
674 }
675
676 /* Initialize volatile registry settings */
677 CmInit2((PCHAR)KeLoaderBlock.CommandLine);
678
679 /*
680 * Enter the kernel debugger before starting up the boot drivers
681 */
682 #ifdef KDBG
683 KdbEnter();
684 #endif /* KDBG */
685
686 IoCreateDriverList();
687
688 /* Pass 3: process boot loaded drivers */
689 BootDriverCount = 0;
690 for (i=1; i < KeLoaderBlock.ModsCount; i++)
691 {
692 start = KeLoaderModules[i].ModStart;
693 length = KeLoaderModules[i].ModEnd - start;
694 name = (PCHAR)KeLoaderModules[i].String;
695 if (RtlpCheckFileNameExtension(name, ".sys") ||
696 RtlpCheckFileNameExtension(name, ".sym"))
697 {
698 CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
699 name, start, length);
700 LdrInitializeBootStartDriver((PVOID)start, name, length);
701 }
702 if (RtlpCheckFileNameExtension(name, ".sys"))
703 BootDriverCount++;
704 }
705
706 if (BootDriverCount == 0)
707 {
708 DbgPrint("No boot drivers available.\n");
709 KeBugCheck(0);
710 }
711
712 /* Create ARC names for boot devices */
713 IoCreateArcNames();
714
715 /* Create the SystemRoot symbolic link */
716 CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
717 Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
718 if (!NT_SUCCESS(Status))
719 KeBugCheck(INACCESSIBLE_BOOT_DEVICE);
720
721 #ifdef DBGPRINT_FILE_LOG
722 /* On the assumption that we can now access disks start up the debug
723 logger thread */
724 DebugLogInit2();
725 #endif /* DBGPRINT_FILE_LOG */
726
727
728 PiInitDefaultLocale();
729
730 /*
731 * Start the motherboard enumerator (the HAL)
732 */
733 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
734 #if 0
735 /*
736 * Load boot start drivers
737 */
738 IopLoadBootStartDrivers();
739 #else
740 /*
741 * Load Auto configured drivers
742 */
743 LdrLoadAutoConfigDrivers();
744 #endif
745
746 IoDestroyDriverList();
747
748 /*
749 * Assign drive letters
750 */
751 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
752 NULL,
753 NULL,
754 NULL);
755
756 /*
757 * Initialize shared user page:
758 * - set dos system path, dos device map, etc.
759 */
760 InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
761
762 /*
763 * Launch initial process
764 */
765 LdrLoadInitialProcess();
766
767 PsTerminateSystemThread(STATUS_SUCCESS);
768 }
769
770
771 VOID
772 KiSystemStartup(BOOLEAN BootProcessor)
773 {
774 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
775
776 if (BootProcessor)
777 {
778 /* Never returns */
779 ExpInitializeExecutive();
780 KeBugCheck(0);
781 }
782 /* Do application processor initialization */
783 KeApplicationProcessorInit();
784 PsApplicationProcessorInit();
785 KeLowerIrql(PASSIVE_LEVEL);
786 PsIdleThreadMain(NULL);
787 KeBugCheck(0);
788 for(;;);
789 }
790
791 VOID
792 _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
793 /*
794 * FUNCTION: Called by the boot loader to start the kernel
795 * ARGUMENTS:
796 * LoaderBlock = Pointer to boot parameters initialized by the boot
797 * loader
798 * NOTE: The boot parameters are stored in low memory which will become
799 * invalid after the memory managment is initialized so we make a local copy.
800 */
801 {
802 ULONG i;
803 ULONG size;
804 ULONG last_kernel_address;
805 extern ULONG _bss_end__;
806 ULONG HalBase;
807 ULONG DriverBase;
808 ULONG DriverSize;
809
810 /* Low level architecture specific initialization */
811 KeInit1();
812
813 /*
814 * Copy the parameters to a local buffer because lowmem will go away
815 */
816 memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
817 memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
818 sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
819 KeLoaderBlock.ModsCount++;
820 KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
821
822 if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
823 {
824 ULONG DiskNumber, PartNumber;
825 PCH p;
826 CHAR Temp[256];
827 PCH options;
828 PCH s1;
829
830 if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
831 ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
832 {
833 DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0';
834 PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0';
835 }
836 strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]);
837 if ((options = strchr(Temp, ' ')) != NULL)
838 {
839 *options = 0;
840 options++;
841 }
842 else
843 {
844 options = "";
845 }
846 if ((s1 = strrchr(Temp, '/')) != NULL)
847 {
848 *s1 = 0;
849 if ((s1 = strrchr(Temp, '/')) != NULL)
850 {
851 *s1 = 0;
852 }
853 }
854 sprintf(KeLoaderCommandLine,
855 "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s",
856 DiskNumber, PartNumber + 1, Temp, options);
857
858 p = KeLoaderCommandLine;
859 while (*p != 0 && *p != ' ')
860 {
861 if ((*p) == '/')
862 {
863 (*p) = '\\';
864 }
865 p++;
866 }
867 DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
868 }
869 else
870 {
871 strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine);
872 }
873 KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
874
875 strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
876 KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
877 KeLoaderModules[0].ModStart = 0xC0000000;
878 KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
879 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
880 {
881 strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
882 KeLoaderModules[i].ModStart -= 0x200000;
883 KeLoaderModules[i].ModStart += 0xc0000000;
884 KeLoaderModules[i].ModEnd -= 0x200000;
885 KeLoaderModules[i].ModEnd += 0xc0000000;
886 KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
887 }
888
889 #ifdef HAL_DBG
890 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
891 #endif
892
893 HalBase = KeLoaderModules[1].ModStart;
894 DriverBase =
895 PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
896
897 /*
898 * Process hal.dll
899 */
900 LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
901
902 LdrHalBase = (ULONG_PTR)DriverBase;
903 last_kernel_address = DriverBase + DriverSize;
904
905 /*
906 * Process ntoskrnl.exe
907 */
908 LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
909
910 FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
911 LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
912 LastKernelAddress = last_kernel_address;
913
914 #ifndef ACPI
915 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
916 KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
917 #endif
918
919 KeMemoryMapRangeCount = 0;
920 if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
921 {
922 /* We have a memory map from the nice BIOS */
923 size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
924 i = 0;
925 while (i < KeLoaderBlock.MmapLength)
926 {
927 memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
928 (PVOID)(KeLoaderBlock.MmapAddr + i),
929 sizeof(ADDRESS_RANGE));
930 KeMemoryMapRangeCount++;
931 i += size;
932 }
933 }
934
935 KiSystemStartup(1);
936 }
937
938 /* EOF */
939