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.120 2002/05/02 23:45:33 dwelch 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 #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>
52 #include <internal/ntosdbg.h>
58 #include <internal/debug.h>
60 /* GLOBALS *******************************************************************/
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
;
76 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
87 SERVICE Services
[] = {
88 {L
"pci", L
"PCI Bus Driver", L
"Boot Bus Extender", 0, 1},
89 {L
"keyboard", L
"Standard Keyboard Driver", L
"Base", 0, 1},
90 {L
"blue", L
"Bluescreen Driver", L
"Base", 0, 1},
91 {L
"vidport", L
"Video Port Driver", L
"Base", 0, 1},
92 {L
"vgamp", L
"VGA Miniport", L
"Base", 0, 1},
93 {L
"minixfs", L
"Minix File System", L
"File system", 0, 1},
94 {L
"msfs", L
"Mail Slot File System", L
"File system", 0, 1},
95 {L
"npfs", L
"Named Pipe File System", L
"File system", 0, 1},
96 {L
"psaux", L
"PS/2 Auxillary Port Driver", L
"", 0, 1},
97 {L
"mouclass", L
"Mouse Class Driver", L
"Pointer Class", 0, 1},
98 {L
"ndis", L
"NDIS System Driver", L
"NDIS Wrapper", 0, 1},
99 {L
"ne2000", L
"Novell Eagle 2000 Driver", L
"NDIS", 0, 1},
100 {L
"afd", L
"AFD Networking Support Environment", L
"TDI", 0, 1},
104 /* FUNCTIONS ****************************************************************/
108 VOID
CreateDefaultRegistryForLegacyDriver(
112 WCHAR LegacyDriver
[] = L
"LegacyDriver";
114 WCHAR InstancePath
[MAX_PATH
];
115 WCHAR KeyNameBuffer
[MAX_PATH
];
116 WCHAR Name
[MAX_PATH
];
117 UNICODE_STRING KeyName
;
124 WCHAR ImagePath
[MAX_PATH
];
127 wcscpy(Name
, Service
->ServiceName
);
129 wcscpy(InstancePath
, L
"Root\\LEGACY_");
130 wcscat(InstancePath
, Name
);
131 wcscat(InstancePath
, L
"\\0000");
133 wcscpy(KeyNameBuffer
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
134 wcscat(KeyNameBuffer
, InstancePath
);
136 RtlInitUnicodeString(&KeyName
, KeyNameBuffer
);
138 DPRINT("Key name is %S\n", KeyName
.Buffer
);
140 Status
= RtlpCreateRegistryKeyPath(KeyName
.Buffer
);
141 if (!NT_SUCCESS(Status
))
143 DPRINT1("RtlpCreateRegistryKeyPath() failed with status %x\n", Status
);
147 Status
= RtlpGetRegistryHandle(
152 if (!NT_SUCCESS(Status
))
154 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
159 Length
= sizeof(DWORD
);
160 Status
= RtlWriteRegistryValue(
167 if (!NT_SUCCESS(Status
))
169 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
174 Length
= (wcslen(LegacyDriver
) + 1) * sizeof(WCHAR
);
175 Status
= RtlWriteRegistryValue(
182 if (!NT_SUCCESS(Status
))
184 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
189 Length
= (wcslen(Service
->DeviceDesc
) + 1) * sizeof(WCHAR
);
190 Status
= RtlWriteRegistryValue(
197 if (!NT_SUCCESS(Status
))
199 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
205 Length
= Length
= sizeof(DWORD
);
206 Status
= RtlWriteRegistryValue(
213 if (!NT_SUCCESS(Status
))
215 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
220 Length
= (wcslen(Service
->ServiceName
) + 1) * sizeof(WCHAR
);
221 Status
= RtlWriteRegistryValue(
226 Service
->ServiceName
,
228 if (!NT_SUCCESS(Status
))
230 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
238 /* Services section */
240 Status
= RtlpGetRegistryHandle(
241 RTL_REGISTRY_SERVICES
,
242 Service
->ServiceName
,
245 if (!NT_SUCCESS(Status
))
247 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
251 Length
= (wcslen(Service
->DeviceDesc
) + 1) * sizeof(WCHAR
);
252 Status
= RtlWriteRegistryValue(
259 if (!NT_SUCCESS(Status
))
261 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
267 Length
= sizeof(DWORD
);
268 Status
= RtlWriteRegistryValue(
275 if (!NT_SUCCESS(Status
))
277 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
282 Length
= (wcslen(Service
->Group
) + 1) * sizeof(WCHAR
);
283 Status
= RtlWriteRegistryValue(
290 if (!NT_SUCCESS(Status
))
292 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
297 wcscpy(ImagePath
, L
"\\SystemRoot\\System32\\drivers\\");
298 wcscat(ImagePath
, Service
->ServiceName
);
299 wcscat(ImagePath
, L
".sys");
301 Length
= (wcslen(ImagePath
) + 1) * sizeof(WCHAR
);
302 Status
= RtlWriteRegistryValue(
309 if (!NT_SUCCESS(Status
))
311 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
316 DwordData
= Service
->Start
;
317 Length
= sizeof(DWORD
);
318 Status
= RtlWriteRegistryValue(
325 if (!NT_SUCCESS(Status
))
327 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
332 DwordData
= Service
->Type
;
333 Length
= sizeof(DWORD
);
334 Status
= RtlWriteRegistryValue(
341 if (!NT_SUCCESS(Status
))
343 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
351 VOID
CreateDefaultRegistry()
356 Status
= RtlpCreateRegistryKeyPath(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
357 if (!NT_SUCCESS(Status
))
359 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status
);
363 Status
= RtlpCreateRegistryKeyPath(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
364 if (!NT_SUCCESS(Status
))
366 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status
);
370 for (i
= 0; Services
[i
].ServiceName
!= NULL
; i
++)
372 CreateDefaultRegistryForLegacyDriver(&Services
[i
]);
378 RtlpCheckFileNameExtension(PCHAR FileName
,
383 Ext
= strrchr(FileName
, '.');
384 if ((Extension
== NULL
) || (*Extension
== 0))
391 if (*Extension
!= '.')
394 if (_stricmp(Ext
, Extension
) == 0)
402 InitSystemSharedUserPage (PCSZ ParameterLine
)
404 UNICODE_STRING ArcDeviceName
;
405 UNICODE_STRING ArcName
;
406 UNICODE_STRING BootPath
;
407 UNICODE_STRING DriveDeviceName
;
408 UNICODE_STRING DriveName
;
409 WCHAR DriveNameBuffer
[20];
411 PWCHAR ArcNameBuffer
;
415 OBJECT_ATTRIBUTES ObjectAttributes
;
418 BOOLEAN BootDriveFound
;
422 * The shared user page has been zeroed-out right after creation.
423 * There is NO need to do this again.
426 SharedUserData
->NtProductType
= NtProductWinNt
;
428 BootDriveFound
= FALSE
;
431 * Retrieve the current dos system path
432 * (e.g.: C:\reactos) from the given arc path
433 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
434 * Format: "<arc_name>\<path> [options...]"
437 /* create local parameter line copy */
438 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
439 strcpy (ParamBuffer
, (char *)ParameterLine
);
440 DPRINT("%s\n", ParamBuffer
);
442 /* cut options off */
443 p
= strchr (ParamBuffer
, ' ');
448 DPRINT("%s\n", ParamBuffer
);
451 p
= strchr (ParamBuffer
, '\\');
454 DPRINT("Boot path: %s\n", p
);
455 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
460 DPRINT("Boot path: %s\n", "\\");
461 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
463 DPRINT("Arc name: %s\n", ParamBuffer
);
465 /* Only arc name left - build full arc name */
466 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
467 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
468 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
469 DPRINT("Arc name: %wZ\n", &ArcName
);
471 /* free ParamBuffer */
472 ExFreePool (ParamBuffer
);
474 /* allocate arc device name string */
475 ArcDeviceName
.Length
= 0;
476 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
477 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
479 InitializeObjectAttributes (&ObjectAttributes
,
485 Status
= NtOpenSymbolicLinkObject (&Handle
,
486 SYMBOLIC_LINK_ALL_ACCESS
,
488 RtlFreeUnicodeString (&ArcName
);
489 if (!NT_SUCCESS(Status
))
491 RtlFreeUnicodeString (&BootPath
);
492 RtlFreeUnicodeString (&ArcDeviceName
);
493 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
499 Status
= NtQuerySymbolicLinkObject (Handle
,
503 if (!NT_SUCCESS(Status
))
505 RtlFreeUnicodeString (&BootPath
);
506 RtlFreeUnicodeString (&ArcDeviceName
);
507 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
512 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
515 /* allocate device name string */
516 DriveDeviceName
.Length
= 0;
517 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
518 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
520 for (i
= 0; i
< 26; i
++)
522 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
523 RtlInitUnicodeString (&DriveName
,
526 InitializeObjectAttributes (&ObjectAttributes
,
532 Status
= NtOpenSymbolicLinkObject (&Handle
,
533 SYMBOLIC_LINK_ALL_ACCESS
,
535 if (!NT_SUCCESS(Status
))
537 DPRINT("Failed to open link %wZ\n",
542 Status
= NtQuerySymbolicLinkObject (Handle
,
545 if (!NT_SUCCESS(Status
))
547 DPRINT("Failed query open link %wZ\n",
551 DPRINT("Opened link: %wZ ==> %wZ\n",
552 &DriveName
, &DriveDeviceName
);
554 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
556 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
557 swprintf(SharedUserData
->NtSystemRoot
,
558 L
"%C:%wZ", 'A' + i
, &BootPath
);
560 BootDriveFound
= TRUE
;
566 RtlFreeUnicodeString (&BootPath
);
567 RtlFreeUnicodeString (&DriveDeviceName
);
568 RtlFreeUnicodeString (&ArcDeviceName
);
570 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData
->DosDeviceMap
);
572 if (BootDriveFound
== FALSE
)
574 DbgPrint("No system drive found!\n");
581 VOID
DumpBIOSMemoryMap(VOID
)
585 DbgPrint("Dumping BIOS memory map:\n");
586 DbgPrint("Memory map base: %d\n", KeLoaderBlock
.MmapAddr
);
587 DbgPrint("Memory map size: %d\n", KeLoaderBlock
.MmapLength
);
588 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount
);
589 for (i
= 0; i
< KeMemoryMapRangeCount
; i
++)
591 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
592 KeMemoryMap
[i
].BaseAddrLow
,
593 KeMemoryMap
[i
].LengthLow
,
594 KeMemoryMap
[i
].Type
);
604 static ULONG Scratch
;
606 EXCEPTION_DISPOSITION
607 ExpUnhandledException1(
608 PEXCEPTION_RECORD ExceptionRecord
,
609 PEXCEPTION_REGISTRATION ExceptionRegistration
,
611 PVOID DispatcherContext
)
613 DbgPrint("ExpUnhandledException1() called\n");
614 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
615 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
616 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
617 DbgPrint("Context 0x%X\n", Context
);
618 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
620 Context
->Eax
= (ULONG
)&Scratch
;
622 return ExceptionContinueExecution
;
626 EXCEPTION_DISPOSITION
627 ExpUnhandledException2(
628 PEXCEPTION_RECORD ExceptionRecord
,
629 PEXCEPTION_REGISTRATION ExceptionRegistration
,
631 PVOID DispatcherContext
)
633 DbgPrint("ExpUnhandledException2() called\n");
634 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
635 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
636 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
637 DbgPrint("Context 0x%X\n", Context
);
638 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
641 Context
->Eax
= (ULONG
)&Scratch
;
643 return ExceptionContinueExecution
;
647 return ExceptionContinueSearch
;
654 // Put in mingw headers
658 PEXCEPTION_REGISTRATION RegistrationFrame
,
664 PVOID RegistrationFrame
);
666 extern EXCEPTION_DISPOSITION
669 PEXCEPTION_RECORD ExceptionRecord
,
670 PEXCEPTION_REGISTRATION RegistrationFrame
,
672 PVOID DispatcherContext
);
674 extern EXCEPTION_DISPOSITION
677 PEXCEPTION_RECORD ExceptionRecord
,
678 PEXCEPTION_REGISTRATION RegistrationFrame
,
680 PVOID DispatcherContext
);
684 PRTL_EXCEPTION_REGISTRATION
689 __asm__("movl %%ebp, %0\n\t" : "=a" (Value
));
691 return((PRTL_EXCEPTION_REGISTRATION
)Value
) - 1;
695 PRTL_EXCEPTION_REGISTRATION TestER
;
696 SCOPETABLE_ENTRY ScopeTable
;
697 PEXCEPTION_REGISTRATION OSPtr
;
700 DWORD CDECL
SEHFilterRoutine(VOID
)
702 DbgPrint("Within filter routine.\n");
703 return EXCEPTION_EXECUTE_HANDLER
;
704 //return EXCEPTION_CONTINUE_EXECUTION;
707 VOID CDECL
SEHHandlerRoutine(VOID
)
709 DbgPrint("Within exception handler.\n");
710 DbgPrint("System halted.\n");
717 RTL_EXCEPTION_REGISTRATION ER
;
718 LPEXCEPTION_POINTERS ExceptionPointers
;
719 PVOID StandardESPInFrame
;
721 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame
));
722 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame
);
724 ExceptionPointers
= NULL
;
726 ER
.OS
.handler
= _except_handler3
;
727 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER
.OS
.prev
));
728 DbgPrint("ER.OS.prev: 0x%X\n", ER
.OS
.prev
);
730 ER
.ScopeTable
= &ScopeTable
;
731 DbgPrint("ER.ScopeTable: 0x%X\n", ER
.ScopeTable
);
733 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER
.Ebp
));
734 DbgPrint("ER.Ebp: 0x%X\n", ER
.Ebp
);
736 ScopeTable
.PreviousTryLevel
= -1;
737 ScopeTable
.FilterRoutine
= SEHFilterRoutine
;
738 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable
.FilterRoutine
);
739 ScopeTable
.HandlerRoutine
= SEHHandlerRoutine
;
740 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable
.HandlerRoutine
);
744 DbgPrint("OSPtr: 0x%X\n", OSPtr
);
746 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr
));
748 /*__try1(__except_handler3)*/ if(1) {
749 ER
.TryLevel
= 0; // Entered first try... block
751 DbgPrint("Within guarded section.\n");
752 x
= (PULONG
)0xf2000000; *x
= 0;
753 DbgPrint("After exception.\n");
754 } /* __except1 */ if(0) {
757 DbgPrint("After exception2.\n");
759 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER
.OS
.prev
));
760 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
762 DbgPrint("Exiting.\n");
768 ExpInitializeExecutive(VOID
)
777 * Fail at runtime if someone has changed various structures without
778 * updating the offsets used for the assembler code.
780 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
781 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
782 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
783 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
784 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
785 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
786 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
787 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
788 KPROCESS_DIRECTORY_TABLE_BASE
);
789 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
790 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
791 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
793 assert(FIELD_OFFSET(KPCR
, ExceptionList
) == KPCR_EXCEPTION_LIST
);
794 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
795 assert(FIELD_OFFSET(KPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
799 KeLowerIrql(DISPATCH_LEVEL
);
803 MmInit1(FirstKrnlPhysAddr
,
806 (PADDRESS_RANGE
)&KeMemoryMap
,
807 KeMemoryMapRangeCount
);
809 /* create default nls tables */
813 * Initialize the kernel debugger
815 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
820 KeLowerIrql(PASSIVE_LEVEL
);
823 KeBugCheck(SECURITY_INITIALIZATION_FAILED
);
826 PiInitProcessManager();
830 if (KdPollBreakIn ())
832 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
836 * Display version number and copyright/warranty message
838 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
839 KERNEL_VERSION_BUILD_STR
")\n");
840 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
841 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
842 "Public License, and you\n");
843 HalDisplayString("are welcome to change it and/or distribute copies of it "
845 HalDisplayString("conditions. There is absolutely no warranty for "
848 /* Initialize all processors */
849 KeNumberProcessors
= 0;
851 while (!HalAllProcessorsStarted())
853 PVOID ProcessorStack
;
855 if (KeNumberProcessors
!= 0)
857 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
858 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
860 /* Allocate a stack for use when booting the processor */
861 /* FIXME: The nonpaged memory for the stack is not released after use */
863 ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
864 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
865 (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
866 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
867 KeNumberProcessors
++;
870 if (KeNumberProcessors
> 1)
873 "Found %d system processors. [%lu MB Memory]\n",
875 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
880 "Found 1 system processor. [%lu MB Memory]\n",
881 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
883 HalDisplayString(str
);
886 * Initialize various critical subsystems
888 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
893 LdrInitModuleManagement();
894 CmInitializeRegistry();
900 /* Report all resources used by hal */
901 HalReportResourceUsage();
904 * Initalize services loaded at boot time
906 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
907 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
909 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
910 KeLoaderModules
[i
].String
,
911 KeLoaderModules
[i
].ModStart
,
912 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
915 /* Pass 1: load nls files */
916 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
918 name
= (PCHAR
)KeLoaderModules
[i
].String
;
919 if (RtlpCheckFileNameExtension(name
, ".nls"))
926 name
= (PCHAR
)KeLoaderModules
[i
+1].String
;
927 if (RtlpCheckFileNameExtension(name
, ".nls"))
929 Mod2Start
= (ULONG
)KeLoaderModules
[i
+1].ModStart
;
930 Mod2End
= (ULONG
)KeLoaderModules
[i
+1].ModEnd
;
932 name
= (PCHAR
)KeLoaderModules
[i
+2].String
;
933 if (RtlpCheckFileNameExtension(name
, ".nls"))
935 Mod3Start
= (ULONG
)KeLoaderModules
[i
+2].ModStart
;
936 Mod3End
= (ULONG
)KeLoaderModules
[i
+2].ModEnd
;
940 /* Initialize nls sections */
941 RtlpInitNlsSections((ULONG
)KeLoaderModules
[i
].ModStart
,
942 (ULONG
)KeLoaderModules
[i
].ModEnd
,
951 /* Pass 2: load registry chunks passed in */
952 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
954 start
= KeLoaderModules
[i
].ModStart
;
955 length
= KeLoaderModules
[i
].ModEnd
- start
;
956 name
= (PCHAR
)KeLoaderModules
[i
].String
;
957 if (RtlpCheckFileNameExtension(name
, "") ||
958 RtlpCheckFileNameExtension(name
, ".hiv"))
960 CPRINT("Process registry chunk at %08lx\n", start
);
961 CmImportHive((PCHAR
)start
, length
);
966 * Enter the kernel debugger before starting up the boot drivers
972 /* Pass 3: process boot loaded drivers */
973 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
975 start
= KeLoaderModules
[i
].ModStart
;
976 length
= KeLoaderModules
[i
].ModEnd
- start
;
977 name
= (PCHAR
)KeLoaderModules
[i
].String
;
978 if (RtlpCheckFileNameExtension(name
, ".sys") ||
979 RtlpCheckFileNameExtension(name
, ".sym"))
981 CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
982 name
, start
, length
);
983 LdrProcessDriver((PVOID
)start
, name
, length
);
987 /* Create ARC names for boot devices */
990 /* Create the SystemRoot symbolic link */
991 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
992 IoCreateSystemRootLink((PUCHAR
)KeLoaderBlock
.CommandLine
);
994 #ifdef DBGPRINT_FILE_LOG
995 /* On the assumption that we can now access disks start up the debug
998 #endif /* DBGPRINT_FILE_LOG */
1002 CreateDefaultRegistry();
1005 PiInitDefaultLocale();
1008 * Start the motherboard enumerator (the HAL)
1010 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1013 * Load boot start drivers
1015 IopLoadBootStartDrivers();
1018 * Load Auto configured drivers
1020 LdrLoadAutoConfigDrivers();
1023 * Assign drive letters
1025 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
1031 * Initialize shared user page:
1032 * - set dos system path, dos device map, etc.
1034 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
1037 KeBugCheck(SECURITY1_INITIALIZATION_FAILED
);
1040 * Launch initial process
1042 LdrLoadInitialProcess();
1044 PsTerminateSystemThread(STATUS_SUCCESS
);
1049 KiSystemStartup(BOOLEAN BootProcessor
)
1051 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1056 ExpInitializeExecutive();
1059 /* Do application processor initialization */
1060 KeApplicationProcessorInit();
1061 PsApplicationProcessorInit();
1062 KeLowerIrql(PASSIVE_LEVEL
);
1063 PsIdleThreadMain(NULL
);
1069 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
1071 * FUNCTION: Called by the boot loader to start the kernel
1073 * LoaderBlock = Pointer to boot parameters initialized by the boot
1075 * NOTE: The boot parameters are stored in low memory which will become
1076 * invalid after the memory managment is initialized so we make a local copy.
1081 ULONG last_kernel_address
;
1082 extern ULONG _bss_end__
;
1087 /* Low level architecture specific initialization */
1091 * Copy the parameters to a local buffer because lowmem will go away
1093 memcpy(&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
1094 memcpy(&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
1095 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
1096 KeLoaderBlock
.ModsCount
++;
1097 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
1099 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[0] == '(')
1101 ULONG DiskNumber
, PartNumber
;
1107 if (((PUCHAR
)_LoaderBlock
->CommandLine
)[1] == 'h' &&
1108 ((PUCHAR
)_LoaderBlock
->CommandLine
)[2] == 'd')
1110 DiskNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[3] - '0';
1111 PartNumber
= ((PUCHAR
)_LoaderBlock
->CommandLine
)[5] - '0';
1113 strcpy(Temp
, &((PUCHAR
)_LoaderBlock
->CommandLine
)[7]);
1114 if ((options
= strchr(Temp
, ' ')) != NULL
)
1123 if ((s1
= strrchr(Temp
, '/')) != NULL
)
1126 if ((s1
= strrchr(Temp
, '/')) != NULL
)
1131 sprintf(KeLoaderCommandLine
,
1132 "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s",
1133 DiskNumber
, PartNumber
+ 1, Temp
, options
);
1135 p
= KeLoaderCommandLine
;
1136 while (*p
!= 0 && *p
!= ' ')
1144 DPRINT1("Command Line: %s\n", KeLoaderCommandLine
);
1148 strcpy(KeLoaderCommandLine
, (PUCHAR
)_LoaderBlock
->CommandLine
);
1150 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
1152 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
1153 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
1154 KeLoaderModules
[0].ModStart
= 0xC0000000;
1155 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
1156 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1158 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
1159 KeLoaderModules
[i
].ModStart
-= 0x200000;
1160 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
1161 KeLoaderModules
[i
].ModEnd
-= 0x200000;
1162 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
1163 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
1167 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1170 HalBase
= KeLoaderModules
[1].ModStart
;
1172 PAGE_ROUND_UP(KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
);
1177 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
1179 LdrHalBase
= (ULONG_PTR
)DriverBase
;
1180 last_kernel_address
= DriverBase
+ DriverSize
;
1183 * Process ntoskrnl.exe
1185 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
1187 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
1188 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
1189 LastKernelAddress
= last_kernel_address
;
1192 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
1193 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
1196 KeMemoryMapRangeCount
= 0;
1197 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
1199 /* We have a memory map from the nice BIOS */
1200 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
1202 while (i
< KeLoaderBlock
.MmapLength
)
1204 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
1205 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
1206 sizeof(ADDRESS_RANGE
));
1207 KeMemoryMapRangeCount
++;