3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ke/main.c
6 * PURPOSE: Initalizes the kernel
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
14 #include "../dbg/kdb.h"
15 #include <ntos/bootvid.h>
16 #include <napi/core.h>
19 #include <internal/ntosdbg.h>
21 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
30 #include <internal/debug.h>
32 /* GLOBALS *******************************************************************/
34 #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
35 ULONG NtMajorVersion
= 4;
36 ULONG NtMinorVersion
= 0;
37 ULONG NtOSCSDVersion
= BUILD_OSCSDVERSION(6, 0);
39 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
40 ULONG EXPORTED NtGlobalFlag
= 0;
41 CHAR EXPORTED KeNumberProcessors
;
42 KAFFINITY EXPORTED KeActiveProcessors
;
43 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
44 ULONG EXPORTED KeDcacheFlushCount
= 0;
45 ULONG EXPORTED KeIcacheFlushCount
= 0;
46 ULONG EXPORTED KiDmaIoCoherency
= 0; /* RISC Architectures only */
47 ULONG EXPORTED InitSafeBootMode
= 0; /* KB83764 */
49 /* Microsoft-style declarations */
50 EXPORTED ULONG NtBuildNumber
= KERNEL_VERSION_BUILD
;
51 EXPORTED ULONG NtGlobalFlag
= 0;
52 EXPORTED CHAR KeNumberProcessors
;
53 EXPORTED KAFFINITY KeActiveProcessors
;
54 EXPORTED LOADER_PARAMETER_BLOCK KeLoaderBlock
;
55 EXPORTED ULONG KeDcacheFlushCount
= 0;
56 EXPORTED ULONG KeIcacheFlushCount
= 0;
57 EXPORTED ULONG KiDmaIoCoherency
= 0; /* RISC Architectures only */
58 EXPORTED ULONG InitSafeBootMode
= 0; /* KB83764 */
61 static LOADER_MODULE KeLoaderModules
[64];
62 static CHAR KeLoaderModuleStrings
[64][256];
63 static CHAR KeLoaderCommandLine
[256];
64 static ADDRESS_RANGE KeMemoryMap
[64];
65 static ULONG KeMemoryMapRangeCount
;
66 static ULONG_PTR FirstKrnlPhysAddr
;
67 static ULONG_PTR LastKrnlPhysAddr
;
68 static ULONG_PTR LastKernelAddress
;
69 volatile BOOLEAN Initialized
= FALSE
;
70 extern ULONG MmCoreDumpType
;
71 extern CHAR KiTimerSystemAuditing
;
73 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
75 /* We allocate 4 pages, but we only use 3. The 4th is to guarantee page alignment */
76 ULONG kernel_stack
[4096];
77 ULONG double_trap_stack
[4096];
79 /* These point to the aligned 3 pages */
85 /* FUNCTIONS ****************************************************************/
87 static VOID INIT_FUNCTION
88 InitSystemSharedUserPage (PCSZ ParameterLine
)
90 UNICODE_STRING ArcDeviceName
;
91 UNICODE_STRING ArcName
;
92 UNICODE_STRING BootPath
;
93 UNICODE_STRING DriveDeviceName
;
94 UNICODE_STRING DriveName
;
95 WCHAR DriveNameBuffer
[20];
101 OBJECT_ATTRIBUTES ObjectAttributes
;
104 BOOLEAN BootDriveFound
;
108 * The shared user page has been zeroed-out right after creation.
109 * There is NO need to do this again.
112 Ki386SetProcessorFeatures();
114 SharedUserData
->NtProductType
= NtProductWinNt
;
115 SharedUserData
->ProductTypeIsValid
= TRUE
;
116 SharedUserData
->NtMajorVersion
= 5;
117 SharedUserData
->NtMinorVersion
= 0;
119 BootDriveFound
= FALSE
;
122 * Retrieve the current dos system path
123 * (e.g.: C:\reactos) from the given arc path
124 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
125 * Format: "<arc_name>\<path> [options...]"
128 /* create local parameter line copy */
129 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
130 strcpy (ParamBuffer
, (char *)ParameterLine
);
131 DPRINT("%s\n", ParamBuffer
);
133 /* cut options off */
134 p
= strchr (ParamBuffer
, ' ');
139 DPRINT("%s\n", ParamBuffer
);
142 p
= strchr (ParamBuffer
, '\\');
145 DPRINT("Boot path: %s\n", p
);
146 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
151 DPRINT("Boot path: %s\n", "\\");
152 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
154 DPRINT("Arc name: %s\n", ParamBuffer
);
156 /* Only arc name left - build full arc name */
157 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
158 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
159 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
160 DPRINT("Arc name: %wZ\n", &ArcName
);
162 /* free ParamBuffer */
163 ExFreePool (ParamBuffer
);
165 /* allocate arc device name string */
166 ArcDeviceName
.Length
= 0;
167 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
168 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
170 InitializeObjectAttributes (&ObjectAttributes
,
176 Status
= NtOpenSymbolicLinkObject (&Handle
,
177 SYMBOLIC_LINK_ALL_ACCESS
,
179 RtlFreeUnicodeString (&ArcName
);
180 if (!NT_SUCCESS(Status
))
182 RtlFreeUnicodeString (&BootPath
);
183 RtlFreeUnicodeString (&ArcDeviceName
);
184 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
190 Status
= NtQuerySymbolicLinkObject (Handle
,
194 if (!NT_SUCCESS(Status
))
196 RtlFreeUnicodeString (&BootPath
);
197 RtlFreeUnicodeString (&ArcDeviceName
);
198 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
203 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
206 /* allocate device name string */
207 DriveDeviceName
.Length
= 0;
208 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
209 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
211 for (i
= 0; i
< 26; i
++)
213 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
214 RtlInitUnicodeString (&DriveName
,
217 InitializeObjectAttributes (&ObjectAttributes
,
223 Status
= NtOpenSymbolicLinkObject (&Handle
,
224 SYMBOLIC_LINK_ALL_ACCESS
,
226 if (!NT_SUCCESS(Status
))
228 DPRINT("Failed to open link %wZ\n",
233 Status
= NtQuerySymbolicLinkObject (Handle
,
236 if (!NT_SUCCESS(Status
))
238 DPRINT("Failed query open link %wZ\n",
242 DPRINT("Opened link: %wZ ==> %wZ\n",
243 &DriveName
, &DriveDeviceName
);
245 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
247 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
248 swprintf(SharedUserData
->NtSystemRoot
,
249 L
"%C:%wZ", 'A' + i
, &BootPath
);
251 BootDriveFound
= TRUE
;
257 RtlFreeUnicodeString (&BootPath
);
258 RtlFreeUnicodeString (&DriveDeviceName
);
259 RtlFreeUnicodeString (&ArcDeviceName
);
261 if (BootDriveFound
== FALSE
)
263 DbgPrint("No system drive found!\n");
264 KEBUGCHECK (NO_BOOT_DEVICE
);
269 ExpInitializeExecutive(VOID
)
271 LARGE_INTEGER Timeout
;
272 HANDLE ProcessHandle
;
283 BOOLEAN NoGuiBoot
= FALSE
;
285 HANDLE InitDoneEventHandle
;
286 OBJECT_ATTRIBUTES ObjectAttributes
;
289 * Fail at runtime if someone has changed various structures without
290 * updating the offsets used for the assembler code.
292 ASSERT(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
293 ASSERT(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
294 ASSERT(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
295 ASSERT(FIELD_OFFSET(KTHREAD
, NpxState
) == KTHREAD_NPX_STATE
);
296 ASSERT(FIELD_OFFSET(KTHREAD
, ServiceTable
) == KTHREAD_SERVICE_TABLE
);
297 ASSERT(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
298 ASSERT(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
299 ASSERT(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
300 ASSERT(FIELD_OFFSET(KTHREAD
, ApcState
.Process
) == KTHREAD_APCSTATE_PROCESS
);
301 ASSERT(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
302 KPROCESS_DIRECTORY_TABLE_BASE
);
303 ASSERT(FIELD_OFFSET(KPROCESS
, IopmOffset
) == KPROCESS_IOPM_OFFSET
);
304 ASSERT(FIELD_OFFSET(KPROCESS
, LdtDescriptor
) == KPROCESS_LDT_DESCRIPTOR0
);
305 ASSERT(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
306 ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME
, SavedExceptionStack
) == TF_SAVED_EXCEPTION_STACK
);
307 ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
308 ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
310 ASSERT(FIELD_OFFSET(KPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
311 ASSERT(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
312 ASSERT(FIELD_OFFSET(KPCR
, PrcbData
) + FIELD_OFFSET(KPRCB
, CurrentThread
) == KPCR_CURRENT_THREAD
);
313 ASSERT(FIELD_OFFSET(KPCR
, PrcbData
) + FIELD_OFFSET(KPRCB
, NpxThread
) == KPCR_NPX_THREAD
);
315 ASSERT(FIELD_OFFSET(KTSS
, Esp0
) == KTSS_ESP0
);
316 ASSERT(FIELD_OFFSET(KTSS
, Eflags
) == KTSS_EFLAGS
);
317 ASSERT(FIELD_OFFSET(KTSS
, IoMapBase
) == KTSS_IOMAPBASE
);
319 ASSERT(sizeof(FX_SAVE_AREA
) == SIZEOF_FX_SAVE_AREA
);
323 KeLowerIrql(DISPATCH_LEVEL
);
327 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
330 while(*p1
&& (p2
= strchr(p1
, '/')))
333 if (!_strnicmp(p2
, "MAXMEM", 6))
336 while (isspace(*p2
)) p2
++;
340 while(isspace(*p2
)) p2
++;
345 MaxMem
= MaxMem
* 10 + *p2
- '0';
352 else if (!_strnicmp(p2
, "NOGUIBOOT", 9))
357 else if (!_strnicmp(p2
, "CRASHDUMP", 9))
363 if (!_strnicmp(p2
, "FULL", 4))
365 MmCoreDumpType
= MM_CORE_DUMP_TYPE_FULL
;
369 MmCoreDumpType
= MM_CORE_DUMP_TYPE_NONE
;
376 MmInit1(FirstKrnlPhysAddr
,
379 (PADDRESS_RANGE
)&KeMemoryMap
,
380 KeMemoryMapRangeCount
,
381 MaxMem
> 8 ? MaxMem
: 4096);
383 /* Import ANSI code page table */
384 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
386 start
= KeLoaderModules
[i
].ModStart
;
387 length
= KeLoaderModules
[i
].ModEnd
- start
;
389 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
392 name
= (PCHAR
)KeLoaderModules
[i
].String
;
399 if (!_stricmp (name
, "ansi.nls"))
401 RtlpImportAnsiCodePage((PUSHORT
)start
, length
);
405 /* Import OEM code page table */
406 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
408 start
= KeLoaderModules
[i
].ModStart
;
409 length
= KeLoaderModules
[i
].ModEnd
- start
;
411 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
414 name
= (PCHAR
)KeLoaderModules
[i
].String
;
421 if (!_stricmp (name
, "oem.nls"))
423 RtlpImportOemCodePage((PUSHORT
)start
, length
);
427 /* Import Unicode casemap table */
428 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
430 start
= KeLoaderModules
[i
].ModStart
;
431 length
= KeLoaderModules
[i
].ModEnd
- start
;
433 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
436 name
= (PCHAR
)KeLoaderModules
[i
].String
;
443 if (!_stricmp (name
, "casemap.nls"))
445 RtlpImportUnicodeCasemap((PUSHORT
)start
, length
);
449 /* Create initial NLS tables */
450 RtlpCreateInitialNlsTables();
453 * Initialize the kernel debugger
455 KdInitSystem (1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
460 if (KeMemoryMapRangeCount
> 0)
462 DPRINT1("MemoryMap:\n");
463 for (i
= 0; i
< KeMemoryMapRangeCount
; i
++)
465 switch(KeMemoryMap
[i
].Type
)
468 strcpy(str
, "(usable)");
471 strcpy(str
, "(reserved)");
474 strcpy(str
, "(ACPI data)");
477 strcpy(str
, "(ACPI NVS)");
480 sprintf(str
, "type %lu", KeMemoryMap
[i
].Type
);
482 DPRINT1("%08x - %08x %s\n", KeMemoryMap
[i
].BaseAddrLow
, KeMemoryMap
[i
].BaseAddrLow
+ KeMemoryMap
[i
].LengthLow
, str
);
487 KeLowerIrql(PASSIVE_LEVEL
);
490 KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
497 KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED
);
499 KeNumberProcessors
= 1;
501 PiInitProcessManager();
503 if (KdPollBreakIn ())
505 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
508 /* Initialize all processors */
509 while (!HalAllProcessorsStarted())
511 PVOID ProcessorStack
;
513 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
514 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
516 /* Allocate a stack for use when booting the processor */
517 ProcessorStack
= Ki386InitialStackArray
[((int)KeNumberProcessors
)] + MM_STACK_SIZE
;
519 HalStartNextProcessor(0, (ULONG
)ProcessorStack
- 2*sizeof(FX_SAVE_AREA
));
520 KeNumberProcessors
++;
524 * Initialize various critical subsystems
526 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
531 PoInit(&KeLoaderBlock
, FALSE
);
532 CmInitializeRegistry();
536 FsRtlpInitFileLockingImplementation();
538 /* Report all resources used by hal */
539 HalReportResourceUsage();
542 * Clear the screen to blue
544 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
547 * Display version number and copyright/warranty message
549 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
550 KERNEL_VERSION_BUILD_STR
")\n");
551 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
552 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
553 "Public License, and you\n");
554 HalDisplayString("are welcome to change it and/or distribute copies of it "
556 HalDisplayString("conditions. There is absolutely no warranty for "
559 if (KeNumberProcessors
> 1)
562 "Found %d system processors. [%lu MB Memory]\n",
564 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
569 "Found 1 system processor. [%lu MB Memory]\n",
570 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
572 HalDisplayString(str
);
577 /* Create the NLS section */
578 RtlpCreateNlsSection();
581 * Initalize services loaded at boot time
583 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
584 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
586 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
587 KeLoaderModules
[i
].String
,
588 KeLoaderModules
[i
].ModStart
,
589 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
592 /* Pass 1: import system hive registry chunk */
594 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
596 start
= KeLoaderModules
[i
].ModStart
;
597 length
= KeLoaderModules
[i
].ModEnd
- start
;
599 DPRINT("Module: '%s'\n", (PCHAR
)KeLoaderModules
[i
].String
);
600 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
603 name
= (PCHAR
)KeLoaderModules
[i
].String
;
610 if (!_stricmp (name
, "system") ||
611 !_stricmp (name
, "system.hiv"))
613 CPRINT("Process system hive registry chunk at %08lx\n", start
);
615 CmImportSystemHive((PCHAR
)start
, length
);
619 /* Pass 2: import hardware hive registry chunk */
620 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
622 start
= KeLoaderModules
[i
].ModStart
;
623 length
= KeLoaderModules
[i
].ModEnd
- start
;
624 name
= (PCHAR
)KeLoaderModules
[i
].String
;
625 if (!_stricmp (name
, "hardware") ||
626 !_stricmp (name
, "hardware.hiv"))
628 CPRINT("Process hardware hive registry chunk at %08lx\n", start
);
629 CmImportHardwareHive((PCHAR
)start
, length
);
633 /* Create dummy keys if no hardware hive was found */
634 CmImportHardwareHive (NULL
, 0);
636 /* Initialize volatile registry settings */
637 if (SetupBoot
== FALSE
)
639 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
642 /* Initialize the time zone information from the registry */
643 ExpInitTimeZoneInfo();
646 * Enter the kernel debugger before starting up the boot drivers
652 IoCreateDriverList();
656 /* Initialize Callbacks before drivers */
657 ExpInitializeCallbacks();
659 /* Start boot logging */
661 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
662 while (*p1
&& (p2
= strchr(p1
, '/')))
665 if (!_strnicmp(p2
, "BOOTLOG", 7))
675 * Load boot start drivers
677 IopInitializeBootDrivers();
679 /* Display the boot screen image if not disabled */
682 InbvEnableBootDriver(TRUE
);
685 /* Create ARC names for boot devices */
688 /* Create the SystemRoot symbolic link */
689 CPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
690 DPRINT1("MmSystemRangeStart: 0x%x PageDir: 0x%x\n", MmSystemRangeStart
, KeLoaderBlock
.PageDirectoryStart
);
691 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
692 if (!NT_SUCCESS(Status
))
694 DbgPrint ( "IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
695 DbgPrintErrorMessage ( Status
);
696 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
702 #if defined(KDBG) || defined(DBG)
704 #endif /* KDBG || DBG */
706 /* On the assumption that we can now access disks start up the debug
708 if ((KdDebuggerEnabled
== TRUE
) && (KdDebugState
& KD_DEBUG_FILELOG
))
713 PiInitDefaultLocale();
716 * Load services for devices found by PnP manager
718 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
721 * Load system start drivers
723 IopInitializeSystemDrivers();
725 IoDestroyDriverList();
727 /* Stop boot logging */
731 * Assign drive letters
733 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
739 * Initialize shared user page:
740 * - set dos system path, dos device map, etc.
742 InitSystemSharedUserPage ((PCHAR
)KeLoaderBlock
.CommandLine
);
744 /* Create 'ReactOSInitDone' event */
745 RtlInitUnicodeString(&Name
, L
"\\ReactOSInitDone");
746 InitializeObjectAttributes(&ObjectAttributes
,
751 Status
= ZwCreateEvent(&InitDoneEventHandle
,
754 SynchronizationEvent
,
755 FALSE
); /* Not signalled */
756 if (!NT_SUCCESS(Status
))
758 DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status
);
759 InitDoneEventHandle
= INVALID_HANDLE_VALUE
;
763 * Launch initial process
765 Status
= LdrLoadInitialProcess(&ProcessHandle
,
767 if (!NT_SUCCESS(Status
))
769 KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
772 if (InitDoneEventHandle
!= INVALID_HANDLE_VALUE
)
774 HANDLE Handles
[2]; /* Init event, Initial process */
776 Handles
[0] = InitDoneEventHandle
;
777 Handles
[1] = ProcessHandle
;
779 /* Wait for the system to be initialized */
780 Timeout
.QuadPart
= (LONGLONG
)-1200000000; /* 120 second timeout */
781 Status
= ZwWaitForMultipleObjects(((LONG
) sizeof(Handles
) / sizeof(HANDLE
)),
784 FALSE
, /* Non-alertable */
786 if (!NT_SUCCESS(Status
))
788 DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status
);
790 else if (Status
== STATUS_TIMEOUT
)
792 DPRINT1("WARNING: System not initialized after 120 seconds.\n");
794 else if (Status
== STATUS_WAIT_0
+ 1)
797 * Crash the system if the initial process was terminated.
799 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
804 InbvEnableBootDriver(FALSE
);
807 ZwSetEvent(InitDoneEventHandle
, NULL
);
809 ZwClose(InitDoneEventHandle
);
813 /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
816 InbvEnableBootDriver(FALSE
);
820 * Crash the system if the initial process terminates within 5 seconds.
822 Timeout
.QuadPart
= (LONGLONG
)-50000000; /* 5 second timeout */
823 Status
= ZwWaitForSingleObject(ProcessHandle
,
826 if (Status
!= STATUS_TIMEOUT
)
828 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
832 * Tell ke/timer.c it's okay to run.
835 KiTimerSystemAuditing
= 1;
837 ZwClose(ThreadHandle
);
838 ZwClose(ProcessHandle
);
841 VOID
__attribute((noinline
))
842 KiSystemStartup(BOOLEAN BootProcessor
)
844 DPRINT1("KiSystemStartup(%d)\n", BootProcessor
);
850 KeApplicationProcessorInit();
853 HalInitializeProcessor(KeNumberProcessors
, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
857 ExpInitializeExecutive();
860 PsTerminateSystemThread(STATUS_SUCCESS
);
864 /* Do application processor initialization */
865 PsApplicationProcessorInit();
866 KeLowerIrql(PASSIVE_LEVEL
);
867 PsIdleThreadMain(NULL
);
874 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
876 * FUNCTION: Called by the boot loader to start the kernel
878 * LoaderBlock = Pointer to boot parameters initialized by the boot
880 * NOTE: The boot parameters are stored in low memory which will become
881 * invalid after the memory managment is initialized so we make a local copy.
890 /* Set up the Stacks */
891 trap_stack
= PAGE_ROUND_UP(&double_trap_stack
);
892 trap_stack_top
= trap_stack
+ 3 * PAGE_SIZE
;
893 init_stack
= PAGE_ROUND_UP(&kernel_stack
);
894 init_stack_top
= init_stack
+ 3 * PAGE_SIZE
;
897 * Copy the parameters to a local buffer because lowmem will go away
899 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
900 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
901 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
902 KeLoaderBlock
.ModsCount
++;
903 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
905 /* Save the Base Address */
906 MmSystemRangeStart
= (PVOID
)KeLoaderBlock
.KernelBase
;
909 * Convert a path specification in the grub format to one understood by the
910 * rest of the kernel.
912 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
914 ULONG DiskNumber
= 0, PartNumber
= 0;
920 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
921 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
923 DiskNumber
= ((PCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
924 PartNumber
= ((PCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
926 strcpy(Temp
, &((PCHAR
)_LoaderBlock
->CommandLine
)[7]);
927 if ((options
= strchr(Temp
, ' ')) != NULL
)
936 if ((s1
= strrchr(Temp
, '/')) != NULL
)
939 if ((s1
= strrchr(Temp
, '/')) != NULL
)
944 sprintf(KeLoaderCommandLine
,
945 "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
946 DiskNumber
, PartNumber
+ 1, Temp
, options
);
948 p
= KeLoaderCommandLine
;
949 while (*p
!= 0 && *p
!= ' ')
957 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
961 strcpy(KeLoaderCommandLine
, (PCHAR
)_LoaderBlock
->CommandLine
);
963 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
965 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
966 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
967 KeLoaderModules
[0].ModStart
= KERNEL_BASE
;
968 /* Take this value from the PE... */
969 PIMAGE_NT_HEADERS NtHeader
= RtlImageNtHeader((PVOID
)KeLoaderModules
[0].ModStart
);
970 PIMAGE_OPTIONAL_HEADER OptHead
= &NtHeader
->OptionalHeader
;
971 KeLoaderModules
[0].ModEnd
= KeLoaderModules
[0].ModStart
+ PAGE_ROUND_UP((ULONG
)OptHead
->SizeOfImage
);
972 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
975 if ((s
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '/')) != 0)
977 strcpy(KeLoaderModuleStrings
[i
], s
+ 1);
981 strcpy(KeLoaderModuleStrings
[i
], (PCHAR
)KeLoaderModules
[i
].String
);
983 KeLoaderModules
[i
].ModStart
-= 0x200000;
984 KeLoaderModules
[i
].ModStart
+= KERNEL_BASE
;
985 KeLoaderModules
[i
].ModEnd
-= 0x200000;
986 KeLoaderModules
[i
].ModEnd
+= KERNEL_BASE
;
987 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
990 LastKernelAddress
= PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
992 /* Low level architecture specific initialization */
993 KeInit1((PCHAR
)KeLoaderBlock
.CommandLine
, &LastKernelAddress
);
995 HalBase
= KeLoaderModules
[1].ModStart
;
996 DriverBase
= LastKernelAddress
;
997 LdrHalBase
= (ULONG_PTR
)DriverBase
;
999 LdrInitModuleManagement();
1004 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)KERNEL_BASE
, &DriverSize
);
1006 LastKernelAddress
+= PAGE_ROUND_UP(DriverSize
);
1009 * Process ntoskrnl.exe
1011 LdrSafePEProcessModule((PVOID
)KERNEL_BASE
, (PVOID
)KERNEL_BASE
, (PVOID
)DriverBase
, &DriverSize
);
1013 /* Now our imports from HAL are fixed. This is the first */
1014 /* time in the boot process that we can use HAL */
1016 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- KERNEL_BASE
+ 0x200000;
1017 LastKrnlPhysAddr
= LastKernelAddress
- KERNEL_BASE
+ 0x200000;
1019 KeMemoryMapRangeCount
= 0;
1020 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
1022 /* We have a memory map from the nice BIOS */
1023 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
1025 while (i
< KeLoaderBlock
.MmapLength
)
1027 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
1028 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
1029 sizeof(ADDRESS_RANGE
));
1030 KeMemoryMapRangeCount
++;
1033 KeLoaderBlock
.MmapLength
= KeMemoryMapRangeCount
* sizeof(ADDRESS_RANGE
);
1034 KeLoaderBlock
.MmapAddr
= (ULONG
)KeMemoryMap
;
1038 KeLoaderBlock
.MmapLength
= 0;
1039 KeLoaderBlock
.MmapAddr
= (ULONG
)KeMemoryMap
;
1042 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1043 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1045 DPRINT1("_main (%x, %x)\n", MultiBootMagic
, _LoaderBlock
);