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.114 2002/02/20 20:14:22 ekohl 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 <napi/shared_data.h>
45 #include <internal/v86m.h>
46 #include <internal/kd.h>
47 #include <internal/trap.h>
48 #include "../dbg/kdb.h"
49 #include <internal/registry.h>
50 #include <reactos/bugcodes.h>
53 #include <internal/ntosdbg.h>
59 #include <internal/debug.h>
61 /* GLOBALS *******************************************************************/
63 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
64 ULONG EXPORTED NtGlobalFlag
= 0;
65 CHAR EXPORTED KeNumberProcessors
;
66 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
67 static LOADER_MODULE KeLoaderModules
[64];
68 static UCHAR KeLoaderModuleStrings
[64][256];
69 static UCHAR KeLoaderCommandLine
[256];
70 static ADDRESS_RANGE KeMemoryMap
[64];
71 static ULONG KeMemoryMapRangeCount
;
72 static ULONG FirstKrnlPhysAddr
;
73 static ULONG LastKrnlPhysAddr
;
74 static ULONG LastKernelAddress
;
75 volatile BOOLEAN Initialized
= FALSE
;
77 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
88 SERVICE Services
[] = {
89 {L
"pci", L
"PCI Bus Driver", L
"Boot Bus Extender", 0, 1},
90 {L
"keyboard", L
"Standard Keyboard Driver", L
"Base", 0, 1},
91 {L
"blue", L
"Bluescreen Driver", L
"Base", 0, 1},
92 {L
"vidport", L
"Video Port Driver", L
"Base", 0, 1},
93 {L
"vgamp", L
"VGA Miniport", L
"Base", 0, 1},
94 {L
"minixfs", L
"Minix File System", L
"File system", 0, 1},
95 {L
"msfs", L
"Mail Slot File System", L
"File system", 0, 1},
96 {L
"npfs", L
"Named Pipe File System", L
"File system", 0, 1},
97 {L
"psaux", L
"PS/2 Auxillary Port Driver", L
"", 0, 1},
98 {L
"mouclass", L
"Mouse Class Driver", L
"Pointer Class", 0, 1},
99 {L
"ndis", L
"NDIS System Driver", L
"NDIS Wrapper", 0, 1},
100 {L
"ne2000", L
"Novell Eagle 2000 Driver", L
"NDIS", 0, 1},
101 {L
"afd", L
"AFD Networking Support Environment", L
"TDI", 0, 1},
105 /* FUNCTIONS ****************************************************************/
109 VOID
CreateDefaultRegistryForLegacyDriver(
113 WCHAR LegacyDriver
[] = L
"LegacyDriver";
115 WCHAR InstancePath
[MAX_PATH
];
116 WCHAR KeyNameBuffer
[MAX_PATH
];
117 WCHAR Name
[MAX_PATH
];
118 UNICODE_STRING KeyName
;
125 WCHAR ImagePath
[MAX_PATH
];
128 wcscpy(Name
, Service
->ServiceName
);
130 wcscpy(InstancePath
, L
"Root\\LEGACY_");
131 wcscat(InstancePath
, Name
);
132 wcscat(InstancePath
, L
"\\0000");
134 wcscpy(KeyNameBuffer
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
135 wcscat(KeyNameBuffer
, InstancePath
);
137 RtlInitUnicodeString(&KeyName
, KeyNameBuffer
);
139 DPRINT("Key name is %S\n", KeyName
.Buffer
);
141 Status
= RtlpCreateRegistryKeyPath(KeyName
.Buffer
);
142 if (!NT_SUCCESS(Status
))
144 DPRINT1("RtlpCreateRegistryKeyPath() failed with status %x\n", Status
);
148 Status
= RtlpGetRegistryHandle(
153 if (!NT_SUCCESS(Status
))
155 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
160 Length
= sizeof(DWORD
);
161 Status
= RtlWriteRegistryValue(
168 if (!NT_SUCCESS(Status
))
170 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
175 Length
= (wcslen(LegacyDriver
) + 1) * sizeof(WCHAR
);
176 Status
= RtlWriteRegistryValue(
183 if (!NT_SUCCESS(Status
))
185 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
190 Length
= (wcslen(Service
->DeviceDesc
) + 1) * sizeof(WCHAR
);
191 Status
= RtlWriteRegistryValue(
198 if (!NT_SUCCESS(Status
))
200 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
206 Length
= Length
= sizeof(DWORD
);
207 Status
= RtlWriteRegistryValue(
214 if (!NT_SUCCESS(Status
))
216 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
221 Length
= (wcslen(Service
->ServiceName
) + 1) * sizeof(WCHAR
);
222 Status
= RtlWriteRegistryValue(
227 Service
->ServiceName
,
229 if (!NT_SUCCESS(Status
))
231 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
239 /* Services section */
241 Status
= RtlpGetRegistryHandle(
242 RTL_REGISTRY_SERVICES
,
243 Service
->ServiceName
,
246 if (!NT_SUCCESS(Status
))
248 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
252 Length
= (wcslen(Service
->DeviceDesc
) + 1) * sizeof(WCHAR
);
253 Status
= RtlWriteRegistryValue(
260 if (!NT_SUCCESS(Status
))
262 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
268 Length
= sizeof(DWORD
);
269 Status
= RtlWriteRegistryValue(
276 if (!NT_SUCCESS(Status
))
278 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
283 Length
= (wcslen(Service
->Group
) + 1) * sizeof(WCHAR
);
284 Status
= RtlWriteRegistryValue(
291 if (!NT_SUCCESS(Status
))
293 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
298 wcscpy(ImagePath
, L
"\\SystemRoot\\System32\\drivers\\");
299 wcscat(ImagePath
, Service
->ServiceName
);
300 wcscat(ImagePath
, L
".sys");
302 Length
= (wcslen(ImagePath
) + 1) * sizeof(WCHAR
);
303 Status
= RtlWriteRegistryValue(
310 if (!NT_SUCCESS(Status
))
312 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
317 DwordData
= Service
->Start
;
318 Length
= sizeof(DWORD
);
319 Status
= RtlWriteRegistryValue(
326 if (!NT_SUCCESS(Status
))
328 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
333 DwordData
= Service
->Type
;
334 Length
= sizeof(DWORD
);
335 Status
= RtlWriteRegistryValue(
342 if (!NT_SUCCESS(Status
))
344 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
352 VOID
CreateDefaultRegistry()
357 Status
= RtlpCreateRegistryKeyPath(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
358 if (!NT_SUCCESS(Status
))
360 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status
);
364 Status
= RtlpCreateRegistryKeyPath(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
365 if (!NT_SUCCESS(Status
))
367 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status
);
371 for (i
= 0; Services
[i
].ServiceName
!= NULL
; i
++)
373 CreateDefaultRegistryForLegacyDriver(&Services
[i
]);
379 RtlpCheckFileNameExtension(PCHAR FileName
,
384 Ext
= strrchr(FileName
, '.');
385 if ((Extension
== NULL
) || (*Extension
== 0))
392 if (*Extension
!= '.')
395 if (_stricmp(Ext
, Extension
) == 0)
402 CreateSystemRootLink (PCSZ ParameterLine
)
404 UNICODE_STRING LinkName
;
405 UNICODE_STRING DeviceName
;
406 UNICODE_STRING ArcName
;
407 UNICODE_STRING BootPath
;
409 PWCHAR ArcNameBuffer
;
413 OBJECT_ATTRIBUTES ObjectAttributes
;
416 /* create local parameter line copy */
417 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
418 strcpy (ParamBuffer
, (char *)ParameterLine
);
420 DPRINT("%s\n", ParamBuffer
);
421 /* Format: <arc_name>\<path> [options...] */
423 /* cut options off */
424 p
= strchr (ParamBuffer
, ' ');
427 DPRINT("%s\n", ParamBuffer
);
430 p
= strchr (ParamBuffer
, '\\');
433 DPRINT("Boot path: %s\n", p
);
434 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
439 DPRINT("Boot path: %s\n", "\\");
440 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
442 DPRINT("Arc name: %s\n", ParamBuffer
);
444 /* Only arc name left - build full arc name */
445 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
446 swprintf (ArcNameBuffer
,
447 L
"\\ArcName\\%S", ParamBuffer
);
448 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
449 DPRINT("Arc name: %wZ\n", &ArcName
);
451 /* free ParamBuffer */
452 ExFreePool (ParamBuffer
);
454 /* allocate device name string */
455 DeviceName
.Length
= 0;
456 DeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
457 DeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
459 InitializeObjectAttributes (&ObjectAttributes
,
465 Status
= NtOpenSymbolicLinkObject (&Handle
,
466 SYMBOLIC_LINK_ALL_ACCESS
,
468 if (!NT_SUCCESS(Status
))
470 RtlFreeUnicodeString (&BootPath
);
471 RtlFreeUnicodeString (&DeviceName
);
472 DPRINT1("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
475 RtlFreeUnicodeString (&ArcName
);
479 RtlFreeUnicodeString (&ArcName
);
481 Status
= NtQuerySymbolicLinkObject (Handle
,
485 if (!NT_SUCCESS(Status
))
487 RtlFreeUnicodeString (&BootPath
);
488 RtlFreeUnicodeString (&DeviceName
);
489 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
494 DPRINT("Length: %lu DeviceName: %wZ\n", Length
, &DeviceName
);
496 RtlAppendUnicodeStringToString (&DeviceName
,
499 RtlFreeUnicodeString (&BootPath
);
500 DPRINT("DeviceName: %wZ\n", &DeviceName
);
502 /* create the '\SystemRoot' link */
503 RtlInitUnicodeString (&LinkName
,
506 Status
= IoCreateSymbolicLink (&LinkName
,
508 RtlFreeUnicodeString (&DeviceName
);
509 if (!NT_SUCCESS(Status
))
511 CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
517 /* Check if '\SystemRoot'(LinkName) can be opened, otherwise crash it! */
518 InitializeObjectAttributes (&ObjectAttributes
,
524 Status
= NtOpenSymbolicLinkObject (&Handle
,
525 SYMBOLIC_LINK_ALL_ACCESS
,
527 if (!NT_SUCCESS(Status
))
529 CPRINT("NtOpenSymbolicLinkObject() failed to open '\\SystemRoot' (Status %x)\n",
538 InitSystemSharedUserPage (PCSZ ParameterLine
)
540 PKUSER_SHARED_DATA SharedPage
;
542 UNICODE_STRING ArcDeviceName
;
543 UNICODE_STRING ArcName
;
544 UNICODE_STRING BootPath
;
545 UNICODE_STRING DriveDeviceName
;
546 UNICODE_STRING DriveName
;
547 WCHAR DriveNameBuffer
[20];
549 PWCHAR ArcNameBuffer
;
553 OBJECT_ATTRIBUTES ObjectAttributes
;
556 BOOLEAN BootDriveFound
;
558 SharedPage
= (PKUSER_SHARED_DATA
)KERNEL_SHARED_DATA_BASE
;
559 SharedPage
->DosDeviceMap
= 0;
560 SharedPage
->NtProductType
= NtProductWinNt
;
561 for (i
= 0; i
< 32; i
++)
563 SharedPage
->DosDeviceDriveType
[i
] = 0;
566 BootDriveFound
= FALSE
;
569 * Retrieve the current dos system path
570 * (e.g.: C:\reactos) from the given arc path
571 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
572 * Format: "<arc_name>\<path> [options...]"
575 /* create local parameter line copy */
576 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
577 strcpy (ParamBuffer
, (char *)ParameterLine
);
578 DPRINT("%s\n", ParamBuffer
);
580 /* cut options off */
581 p
= strchr (ParamBuffer
, ' ');
586 DPRINT("%s\n", ParamBuffer
);
589 p
= strchr (ParamBuffer
, '\\');
592 DPRINT("Boot path: %s\n", p
);
593 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
598 DPRINT("Boot path: %s\n", "\\");
599 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
601 DPRINT("Arc name: %s\n", ParamBuffer
);
603 /* Only arc name left - build full arc name */
604 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
605 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
606 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
607 DPRINT("Arc name: %wZ\n", &ArcName
);
609 /* free ParamBuffer */
610 ExFreePool (ParamBuffer
);
612 /* allocate arc device name string */
613 ArcDeviceName
.Length
= 0;
614 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
615 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
617 InitializeObjectAttributes (&ObjectAttributes
,
623 Status
= NtOpenSymbolicLinkObject (&Handle
,
624 SYMBOLIC_LINK_ALL_ACCESS
,
626 RtlFreeUnicodeString (&ArcName
);
627 if (!NT_SUCCESS(Status
))
629 RtlFreeUnicodeString (&BootPath
);
630 RtlFreeUnicodeString (&ArcDeviceName
);
631 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
637 Status
= NtQuerySymbolicLinkObject (Handle
,
641 if (!NT_SUCCESS(Status
))
643 RtlFreeUnicodeString (&BootPath
);
644 RtlFreeUnicodeString (&ArcDeviceName
);
645 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
650 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
653 /* allocate device name string */
654 DriveDeviceName
.Length
= 0;
655 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
656 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
658 for (i
= 0; i
< 26; i
++)
660 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
661 RtlInitUnicodeString (&DriveName
,
664 InitializeObjectAttributes (&ObjectAttributes
,
670 Status
= NtOpenSymbolicLinkObject (&Handle
,
671 SYMBOLIC_LINK_ALL_ACCESS
,
673 if (!NT_SUCCESS(Status
))
675 DPRINT("Failed to open link %wZ\n",
680 Status
= NtQuerySymbolicLinkObject (Handle
,
683 if (!NT_SUCCESS(Status
))
685 DPRINT("Failed query open link %wZ\n",
689 DPRINT("Opened link: %wZ ==> %wZ\n",
690 &DriveName
, &DriveDeviceName
);
692 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
694 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
695 swprintf (SharedPage
->NtSystemRoot
,
696 L
"%C:%wZ", 'A' + i
, &BootPath
);
698 BootDriveFound
= TRUE
;
703 /* set bit in dos drives bitmap (drive available) */
704 SharedPage
->DosDeviceMap
|= (1<<i
);
707 RtlFreeUnicodeString (&BootPath
);
708 RtlFreeUnicodeString (&DriveDeviceName
);
709 RtlFreeUnicodeString (&ArcDeviceName
);
711 DPRINT("DosDeviceMap: 0x%x\n", SharedPage
->DosDeviceMap
);
713 if (BootDriveFound
== FALSE
)
715 DbgPrint("No system drive found!\n");
722 VOID
DumpBIOSMemoryMap(VOID
)
726 DbgPrint("Dumping BIOS memory map:\n");
727 DbgPrint("Memory map base: %d\n", KeLoaderBlock
.MmapAddr
);
728 DbgPrint("Memory map size: %d\n", KeLoaderBlock
.MmapLength
);
729 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount
);
730 for (i
= 0; i
< KeMemoryMapRangeCount
; i
++)
732 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
733 KeMemoryMap
[i
].BaseAddrLow
,
734 KeMemoryMap
[i
].LengthLow
,
735 KeMemoryMap
[i
].Type
);
745 static ULONG Scratch
;
747 EXCEPTION_DISPOSITION
748 ExpUnhandledException1(
749 PEXCEPTION_RECORD ExceptionRecord
,
750 PEXCEPTION_REGISTRATION ExceptionRegistration
,
752 PVOID DispatcherContext
)
754 DbgPrint("ExpUnhandledException1() called\n");
755 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
756 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
757 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
758 DbgPrint("Context 0x%X\n", Context
);
759 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
761 Context
->Eax
= (ULONG
)&Scratch
;
763 return ExceptionContinueExecution
;
767 EXCEPTION_DISPOSITION
768 ExpUnhandledException2(
769 PEXCEPTION_RECORD ExceptionRecord
,
770 PEXCEPTION_REGISTRATION ExceptionRegistration
,
772 PVOID DispatcherContext
)
774 DbgPrint("ExpUnhandledException2() called\n");
775 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
776 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
777 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
778 DbgPrint("Context 0x%X\n", Context
);
779 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
782 Context
->Eax
= (ULONG
)&Scratch
;
784 return ExceptionContinueExecution
;
788 return ExceptionContinueSearch
;
795 // Put in mingw headers
799 PEXCEPTION_REGISTRATION RegistrationFrame
,
805 PVOID RegistrationFrame
);
807 extern EXCEPTION_DISPOSITION
810 PEXCEPTION_RECORD ExceptionRecord
,
811 PEXCEPTION_REGISTRATION RegistrationFrame
,
813 PVOID DispatcherContext
);
815 extern EXCEPTION_DISPOSITION
818 PEXCEPTION_RECORD ExceptionRecord
,
819 PEXCEPTION_REGISTRATION RegistrationFrame
,
821 PVOID DispatcherContext
);
825 PRTL_EXCEPTION_REGISTRATION
830 __asm__("movl %%ebp, %0\n\t" : "=a" (Value
));
832 return((PRTL_EXCEPTION_REGISTRATION
)Value
) - 1;
836 PRTL_EXCEPTION_REGISTRATION TestER
;
837 SCOPETABLE_ENTRY ScopeTable
;
838 PEXCEPTION_REGISTRATION OSPtr
;
841 DWORD CDECL
SEHFilterRoutine(VOID
)
843 DbgPrint("Within filter routine.\n");
844 return EXCEPTION_EXECUTE_HANDLER
;
845 //return EXCEPTION_CONTINUE_EXECUTION;
848 VOID CDECL
SEHHandlerRoutine(VOID
)
850 DbgPrint("Within exception handler.\n");
851 DbgPrint("System halted.\n");
858 RTL_EXCEPTION_REGISTRATION ER
;
859 LPEXCEPTION_POINTERS ExceptionPointers
;
860 PVOID StandardESPInFrame
;
862 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame
));
863 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame
);
865 ExceptionPointers
= NULL
;
867 ER
.OS
.handler
= _except_handler3
;
868 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER
.OS
.prev
));
869 DbgPrint("ER.OS.prev: 0x%X\n", ER
.OS
.prev
);
871 ER
.ScopeTable
= &ScopeTable
;
872 DbgPrint("ER.ScopeTable: 0x%X\n", ER
.ScopeTable
);
874 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER
.Ebp
));
875 DbgPrint("ER.Ebp: 0x%X\n", ER
.Ebp
);
877 ScopeTable
.PreviousTryLevel
= -1;
878 ScopeTable
.FilterRoutine
= SEHFilterRoutine
;
879 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable
.FilterRoutine
);
880 ScopeTable
.HandlerRoutine
= SEHHandlerRoutine
;
881 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable
.HandlerRoutine
);
885 DbgPrint("OSPtr: 0x%X\n", OSPtr
);
887 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr
));
889 /*__try1(__except_handler3)*/ if(1) {
890 ER
.TryLevel
= 0; // Entered first try... block
892 DbgPrint("Within guarded section.\n");
893 x
= (PULONG
)0xf2000000; *x
= 0;
894 DbgPrint("After exception.\n");
895 } /* __except1 */ if(0) {
898 DbgPrint("After exception2.\n");
900 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER
.OS
.prev
));
901 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
903 DbgPrint("Exiting.\n");
909 ExpInitializeExecutive(VOID
)
918 * Fail at runtime if someone has changed various structures without
919 * updating the offsets used for the assembler code.
921 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
922 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
923 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
924 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
925 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
926 assert(FIELD_OFFSET(KTHREAD
, CallbackStack
) == KTHREAD_CALLBACK_STACK
);
927 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
928 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
929 KPROCESS_DIRECTORY_TABLE_BASE
);
930 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
931 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
932 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
934 assert(FIELD_OFFSET(KPCR
, ExceptionList
) == KPCR_EXCEPTION_LIST
);
935 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
936 assert(FIELD_OFFSET(KPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
940 KeLowerIrql(DISPATCH_LEVEL
);
944 MmInit1(FirstKrnlPhysAddr
,
947 (PADDRESS_RANGE
)&KeMemoryMap
,
948 KeMemoryMapRangeCount
);
950 /* create default nls tables */
954 * Initialize the kernel debugger
956 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
961 KeLowerIrql(PASSIVE_LEVEL
);
964 KeBugCheck(SECURITY_INITIALIZATION_FAILED
);
967 PiInitProcessManager();
971 if (KdPollBreakIn ())
973 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
977 * Display version number and copyright/warranty message
979 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
980 KERNEL_VERSION_BUILD_STR
")\n");
981 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
982 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
983 "Public License, and you\n");
984 HalDisplayString("are welcome to change it and/or distribute copies of it "
986 HalDisplayString("conditions. There is absolutely no warranty for "
989 /* Initialize all processors */
990 KeNumberProcessors
= 0;
992 while (!HalAllProcessorsStarted())
994 PVOID ProcessorStack
;
996 if (KeNumberProcessors
!= 0)
998 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
999 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
1001 /* Allocate a stack for use when booting the processor */
1002 /* FIXME: The nonpaged memory for the stack is not released after use */
1004 ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
1005 Ki386InitialStackArray
[((int)KeNumberProcessors
)] =
1006 (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
1007 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
1008 KeNumberProcessors
++;
1011 if (KeNumberProcessors
> 1)
1014 "Found %d system processors. [%lu MB Memory]\n",
1016 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
1021 "Found 1 system processor. [%lu MB Memory]\n",
1022 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
1024 HalDisplayString(str
);
1027 * Initialize various critical subsystems
1029 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1034 LdrInitModuleManagement();
1035 CmInitializeRegistry();
1041 /* Report all resources used by hal */
1042 HalReportResourceUsage();
1045 * Initalize services loaded at boot time
1047 DPRINT("%d files loaded\n",KeLoaderBlock
.ModsCount
);
1048 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
1050 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
1051 KeLoaderModules
[i
].String
,
1052 KeLoaderModules
[i
].ModStart
,
1053 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
1056 /* Pass 1: load nls files */
1057 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1059 name
= (PCHAR
)KeLoaderModules
[i
].String
;
1060 if (RtlpCheckFileNameExtension(name
, ".nls"))
1062 ULONG Mod2Start
= 0;
1064 ULONG Mod3Start
= 0;
1067 name
= (PCHAR
)KeLoaderModules
[i
+1].String
;
1068 if (RtlpCheckFileNameExtension(name
, ".nls"))
1070 Mod2Start
= (ULONG
)KeLoaderModules
[i
+1].ModStart
;
1071 Mod2End
= (ULONG
)KeLoaderModules
[i
+1].ModEnd
;
1073 name
= (PCHAR
)KeLoaderModules
[i
+2].String
;
1074 if (RtlpCheckFileNameExtension(name
, ".nls"))
1076 Mod3Start
= (ULONG
)KeLoaderModules
[i
+2].ModStart
;
1077 Mod3End
= (ULONG
)KeLoaderModules
[i
+2].ModEnd
;
1081 /* Initialize nls sections */
1082 RtlpInitNlsSections((ULONG
)KeLoaderModules
[i
].ModStart
,
1083 (ULONG
)KeLoaderModules
[i
].ModEnd
,
1092 /* Pass 2: load registry chunks passed in */
1093 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1095 start
= KeLoaderModules
[i
].ModStart
;
1096 length
= KeLoaderModules
[i
].ModEnd
- start
;
1097 name
= (PCHAR
)KeLoaderModules
[i
].String
;
1098 if (RtlpCheckFileNameExtension(name
, "") ||
1099 RtlpCheckFileNameExtension(name
, ".hiv"))
1101 CPRINT("Process registry chunk at %08lx\n", start
);
1102 CmImportHive((PCHAR
)start
, length
);
1107 * Enter the kernel debugger before starting up the boot drivers
1113 /* Pass 3: process boot loaded drivers */
1114 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
1116 start
= KeLoaderModules
[i
].ModStart
;
1117 length
= KeLoaderModules
[i
].ModEnd
- start
;
1118 name
= (PCHAR
)KeLoaderModules
[i
].String
;
1119 if (RtlpCheckFileNameExtension(name
, ".sys") ||
1120 RtlpCheckFileNameExtension(name
, ".sym"))
1122 CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
1123 name
, start
, length
);
1124 LdrProcessDriver((PVOID
)start
, name
, length
);
1128 /* Create the SystemRoot symbolic link */
1129 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
1131 CreateSystemRootLink ((PUCHAR
)KeLoaderBlock
.CommandLine
);
1133 #ifdef DBGPRINT_FILE_LOG
1134 /* On the assumption that we can now access disks start up the debug
1137 #endif /* DBGPRINT_FILE_LOG */
1140 CmInitializeRegistry2();
1143 CreateDefaultRegistry();
1146 PiInitDefaultLocale();
1149 * Start the motherboard enumerator (the HAL)
1151 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1154 * Load boot start drivers
1156 IopLoadBootStartDrivers();
1159 * Load Auto configured drivers
1161 LdrLoadAutoConfigDrivers();
1164 * Assign drive letters
1166 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
1172 * Initialize shared user page:
1173 * - set dos system path, dos device map, etc.
1175 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
1178 KeBugCheck(SECURITY1_INITIALIZATION_FAILED
);
1181 * Launch initial process
1183 LdrLoadInitialProcess();
1185 PsTerminateSystemThread(STATUS_SUCCESS
);
1190 KiSystemStartup(BOOLEAN BootProcessor
)
1192 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1197 ExpInitializeExecutive();
1200 /* Do application processor initialization */
1201 KeApplicationProcessorInit();
1202 PsApplicationProcessorInit();
1203 KeLowerIrql(PASSIVE_LEVEL
);
1204 PsIdleThreadMain(NULL
);
1210 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
1212 * FUNCTION: Called by the boot loader to start the kernel
1214 * LoaderBlock = Pointer to boot parameters initialized by the boot
1216 * NOTE: The boot parameters are stored in low memory which will become
1217 * invalid after the memory managment is initialized so we make a local copy.
1222 ULONG last_kernel_address
;
1223 extern ULONG _bss_end__
;
1228 /* Low level architecture specific initialization */
1232 * Copy the parameters to a local buffer because lowmem will go away
1234 memcpy (&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
1235 memcpy (&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
1236 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
1237 KeLoaderBlock
.ModsCount
++;
1238 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
1241 * FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
1242 * This should be done by the boot loader.
1244 strcpy (KeLoaderCommandLine
,
1245 "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
1246 strcat (KeLoaderCommandLine
, (PUCHAR
)KeLoaderBlock
.CommandLine
);
1248 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
1249 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
1250 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
1251 KeLoaderModules
[0].ModStart
= 0xC0000000;
1252 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
1253 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1255 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
1256 KeLoaderModules
[i
].ModStart
-= 0x200000;
1257 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
1258 KeLoaderModules
[i
].ModEnd
-= 0x200000;
1259 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
1260 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
1264 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1267 HalBase
= KeLoaderModules
[1].ModStart
;
1268 DriverBase
= KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
;
1273 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
1275 LdrHalBase
= (ULONG_PTR
)DriverBase
;
1276 last_kernel_address
= DriverBase
+ DriverSize
;
1279 * Process ntoskrnl.exe
1281 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
1283 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
1284 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
1285 LastKernelAddress
= last_kernel_address
;
1288 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
1289 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
1292 KeMemoryMapRangeCount
= 0;
1293 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
1295 /* We have a memory map from the nice BIOS */
1296 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
1298 while (i
< KeLoaderBlock
.MmapLength
)
1300 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
1301 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
1302 sizeof(ADDRESS_RANGE
));
1303 KeMemoryMapRangeCount
++;