3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
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.
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.
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.
19 /* $Id: main.c,v 1.190 2004/08/01 21:57:35 navaraf Exp $
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/main.c
23 * PURPOSE: Initalizes the kernel
24 * PROGRAMMER: David Welch (welch@cwcom.net)
29 /* INCLUDES *****************************************************************/
31 #define NTOS_MODE_KERNEL
33 #include <internal/ntoskrnl.h>
34 #include <reactos/resource.h>
35 #include <internal/mm.h>
36 #include <internal/ifs.h>
37 #include <internal/module.h>
38 #include <internal/ldr.h>
39 #include <internal/ex.h>
40 #include <internal/ps.h>
41 #include <internal/ke.h>
42 #include <internal/io.h>
43 #include <internal/po.h>
44 #include <internal/cc.h>
45 #include <internal/se.h>
46 #include <internal/v86m.h>
47 #include <internal/kd.h>
48 #include <internal/trap.h>
49 #include "../dbg/kdb.h"
50 #include <internal/nls.h>
51 #include <reactos/bugcodes.h>
52 #include <ntos/bootvid.h>
53 #include <napi/core.h>
56 #include <internal/ntosdbg.h>
58 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
67 #include <internal/debug.h>
69 /* GLOBALS *******************************************************************/
72 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
73 ULONG EXPORTED NtGlobalFlag
= 0;
74 CHAR EXPORTED KeNumberProcessors
;
75 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
76 ULONG EXPORTED KeDcacheFlushCount
= 0;
77 ULONG EXPORTED KeIcacheFlushCount
= 0;
79 /* Microsoft-style declarations */
80 EXPORTED ULONG NtBuildNumber
= KERNEL_VERSION_BUILD
;
81 EXPORTED ULONG NtGlobalFlag
= 0;
82 EXPORTED CHAR KeNumberProcessors
;
83 EXPORTED LOADER_PARAMETER_BLOCK KeLoaderBlock
;
84 EXPORTED ULONG KeDcacheFlushCount
= 0;
85 EXPORTED ULONG KeIcacheFlushCount
= 0;
88 static LOADER_MODULE KeLoaderModules
[64];
89 static UCHAR KeLoaderModuleStrings
[64][256];
90 static UCHAR KeLoaderCommandLine
[256];
91 static ADDRESS_RANGE KeMemoryMap
[64];
92 static ULONG KeMemoryMapRangeCount
;
93 static ULONG FirstKrnlPhysAddr
;
94 static ULONG LastKrnlPhysAddr
;
95 static ULONG LastKernelAddress
;
96 volatile BOOLEAN Initialized
= FALSE
;
97 extern ULONG MmCoreDumpType
;
98 extern CHAR KiTimerSystemAuditing
;
100 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
103 /* FUNCTIONS ****************************************************************/
105 static VOID INIT_FUNCTION
106 InitSystemSharedUserPage (PCSZ ParameterLine
)
108 UNICODE_STRING ArcDeviceName
;
109 UNICODE_STRING ArcName
;
110 UNICODE_STRING BootPath
;
111 UNICODE_STRING DriveDeviceName
;
112 UNICODE_STRING DriveName
;
113 WCHAR DriveNameBuffer
[20];
115 PWCHAR ArcNameBuffer
;
119 OBJECT_ATTRIBUTES ObjectAttributes
;
122 BOOLEAN BootDriveFound
;
126 * The shared user page has been zeroed-out right after creation.
127 * There is NO need to do this again.
130 SharedUserData
->NtProductType
= NtProductWinNt
;
132 BootDriveFound
= FALSE
;
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...]"
141 /* create local parameter line copy */
142 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
143 strcpy (ParamBuffer
, (char *)ParameterLine
);
144 DPRINT("%s\n", ParamBuffer
);
146 /* cut options off */
147 p
= strchr (ParamBuffer
, ' ');
152 DPRINT("%s\n", ParamBuffer
);
155 p
= strchr (ParamBuffer
, '\\');
158 DPRINT("Boot path: %s\n", p
);
159 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
164 DPRINT("Boot path: %s\n", "\\");
165 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
167 DPRINT("Arc name: %s\n", ParamBuffer
);
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
);
175 /* free ParamBuffer */
176 ExFreePool (ParamBuffer
);
178 /* allocate arc device name string */
179 ArcDeviceName
.Length
= 0;
180 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
181 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
183 InitializeObjectAttributes (&ObjectAttributes
,
189 Status
= NtOpenSymbolicLinkObject (&Handle
,
190 SYMBOLIC_LINK_ALL_ACCESS
,
192 RtlFreeUnicodeString (&ArcName
);
193 if (!NT_SUCCESS(Status
))
195 RtlFreeUnicodeString (&BootPath
);
196 RtlFreeUnicodeString (&ArcDeviceName
);
197 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
203 Status
= NtQuerySymbolicLinkObject (Handle
,
207 if (!NT_SUCCESS(Status
))
209 RtlFreeUnicodeString (&BootPath
);
210 RtlFreeUnicodeString (&ArcDeviceName
);
211 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
216 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
219 /* allocate device name string */
220 DriveDeviceName
.Length
= 0;
221 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
222 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
224 for (i
= 0; i
< 26; i
++)
226 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
227 RtlInitUnicodeString (&DriveName
,
230 InitializeObjectAttributes (&ObjectAttributes
,
236 Status
= NtOpenSymbolicLinkObject (&Handle
,
237 SYMBOLIC_LINK_ALL_ACCESS
,
239 if (!NT_SUCCESS(Status
))
241 DPRINT("Failed to open link %wZ\n",
246 Status
= NtQuerySymbolicLinkObject (Handle
,
249 if (!NT_SUCCESS(Status
))
251 DPRINT("Failed query open link %wZ\n",
255 DPRINT("Opened link: %wZ ==> %wZ\n",
256 &DriveName
, &DriveDeviceName
);
258 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
260 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
261 swprintf(SharedUserData
->NtSystemRoot
,
262 L
"%C:%wZ", 'A' + i
, &BootPath
);
264 BootDriveFound
= TRUE
;
270 RtlFreeUnicodeString (&BootPath
);
271 RtlFreeUnicodeString (&DriveDeviceName
);
272 RtlFreeUnicodeString (&ArcDeviceName
);
274 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData
->DosDeviceMap
);
276 if (BootDriveFound
== FALSE
)
278 DbgPrint("No system drive found!\n");
279 KEBUGCHECK (NO_BOOT_DEVICE
);
284 ExpInitializeExecutive(VOID
)
286 LARGE_INTEGER Timeout
;
287 HANDLE ProcessHandle
;
298 BOOLEAN NoGuiBoot
= FALSE
;
300 HANDLE InitDoneEventHandle
;
301 OBJECT_ATTRIBUTES ObjectAttributes
;
304 * Fail at runtime if someone has changed various structures without
305 * updating the offsets used for the assembler code.
307 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
308 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
309 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
310 assert(FIELD_OFFSET(KTHREAD
, ServiceTable
) == KTHREAD_SERVICE_TABLE
);
311 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
312 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
313 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
314 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
315 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
316 KPROCESS_DIRECTORY_TABLE_BASE
);
317 assert(FIELD_OFFSET(KPROCESS
, IopmOffset
) == KPROCESS_IOPM_OFFSET
);
318 assert(FIELD_OFFSET(KPROCESS
, LdtDescriptor
) == KPROCESS_LDT_DESCRIPTOR0
);
319 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
320 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
321 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
323 assert(FIELD_OFFSET(KPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
324 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
325 assert(FIELD_OFFSET(IKPCR
, Tib
.ExceptionList
) == KPCR_EXCEPTION_LIST
);
326 assert(FIELD_OFFSET(IKPCR
, Self
) == KPCR_SELF
);
327 assert(FIELD_OFFSET(IKPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
331 KeLowerIrql(DISPATCH_LEVEL
);
335 p1
= (PCHAR
)KeLoaderBlock
.CommandLine
;
338 while(*p1
&& (p2
= strchr(p1
, '/')))
341 if (!_strnicmp(p2
, "MAXMEM", 6))
344 while (isspace(*p2
)) p2
++;
348 while(isspace(*p2
)) p2
++;
353 MaxMem
= MaxMem
* 10 + *p2
- '0';
360 else if (!_strnicmp(p2
, "NOGUIBOOT", 12))
365 else if (!_strnicmp(p2
, "CRASHDUMP", 9))
371 if (!_strnicmp(p2
, "FULL", 4))
373 MmCoreDumpType
= MM_CORE_DUMP_TYPE_FULL
;
377 MmCoreDumpType
= MM_CORE_DUMP_TYPE_NONE
;
384 MmInit1(FirstKrnlPhysAddr
,
387 (PADDRESS_RANGE
)&KeMemoryMap
,
388 KeMemoryMapRangeCount
,
389 MaxMem
> 8 ? MaxMem
: 4096);
391 /* Import ANSI code page table */
392 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
394 start
= KeLoaderModules
[i
].ModStart
;
395 length
= KeLoaderModules
[i
].ModEnd
- start
;
397 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
400 name
= (PCHAR
)KeLoaderModules
[i
].String
;
407 if (!_stricmp (name
, "ansi.nls"))
409 RtlpImportAnsiCodePage((PUSHORT
)start
, length
);
413 /* Import OEM code page table */
414 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
416 start
= KeLoaderModules
[i
].ModStart
;
417 length
= KeLoaderModules
[i
].ModEnd
- start
;
419 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
422 name
= (PCHAR
)KeLoaderModules
[i
].String
;
429 if (!_stricmp (name
, "oem.nls"))
431 RtlpImportOemCodePage((PUSHORT
)start
, length
);
435 /* Import Unicode casemap table */
436 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
438 start
= KeLoaderModules
[i
].ModStart
;
439 length
= KeLoaderModules
[i
].ModEnd
- start
;
441 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
444 name
= (PCHAR
)KeLoaderModules
[i
].String
;
451 if (!_stricmp (name
, "casemap.nls"))
453 RtlpImportUnicodeCasemap((PUSHORT
)start
, length
);
457 /* Create initial NLS tables */
458 RtlpCreateInitialNlsTables();
461 * Initialize the kernel debugger
463 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
468 if (KeMemoryMapRangeCount
> 0)
470 DPRINT1("MemoryMap:\n");
471 for (i
= 0; i
< KeMemoryMapRangeCount
; i
++)
473 switch(KeMemoryMap
[i
].Type
)
476 strcpy(str
, "(usable)");
479 strcpy(str
, "(reserved)");
482 strcpy(str
, "(ACPI data)");
485 strcpy(str
, "(ACPI NVS)");
488 sprintf(str
, "type %lu", KeMemoryMap
[i
].Type
);
490 DPRINT1("%08x - %08x %s\n", KeMemoryMap
[i
].BaseAddrLow
, KeMemoryMap
[i
].BaseAddrLow
+ KeMemoryMap
[i
].LengthLow
, str
);
495 KeLowerIrql(PASSIVE_LEVEL
);
498 KEBUGCHECK(SECURITY_INITIALIZATION_FAILED
);
505 KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED
);
507 PiInitProcessManager();
509 if (KdPollBreakIn ())
511 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
514 /* Initialize all processors */
515 KeNumberProcessors
= 0;
517 while (!HalAllProcessorsStarted())
519 PVOID ProcessorStack
;
521 if (KeNumberProcessors
!= 0)
523 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
524 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
526 /* Allocate a stack for use when booting the processor */
527 /* FIXME: The nonpaged memory for the stack is not released after use */
529 (char*)ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
530 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
531 (PVOID
)((char*)ProcessorStack
- MM_STACK_SIZE
);
532 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
533 KeNumberProcessors
++;
537 * Initialize various critical subsystems
539 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
545 LdrInitModuleManagement();
546 CmInitializeRegistry();
551 FsRtlpInitFileLockingImplementation();
553 /* Report all resources used by hal */
554 HalReportResourceUsage();
557 * Clear the screen to blue
559 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
562 * Display version number and copyright/warranty message
564 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
565 KERNEL_VERSION_BUILD_STR
")\n");
566 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
567 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
568 "Public License, and you\n");
569 HalDisplayString("are welcome to change it and/or distribute copies of it "
571 HalDisplayString("conditions. There is absolutely no warranty for "
574 if (KeNumberProcessors
> 1)
577 "Found %d system processors. [%lu MB Memory]\n",
579 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
584 "Found 1 system processor. [%lu MB Memory]\n",
585 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
587 HalDisplayString(str
);
592 /* Create the NLS section */
593 RtlpCreateNlsSection();
596 * Initalize services loaded at boot time
598 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
599 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
601 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
602 KeLoaderModules
[i
].String
,
603 KeLoaderModules
[i
].ModStart
,
604 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
607 /* Pass 1: import system hive registry chunk */
609 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
611 start
= KeLoaderModules
[i
].ModStart
;
612 length
= KeLoaderModules
[i
].ModEnd
- start
;
614 DPRINT("Module: '%s'\n", (PCHAR
)KeLoaderModules
[i
].String
);
615 name
= strrchr((PCHAR
)KeLoaderModules
[i
].String
, '\\');
618 name
= (PCHAR
)KeLoaderModules
[i
].String
;
625 if (!_stricmp (name
, "system") ||
626 !_stricmp (name
, "system.hiv"))
628 CPRINT("Process system hive registry chunk at %08lx\n", start
);
630 CmImportSystemHive((PCHAR
)start
, length
);
634 /* Pass 2: import hardware hive registry chunk */
635 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
637 start
= KeLoaderModules
[i
].ModStart
;
638 length
= KeLoaderModules
[i
].ModEnd
- start
;
639 name
= (PCHAR
)KeLoaderModules
[i
].String
;
640 if (!_stricmp (name
, "hardware") ||
641 !_stricmp (name
, "hardware.hiv"))
643 CPRINT("Process hardware hive registry chunk at %08lx\n", start
);
644 CmImportHardwareHive((PCHAR
)start
, length
);
648 /* Create dummy keys if no hardware hive was found */
649 CmImportHardwareHive (NULL
, 0);
651 /* Initialize volatile registry settings */
652 if (SetupBoot
== FALSE
)
654 CmInit2((PCHAR
)KeLoaderBlock
.CommandLine
);
658 * Enter the kernel debugger before starting up the boot drivers
664 IoCreateDriverList();
668 /* Initialize Callbacks before drivers */
669 ExpInitializeCallbacks();
672 * Load boot start drivers
674 IopInitializeBootDrivers();
676 /* Display the boot screen image if not disabled */
679 InbvEnableBootDriver(TRUE
);
682 /* Create ARC names for boot devices */
685 /* Create the SystemRoot symbolic link */
686 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
687 Status
= IoCreateSystemRootLink((PUCHAR
)KeLoaderBlock
.CommandLine
);
688 if (!NT_SUCCESS(Status
))
689 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
695 /* On the assumption that we can now access disks start up the debug
697 if ((KdDebuggerEnabled
== TRUE
) && (KdDebugState
& KD_DEBUG_FILELOG
))
702 PiInitDefaultLocale();
705 * Load services for devices found by PnP manager
707 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
710 * Load system start drivers
712 IopInitializeSystemDrivers();
714 IoDestroyDriverList();
717 * Assign drive letters
719 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
725 * Initialize shared user page:
726 * - set dos system path, dos device map, etc.
728 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
730 /* Create 'ReactOSInitDone' event */
731 RtlInitUnicodeString(&Name
, L
"\\ReactOSInitDone");
732 InitializeObjectAttributes(&ObjectAttributes
,
737 Status
= NtCreateEvent(&InitDoneEventHandle
,
740 FALSE
, /* Synchronization event */
741 FALSE
); /* Not signalled */
742 if (!NT_SUCCESS(Status
))
744 DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status
);
745 InitDoneEventHandle
= INVALID_HANDLE_VALUE
;
749 * Launch initial process
751 Status
= LdrLoadInitialProcess(&ProcessHandle
,
753 if (!NT_SUCCESS(Status
))
755 KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
758 if (InitDoneEventHandle
!= INVALID_HANDLE_VALUE
)
760 HANDLE Handles
[2]; /* Init event, Initial process */
762 Handles
[0] = InitDoneEventHandle
;
763 Handles
[1] = ProcessHandle
;
765 /* Wait for the system to be initialized */
767 Timeout
.QuadPart
= -1200000000LL; /* 120 second timeout */
769 Timeout
.QuadPart
= -1200000000; /* 120 second timeout */
771 Status
= NtWaitForMultipleObjects(((LONG
) sizeof(Handles
) / sizeof(HANDLE
)),
774 FALSE
, /* Non-alertable */
776 if (!NT_SUCCESS(Status
))
778 DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status
);
780 else if (Status
== STATUS_TIMEOUT
)
782 DPRINT1("WARNING: System not initialized after 120 seconds.\n");
784 else if (Status
== STATUS_WAIT_0
+ 1)
787 * Crash the system if the initial process was terminated.
789 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
794 InbvEnableBootDriver(FALSE
);
797 NtSetEvent(InitDoneEventHandle
, NULL
);
799 NtClose(InitDoneEventHandle
);
803 /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
806 InbvEnableBootDriver(FALSE
);
810 * Crash the system if the initial process terminates within 5 seconds.
813 Timeout
.QuadPart
= -50000000LL;
815 Timeout
.QuadPart
= -50000000;
817 Status
= NtWaitForSingleObject(ProcessHandle
,
820 if (Status
!= STATUS_TIMEOUT
)
822 KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED
, Status
, 1, 0, 0);
826 * Tell ke/timer.c it's okay to run.
829 KiTimerSystemAuditing
= 1;
831 NtClose(ThreadHandle
);
832 NtClose(ProcessHandle
);
835 VOID
__attribute((noinline
))
836 KiSystemStartup(BOOLEAN BootProcessor
)
838 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
842 ExpInitializeExecutive();
845 PsTerminateSystemThread(STATUS_SUCCESS
);
848 /* Do application processor initialization */
849 KeApplicationProcessorInit();
850 PsApplicationProcessorInit();
851 KeLowerIrql(PASSIVE_LEVEL
);
852 PsIdleThreadMain(NULL
);
858 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
860 * FUNCTION: Called by the boot loader to start the kernel
862 * LoaderBlock = Pointer to boot parameters initialized by the boot
864 * NOTE: The boot parameters are stored in low memory which will become
865 * invalid after the memory managment is initialized so we make a local copy.
870 ULONG last_kernel_address
;
871 extern ULONG _bss_end__
;
876 /* Low level architecture specific initialization */
880 * Copy the parameters to a local buffer because lowmem will go away
882 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
883 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
884 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
885 KeLoaderBlock
.ModsCount
++;
886 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
889 * Convert a path specification in the grub format to one understood by the
890 * rest of the kernel.
892 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
894 ULONG DiskNumber
= 0, PartNumber
= 0;
900 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
901 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
903 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
904 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
906 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
907 if ((options
= strchr(Temp
, ' ')) != NULL
)
916 if ((s1
= strrchr(Temp
, '/')) != NULL
)
919 if ((s1
= strrchr(Temp
, '/')) != NULL
)
924 sprintf(KeLoaderCommandLine
,
925 "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
926 DiskNumber
, PartNumber
+ 1, Temp
, options
);
928 p
= KeLoaderCommandLine
;
929 while (*p
!= 0 && *p
!= ' ')
937 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
941 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
943 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
945 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
946 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
947 KeLoaderModules
[0].ModStart
= KERNEL_BASE
;
949 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
951 /* Take this value from the PE... */
953 PIMAGE_NT_HEADERS NtHeader
= RtlImageNtHeader((PVOID
)KeLoaderModules
[0].ModStart
);
954 PIMAGE_OPTIONAL_HEADER OptHead
= &NtHeader
->OptionalHeader
;
955 KeLoaderModules
[0].ModEnd
=
956 KeLoaderModules
[0].ModStart
+ PAGE_ROUND_UP((ULONG
)OptHead
->SizeOfImage
);
959 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
962 if ((s
= strrchr((PUCHAR
)KeLoaderModules
[i
].String
, '/')) != 0)
964 strcpy(KeLoaderModuleStrings
[i
], s
+ 1);
968 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
970 /* TODO: Fix this hardcoded load address stuff... */
971 KeLoaderModules
[i
].ModStart
-= 0x200000;
972 KeLoaderModules
[i
].ModStart
+= KERNEL_BASE
;
973 KeLoaderModules
[i
].ModEnd
-= 0x200000;
974 KeLoaderModules
[i
].ModEnd
+= KERNEL_BASE
;
975 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
979 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
982 HalBase
= KeLoaderModules
[1].ModStart
;
984 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
989 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)KERNEL_BASE
, &DriverSize
);
991 LdrHalBase
= (ULONG_PTR
)DriverBase
;
992 last_kernel_address
= DriverBase
+ DriverSize
;
995 * Process ntoskrnl.exe
997 LdrSafePEProcessModule((PVOID
)KERNEL_BASE
, (PVOID
)KERNEL_BASE
, (PVOID
)DriverBase
, &DriverSize
);
999 /* Now our imports from HAL is fixed. This is the first */
1000 /* time in the boot process that we can use HAL */
1002 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- KERNEL_BASE
+ 0x200000;
1003 LastKrnlPhysAddr
= last_kernel_address
- KERNEL_BASE
+ 0x200000;
1004 LastKernelAddress
= last_kernel_address
;
1007 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
1008 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
1011 KeMemoryMapRangeCount
= 0;
1012 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
1014 /* We have a memory map from the nice BIOS */
1015 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
1017 while (i
< KeLoaderBlock
.MmapLength
)
1019 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
1020 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
1021 sizeof(ADDRESS_RANGE
));
1022 KeMemoryMapRangeCount
++;