2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ex/init.c
5 * PURPOSE: Executive Initialization Code
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl (ekohl@rz-online.de)
10 /* INCLUDES ******************************************************************/
14 #include <internal/debug.h>
16 /* DATA **********************************************************************/
19 extern BOOLEAN KiClockSetupComplete
;
21 #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
24 ULONG NtMajorVersion
= 5;
25 ULONG NtMinorVersion
= 0;
26 ULONG NtOSCSDVersion
= BUILD_OSCSDVERSION(4, 0);
27 ULONG NtBuildNumber
= KERNEL_VERSION_BUILD
;
31 /* Init flags and settings */
32 ULONG ExpInitializationPhase
;
33 BOOLEAN ExpInTextModeSetup
;
34 BOOLEAN IoRemoteBootClient
;
35 ULONG InitSafeBootMode
;
37 BOOLEAN NoGuiBoot
= FALSE
;
40 UNICODE_STRING NtSystemRoot
;
42 /* Boot NLS information */
43 PVOID ExpNlsTableBase
;
44 ULONG ExpAnsiCodePageDataOffset
, ExpOemCodePageDataOffset
;
45 ULONG ExpUnicodeCaseTableDataOffset
;
46 NLSTABLEINFO ExpNlsTableInfo
;
47 ULONG ExpNlsTableSize
;
48 PVOID ExpNlsSectionPointer
;
50 /* FUNCTIONS ****************************************************************/
54 ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
56 UNICODE_STRING LinkName
;
57 OBJECT_ATTRIBUTES ObjectAttributes
;
62 ANSI_STRING TargetString
;
63 UNICODE_STRING TargetName
;
65 /* Initialize the ArcName tree */
66 RtlInitUnicodeString(&LinkName
, L
"\\ArcName");
67 InitializeObjectAttributes(&ObjectAttributes
,
69 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
74 Status
= NtCreateDirectoryObject(&LinkHandle
,
77 if (!NT_SUCCESS(Status
))
79 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
82 /* Close the LinkHandle */
85 /* Initialize the Device tree */
86 RtlInitUnicodeString(&LinkName
, L
"\\Device");
87 InitializeObjectAttributes(&ObjectAttributes
,
89 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
94 Status
= NtCreateDirectoryObject(&LinkHandle
,
97 if (!NT_SUCCESS(Status
))
99 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED
, Status
, 2, 0, 0);
102 /* Close the LinkHandle */
103 ObCloseHandle(LinkHandle
, KernelMode
);
105 /* Create the system root symlink name */
106 RtlInitAnsiString(&AnsiName
, "\\SystemRoot");
107 Status
= RtlAnsiStringToUnicodeString(&LinkName
, &AnsiName
, TRUE
);
108 if (!NT_SUCCESS(Status
))
110 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED
, Status
, 3, 0, 0);
113 /* Initialize the attributes for the link */
114 InitializeObjectAttributes(&ObjectAttributes
,
116 OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
120 /* Build the ARC name */
123 LoaderBlock
->ArcBootDeviceName
,
124 LoaderBlock
->NtBootPathName
);
125 Buffer
[strlen(Buffer
) - 1] = ANSI_NULL
;
127 /* Convert it to Unicode */
128 RtlInitString(&TargetString
, Buffer
);
129 Status
= RtlAnsiStringToUnicodeString(&TargetName
,
132 if (!NT_SUCCESS(Status
))
134 /* We failed, bugcheck */
135 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED
, Status
, 4, 0, 0);
139 Status
= NtCreateSymbolicLinkObject(&LinkHandle
,
140 SYMBOLIC_LINK_ALL_ACCESS
,
144 /* Free the strings */
145 RtlFreeUnicodeString(&LinkName
);
146 RtlFreeUnicodeString(&TargetName
);
148 /* Check if creating the link failed */
149 if (!NT_SUCCESS(Status
))
151 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED
, Status
, 5, 0, 0);
154 /* Close the handle and return success */
155 ObCloseHandle(LinkHandle
, KernelMode
);
156 return STATUS_SUCCESS
;
161 ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
163 LARGE_INTEGER SectionSize
;
166 PVOID SectionBase
= NULL
;
168 LARGE_INTEGER SectionOffset
= {{0}};
169 PLIST_ENTRY ListHead
, NextEntry
;
170 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
172 /* Check if this is boot-time phase 0 initialization */
173 if (!ExpInitializationPhase
)
175 /* Loop the memory descriptors */
176 ListHead
= &LoaderBlock
->MemoryDescriptorListHead
;
177 NextEntry
= ListHead
->Flink
;
178 while (NextEntry
!= ListHead
)
180 /* Get the current block */
181 MdBlock
= CONTAINING_RECORD(NextEntry
,
182 MEMORY_ALLOCATION_DESCRIPTOR
,
185 /* Check if this is an NLS block */
186 if (MdBlock
->MemoryType
== LoaderNlsData
)
188 /* Increase the table size */
189 ExpNlsTableSize
+= MdBlock
->PageCount
* PAGE_SIZE
;
192 /* Go to the next block */
193 NextEntry
= MdBlock
->ListEntry
.Flink
;
197 * In NT, the memory blocks are contiguous, but in ReactOS they aren't,
198 * so unless someone fixes FreeLdr, we'll have to use this icky hack.
200 ExpNlsTableSize
+= 2 * PAGE_SIZE
; // BIAS FOR FREELDR. HACK!
202 /* Allocate the a new buffer since loader memory will be freed */
203 ExpNlsTableBase
= ExAllocatePoolWithTag(NonPagedPool
,
205 TAG('R', 't', 'l', 'i'));
206 if (!ExpNlsTableBase
) KeBugCheck(PHASE0_INITIALIZATION_FAILED
);
208 /* Copy the codepage data in its new location. */
209 RtlCopyMemory(ExpNlsTableBase
,
210 LoaderBlock
->NlsData
->AnsiCodePageData
,
213 /* Initialize and reset the NLS TAbles */
214 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
215 ExpAnsiCodePageDataOffset
),
216 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
217 ExpOemCodePageDataOffset
),
218 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
219 ExpUnicodeCaseTableDataOffset
),
221 RtlResetRtlTranslations(&ExpNlsTableInfo
);
225 /* Set the section size */
226 SectionSize
.QuadPart
= ExpNlsTableSize
;
228 /* Create the NLS Section */
229 Status
= ZwCreateSection(&NlsSection
,
236 if (!NT_SUCCESS(Status
))
239 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
242 /* Get a pointer to the section */
243 Status
= ObReferenceObjectByHandle(NlsSection
,
247 &ExpNlsSectionPointer
,
250 if (!NT_SUCCESS(Status
))
253 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 2, 0, 0);
256 /* Map the NLS Section in system space */
257 Status
= MmMapViewInSystemSpace(ExpNlsSectionPointer
,
260 if (!NT_SUCCESS(Status
))
263 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 3, 0, 0);
266 /* Copy the codepage data in its new location. */
267 RtlCopyMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
269 /* Free the previously allocated buffer and set the new location */
270 ExFreePool(ExpNlsTableBase
);
271 ExpNlsTableBase
= SectionBase
;
273 /* Initialize the NLS Tables */
274 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
275 ExpAnsiCodePageDataOffset
),
276 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
277 ExpOemCodePageDataOffset
),
278 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
279 ExpUnicodeCaseTableDataOffset
),
281 RtlResetRtlTranslations(&ExpNlsTableInfo
);
283 /* Reset the base to 0 */
286 /* Map the section in the system process */
287 Status
= MmMapViewOfSection(ExpNlsSectionPointer
,
288 PsGetCurrentProcess(),
297 if (!NT_SUCCESS(Status
))
300 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, Status
, 5, 0, 0);
303 /* Copy the table into the system process and set this as the base */
304 RtlCopyMemory(SectionBase
, ExpNlsTableBase
, ExpNlsTableSize
);
305 ExpNlsTableBase
= SectionBase
;
310 ExpDisplayNotice(VOID
)
314 if (ExpInTextModeSetup
)
317 "\n\n\n ReactOS " KERNEL_VERSION_STR
" Setup \n");
319 " \xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD");
325 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
326 KERNEL_VERSION_BUILD_STR
")\n");
327 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
328 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
329 "Public License, and you\n");
330 HalDisplayString("are welcome to change it and/or distribute copies of it "
332 HalDisplayString("conditions. There is absolutely no warranty for "
335 /* Display number of Processors */
337 "Found %x system processor(s). [%lu MB Memory]\n",
338 (int)KeNumberProcessors
,
339 (MmFreeLdrMemHigher
+ 1088)/ 1024);
340 HalDisplayString(str
);
346 ExpLoadInitialProcess(IN PHANDLE ProcessHandle
,
347 IN PHANDLE ThreadHandle
)
349 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
352 RTL_USER_PROCESS_INFORMATION ProcessInformation
;
354 UNICODE_STRING NullString
= RTL_CONSTANT_STRING(L
"");
355 UNICODE_STRING SmssName
, Environment
, SystemDriveString
;
357 /* Allocate memory for the process parameters */
358 Size
= sizeof(RTL_USER_PROCESS_PARAMETERS
) +
359 ((MAX_PATH
* 4) * sizeof(WCHAR
));
360 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
361 (PVOID
)&ProcessParameters
,
366 if (!NT_SUCCESS(Status
))
369 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
372 /* Setup the basic header, and give the process the low 1MB to itself */
373 ProcessParameters
->Length
= Size
;
374 ProcessParameters
->MaximumLength
= Size
;
375 ProcessParameters
->Flags
= RTL_USER_PROCESS_PARAMETERS_NORMALIZED
|
376 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
;
378 /* Allocate a page for the environment */
380 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
381 (PVOID
)&ProcessParameters
->Environment
,
386 if (!NT_SUCCESS(Status
))
389 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
392 /* Make a buffer for the DOS path */
393 p
= (PWSTR
)(ProcessParameters
+ 1);
394 ProcessParameters
->CurrentDirectory
.DosPath
.Buffer
= p
;
396 CurrentDirectory
.DosPath
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
398 /* Copy the DOS path */
399 RtlCopyUnicodeString(&ProcessParameters
->CurrentDirectory
.DosPath
,
402 /* Make a buffer for the DLL Path */
403 p
= (PWSTR
)((PCHAR
)ProcessParameters
->CurrentDirectory
.DosPath
.Buffer
+
404 ProcessParameters
->CurrentDirectory
.DosPath
.MaximumLength
);
405 ProcessParameters
->DllPath
.Buffer
= p
;
406 ProcessParameters
->DllPath
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
408 /* Copy the DLL path and append the system32 directory */
409 RtlCopyUnicodeString(&ProcessParameters
->DllPath
,
410 &ProcessParameters
->CurrentDirectory
.DosPath
);
411 RtlAppendUnicodeToString(&ProcessParameters
->DllPath
, L
"\\System32");
413 /* Make a buffer for the image name */
414 p
= (PWSTR
)((PCHAR
)ProcessParameters
->DllPath
.Buffer
+
415 ProcessParameters
->DllPath
.MaximumLength
);
416 ProcessParameters
->ImagePathName
.Buffer
= p
;
417 ProcessParameters
->ImagePathName
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
419 /* Append the system path and session manager name */
420 RtlAppendUnicodeToString(&ProcessParameters
->ImagePathName
,
421 L
"\\SystemRoot\\System32");
422 RtlAppendUnicodeToString(&ProcessParameters
->ImagePathName
,
425 /* Create the environment string */
426 RtlInitEmptyUnicodeString(&Environment
,
427 ProcessParameters
->Environment
,
430 /* Append the DLL path to it */
431 RtlAppendUnicodeToString(&Environment
, L
"Path=" );
432 RtlAppendUnicodeStringToString(&Environment
, &ProcessParameters
->DllPath
);
433 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
435 /* Create the system drive string */
436 SystemDriveString
= NtSystemRoot
;
437 SystemDriveString
.Length
= 2 * sizeof(WCHAR
);
439 /* Append it to the environment */
440 RtlAppendUnicodeToString(&Environment
, L
"SystemDrive=");
441 RtlAppendUnicodeStringToString(&Environment
, &SystemDriveString
);
442 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
444 /* Append the system root to the environment */
445 RtlAppendUnicodeToString(&Environment
, L
"SystemRoot=");
446 RtlAppendUnicodeStringToString(&Environment
, &NtSystemRoot
);
447 RtlAppendUnicodeStringToString(&Environment
, &NullString
);
449 /* Get and set the command line equal to the image path */
450 ProcessParameters
->CommandLine
= ProcessParameters
->ImagePathName
;
451 SmssName
= ProcessParameters
->ImagePathName
;
453 /* Create SMSS process */
454 Status
= RtlCreateUserProcess(&SmssName
,
455 OBJ_CASE_INSENSITIVE
,
456 RtlDeNormalizeProcessParams(
464 &ProcessInformation
);
465 if (!NT_SUCCESS(Status
))
468 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
471 /* Resume the thread */
472 Status
= ZwResumeThread(ProcessInformation
.ThreadHandle
, NULL
);
473 if (!NT_SUCCESS(Status
))
476 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
480 *ProcessHandle
= ProcessInformation
.ProcessHandle
;
481 *ThreadHandle
= ProcessInformation
.ThreadHandle
;
482 return STATUS_SUCCESS
;
487 ExComputeTickCountMultiplier(IN ULONG ClockIncrement
)
489 ULONG MsRemainder
= 0, MsIncrement
;
490 ULONG IncrementRemainder
;
493 /* Count the number of milliseconds for each clock interrupt */
494 MsIncrement
= ClockIncrement
/ (10 * 1000);
496 /* Count the remainder from the division above, with 24-bit precision */
497 IncrementRemainder
= ClockIncrement
- (MsIncrement
* (10 * 1000));
498 for (i
= 0; i
< 24; i
++)
500 /* Shift the remainders */
502 IncrementRemainder
<<= 1;
504 /* Check if we've went past 1 ms */
505 if (IncrementRemainder
>= (10 * 1000))
507 /* Increase the remainder by one, and substract from increment */
508 IncrementRemainder
-= (10 * 1000);
513 /* Return the increment */
514 return (MsIncrement
<< 24) | MsRemainder
;
519 ExpInitSystemPhase0(VOID
)
521 /* Initialize EXRESOURCE Support */
522 ExpResourceInitialization();
524 /* Initialize the environment lock */
525 ExInitializeFastMutex(&ExpEnvironmentLock
);
527 /* Initialize the lookaside lists and locks */
528 ExpInitLookasideLists();
530 /* Initialize the Firmware Table resource and listhead */
531 InitializeListHead(&ExpFirmwareTableProviderListHead
);
532 ExInitializeResourceLite(&ExpFirmwareTableResource
);
534 /* Set the suite mask to maximum and return */
535 ExSuiteMask
= 0xFFFFFFFF;
541 ExpInitSystemPhase1(VOID
)
543 /* Initialize worker threads */
544 ExpInitializeWorkerThreads();
546 /* Initialize pushlocks */
547 ExpInitializePushLocks();
549 /* Initialize events and event pairs */
550 ExpInitializeEventImplementation();
551 ExpInitializeEventPairImplementation();
553 /* Initialize callbacks */
554 ExpInitializeCallbacks();
556 /* Initialize mutants */
557 ExpInitializeMutantImplementation();
559 /* Initialize semaphores */
560 ExpInitializeSemaphoreImplementation();
562 /* Initialize timers */
563 ExpInitializeTimerImplementation();
565 /* Initialize profiling */
566 ExpInitializeProfileImplementation();
568 /* Initialize UUIDs */
571 /* Initialize Win32K */
580 /* Check the initialization phase */
581 switch (ExpInitializationPhase
)
586 return ExpInitSystemPhase0();
591 return ExpInitSystemPhase1();
595 /* Don't know any other phase! Bugcheck! */
596 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL
);
603 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
605 PLOADER_PARAMETER_EXTENSION Extension
;
607 /* Get the loader extension */
608 Extension
= LoaderBlock
->Extension
;
610 /* Validate the size (larger structures are OK, we'll just ignore them) */
611 if (Extension
->Size
< sizeof(LOADER_PARAMETER_EXTENSION
)) return FALSE
;
613 /* Don't validate upper versions */
614 if (Extension
->MajorVersion
> 5) return TRUE
;
616 /* Fail if this is NT 4 */
617 if (Extension
->MajorVersion
< 5) return FALSE
;
619 /* Fail if this is XP */
620 if (Extension
->MinorVersion
< 2) return FALSE
;
622 /* This is 2003 or newer, approve it */
628 ExpInitializeExecutive(IN ULONG Cpu
,
629 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
631 PNLS_DATA_BLOCK NlsData
;
633 ANSI_STRING AnsiPath
;
636 /* Validate Loader */
637 if (!ExpIsLoaderValid(LoaderBlock
))
639 /* Invalid loader version */
640 KeBugCheckEx(MISMATCHED_HAL
,
642 LoaderBlock
->Extension
->Size
,
643 LoaderBlock
->Extension
->MajorVersion
,
644 LoaderBlock
->Extension
->MinorVersion
);
647 /* Initialize PRCB pool lookaside pointers */
648 ExInitPoolLookasidePointers();
650 /* Check if this is an application CPU */
653 /* Then simply initialize it with HAL */
654 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
656 /* Initialization failed */
657 KeBugCheck(HAL_INITIALIZATION_FAILED
);
664 /* Assume no text-mode or remote boot */
665 ExpInTextModeSetup
= FALSE
;
666 IoRemoteBootClient
= FALSE
;
668 /* Check if we have a setup loader block */
669 if (LoaderBlock
->SetupLdrBlock
)
671 /* Check if this is text-mode setup */
672 if (LoaderBlock
->SetupLdrBlock
->Flags
& 1) ExpInTextModeSetup
= TRUE
;
674 /* Check if this is network boot */
675 if (LoaderBlock
->SetupLdrBlock
->Flags
& 2)
678 IoRemoteBootClient
= TRUE
;
680 /* Make sure we're actually booting off the network */
681 ASSERT(!_memicmp(LoaderBlock
->ArcBootDeviceName
, "net(0)", 6));
686 ExpInitializationPhase
= 0;
688 /* Setup NLS Base and offsets */
689 NlsData
= LoaderBlock
->NlsData
;
690 ExpNlsTableBase
= NlsData
->AnsiCodePageData
;
691 ExpAnsiCodePageDataOffset
= 0;
692 ExpOemCodePageDataOffset
= ((ULONG_PTR
)NlsData
->OemCodePageData
-
693 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
694 ExpUnicodeCaseTableDataOffset
= ((ULONG_PTR
)NlsData
->UnicodeCodePageData
-
695 (ULONG_PTR
)NlsData
->AnsiCodePageData
);
697 /* Initialize the NLS Tables */
698 RtlInitNlsTables((PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
699 ExpAnsiCodePageDataOffset
),
700 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
701 ExpOemCodePageDataOffset
),
702 (PVOID
)((ULONG_PTR
)ExpNlsTableBase
+
703 ExpUnicodeCaseTableDataOffset
),
705 RtlResetRtlTranslations(&ExpNlsTableInfo
);
707 /* Now initialize the HAL */
708 if (!HalInitSystem(ExpInitializationPhase
, LoaderBlock
))
710 /* HAL failed to initialize, bugcheck */
711 KeBugCheck(HAL_INITIALIZATION_FAILED
);
714 /* Make sure interrupts are active now */
717 /* Clear the crypto exponent */
718 SharedUserData
->CryptoExponent
= 0;
720 /* Set global flags for the checked build */
722 NtGlobalFlag
|= FLG_ENABLE_CLOSE_EXCEPTIONS
|
723 FLG_ENABLE_KDEBUG_SYMBOL_LOAD
;
726 /* Setup NT System Root Path */
727 sprintf(Buffer
, "C:%s", LoaderBlock
->NtBootPathName
);
729 /* Convert to ANSI_STRING and null-terminate it */
730 RtlInitString(&AnsiPath
, Buffer
);
731 Buffer
[--AnsiPath
.Length
] = ANSI_NULL
;
733 /* Get the string from KUSER_SHARED_DATA's buffer */
734 NtSystemRoot
.Buffer
= SharedUserData
->NtSystemRoot
;
735 NtSystemRoot
.MaximumLength
= sizeof(SharedUserData
->NtSystemRoot
) / sizeof(WCHAR
);
736 NtSystemRoot
.Length
= 0;
739 Status
= RtlAnsiStringToUnicodeString(&NtSystemRoot
, &AnsiPath
, FALSE
);
740 if (!NT_SUCCESS(Status
)) KEBUGCHECK(SESSION3_INITIALIZATION_FAILED
);
742 /* Setup bugcheck messages */
743 KiInitializeBugCheck();
745 /* Initialize the executive at phase 0 */
746 if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED
);
748 /* Break into the Debugger if requested */
749 if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
751 /* Set system ranges */
752 SharedUserData
->Reserved1
= (ULONG_PTR
)MmHighestUserAddress
;
753 SharedUserData
->Reserved3
= (ULONG_PTR
)MmSystemRangeStart
;
755 /* Make a copy of the NLS Tables */
756 ExpInitNls(LoaderBlock
);
758 /* Initialize the Handle Table */
759 ExpInitializeHandleTables();
762 /* On checked builds, allocate the system call count table */
763 KeServiceDescriptorTable
[0].Count
=
764 ExAllocatePoolWithTag(NonPagedPool
,
765 KiServiceLimit
* sizeof(ULONG
),
766 TAG('C', 'a', 'l', 'l'));
768 /* Use it for the shadow table too */
769 KeServiceDescriptorTableShadow
[0].Count
= KeServiceDescriptorTable
[0].Count
;
771 /* Make sure allocation succeeded */
772 if (KeServiceDescriptorTable
[0].Count
)
774 /* Zero the call counts to 0 */
775 RtlZeroMemory(KeServiceDescriptorTable
[0].Count
,
776 KiServiceLimit
* sizeof(ULONG
));
780 /* Create the Basic Object Manager Types to allow new Object Types */
781 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED
);
783 /* Load basic Security for other Managers */
784 if (!SeInit()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
786 /* Set up Region Maps, Sections and the Paging File */
789 /* Initialize the boot video. */
790 InbvDisplayInitialize();
792 /* Initialize the Process Manager */
793 if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED
);
795 /* Initialize the User-Mode Debugging Subsystem */
798 /* Calculate the tick count multiplier */
799 ExpTickCountMultiplier
= ExComputeTickCountMultiplier(KeMaximumIncrement
);
800 SharedUserData
->TickCountMultiplier
= ExpTickCountMultiplier
;
802 /* Set the OS Version */
803 SharedUserData
->NtMajorVersion
= NtMajorVersion
;
804 SharedUserData
->NtMinorVersion
= NtMinorVersion
;
806 /* Set the machine type */
808 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_I386
;
809 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_I386
;
810 #elif defined(_PPC_) // <3 Arty
811 SharedUserData
->ImageNumberLow
= IMAGE_FILE_MACHINE_POWERPC
;
812 SharedUserData
->ImageNumberHigh
= IMAGE_FILE_MACHINE_POWERPC
;
814 #error "Unsupported ReactOS Target"
820 ExPhase2Init(PVOID Context
)
822 LARGE_INTEGER Timeout
;
823 HANDLE ProcessHandle
;
826 TIME_FIELDS TimeFields
;
827 LARGE_INTEGER SystemBootTime
, UniversalBootTime
;
830 ExpInitializationPhase
= 1;
832 /* Set us at maximum priority */
833 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY
);
835 /* Do Phase 1 HAL Initialization */
836 HalInitSystem(1, KeLoaderBlock
);
838 /* Check if GUI Boot is enabled */
839 if (strstr(KeLoaderBlock
->LoadOptions
, "NOGUIBOOT")) NoGuiBoot
= TRUE
;
841 /* Display the boot screen image if not disabled */
842 if (!ExpInTextModeSetup
) InbvDisplayInitialize2(NoGuiBoot
);
843 if (!NoGuiBoot
) InbvDisplayBootLogo();
845 /* Clear the screen to blue and display the boot notice and debug status */
846 if (NoGuiBoot
) ExpDisplayNotice();
847 KdInitSystem(2, KeLoaderBlock
);
849 /* Initialize Power Subsystem in Phase 0 */
850 PoInit(0, AcpiTableDetected
);
852 /* Query the clock */
853 if (HalQueryRealTimeClock(&TimeFields
))
855 /* Convert to time fields */
856 RtlTimeFieldsToTime(&TimeFields
, &SystemBootTime
);
857 UniversalBootTime
= SystemBootTime
;
859 #if 0 // FIXME: Won't work until we can read registry data here
860 /* FIXME: This assumes that the RTC is not already in GMT */
861 ExpTimeZoneBias
.QuadPart
= Int32x32To64(ExpLastTimeZoneBias
* 60,
864 /* Set the boot time-zone bias */
865 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.HighPart
;
866 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.LowPart
;
867 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.HighPart
;
869 /* Convert the boot time to local time, and set it */
870 UniversalBootTime
.QuadPart
= SystemBootTime
.QuadPart
+
871 ExpTimeZoneBias
.QuadPart
;
873 KiSetSystemTime(&UniversalBootTime
);
875 /* Remember this as the boot time */
876 KeBootTime
= UniversalBootTime
;
879 /* The clock is ready now (FIXME: HACK FOR OLD HAL) */
880 KiClockSetupComplete
= TRUE
;
882 /* Initialize all processors */
883 HalAllProcessorsStarted();
885 /* Call OB initialization again */
886 if (!ObInit()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED
);
888 /* Initialize Basic System Objects and Worker Threads */
889 if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, 1, 0, 0, 0);
891 /* Initialize the later stages of the kernel */
892 if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, 2, 0, 0, 0);
894 /* Call KD Providers at Phase 1 */
895 if (!KdInitSystem(ExpInitializationPhase
, KeLoaderBlock
))
897 /* Failed, bugcheck */
898 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED
, 3, 0, 0, 0);
901 /* Create SystemRoot Link */
902 Status
= ExpCreateSystemRootLink(KeLoaderBlock
);
903 if (!NT_SUCCESS(Status
))
905 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
908 /* Create NLS section */
909 ExpInitNls(KeLoaderBlock
);
911 /* Initialize Cache Views */
912 CcInitializeCacheManager();
914 /* Initialize the Registry */
915 if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED
);
917 /* Update timezone information */
918 ExRefreshTimeZoneInformation(&SystemBootTime
);
920 /* Initialize the File System Runtime Library */
923 /* Report all resources used by HAL */
924 HalReportResourceUsage();
929 /* Enter the kernel debugger before starting up the boot drivers */
930 if (KdDebuggerEnabled
&& KdpEarlyBreak
) DbgBreakPoint();
932 /* Initialize the I/O Subsystem */
933 if (!IoInitSystem(KeLoaderBlock
)) KeBugCheck(IO1_INITIALIZATION_FAILED
);
935 /* Unmap Low memory, and initialize the MPW and Balancer Thread */
940 ASSERT(Guard
== 0xCACA1234);
942 /* Initialize VDM support */
943 KeI386VdmInitialize();
945 /* Initialize Power Subsystem in Phase 1*/
946 PoInit(1, AcpiTableDetected
);
948 /* Initialize the Process Manager at Phase 1 */
949 if (!PsInitSystem()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED
);
951 /* Launch initial process */
952 Status
= ExpLoadInitialProcess(&ProcessHandle
, &ThreadHandle
);
954 /* Wait 5 seconds for it to initialize */
955 Timeout
.QuadPart
= Int32x32To64(5, -10000000);
956 Status
= ZwWaitForSingleObject(ProcessHandle
, FALSE
, &Timeout
);
957 if (!NoGuiBoot
) InbvFinalizeBootLogo();
958 if (Status
== STATUS_SUCCESS
)
960 /* Bugcheck the system if SMSS couldn't initialize */
961 KeBugCheck(SESSION5_INITIALIZATION_FAILED
);
965 /* Close process handles */
966 ZwClose(ThreadHandle
);
967 ZwClose(ProcessHandle
);
969 /* FIXME: We should free the initial process' memory!*/
971 /* Increase init phase */
972 ExpInitializationPhase
+= 1;
974 /* Jump into zero page thread */
975 MmZeroPageThreadMain(NULL
);