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.108 2001/11/02 09:09:50 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/se.h>
43 #include <napi/shared_data.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>
51 #include <internal/ntosdbg.h>
57 #include <internal/debug.h>
59 /* GLOBALS *******************************************************************/
61 ULONG EXPORTED NtBuildNumber
= KERNEL_VERSION_BUILD
;
62 ULONG EXPORTED NtGlobalFlag
= 0;
63 CHAR EXPORTED KeNumberProcessors
;
64 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock
;
65 static LOADER_MODULE KeLoaderModules
[64];
66 static UCHAR KeLoaderModuleStrings
[64][256];
67 static UCHAR KeLoaderCommandLine
[256];
68 static ADDRESS_RANGE KeMemoryMap
[64];
69 static ULONG KeMemoryMapRangeCount
;
70 static ULONG FirstKrnlPhysAddr
;
71 static ULONG LastKrnlPhysAddr
;
72 static ULONG LastKernelAddress
;
73 volatile BOOLEAN Initialized
= FALSE
;
75 extern PVOID Ki386InitialStackArray
[MAXIMUM_PROCESSORS
];
86 SERVICE Services
[] = {
87 {L
"pci", L
"PCI Bus Driver", L
"Boot Bus Extender", 0, 1},
88 {L
"keyboard", L
"Standard Keyboard Driver", L
"Base", 0, 1},
89 {L
"blue", L
"Bluescreen Driver", L
"Base", 0, 1},
90 /* {L"vidport", L"Video Port Driver", L"Base", 0, 1},
91 {L"vgamp", L"VGA Miniport", L"Base", 0, 1},
92 {L"minixfs", L"Minix File System", L"File system", 0, 1},
93 {L"msfs", L"Mail Slot File System", L"File system", 0, 1},
94 {L"npfs", L"Named Pipe File System", L"File system", 0, 1},
95 {L"psaux", L"PS/2 Auxillary Port Driver", L"", 0, 1},
96 {L"mouclass", L"Mouse Class Driver", L"Pointer Class", 0, 1},
97 {L"ndis", L"NDIS System Driver", L"NDIS Wrapper", 0, 1},
98 {L"ne2000", L"Novell Eagle 2000 Driver", L"NDIS", 0, 1},
99 {L"afd", L"AFD Networking Support Environment", L"TDI", 0, 1},*/
103 /* FUNCTIONS ****************************************************************/
107 VOID
CreateDefaultRegistryForLegacyDriver(
111 WCHAR LegacyDriver
[] = L
"LegacyDriver";
113 WCHAR InstancePath
[MAX_PATH
];
114 WCHAR KeyNameBuffer
[MAX_PATH
];
115 WCHAR Name
[MAX_PATH
];
116 UNICODE_STRING KeyName
;
123 WCHAR ImagePath
[MAX_PATH
];
126 wcscpy(Name
, Service
->ServiceName
);
128 wcscpy(InstancePath
, L
"Root\\LEGACY_");
129 wcscat(InstancePath
, Name
);
130 wcscat(InstancePath
, L
"\\0000");
132 wcscpy(KeyNameBuffer
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
133 wcscat(KeyNameBuffer
, InstancePath
);
135 RtlInitUnicodeString(&KeyName
, KeyNameBuffer
);
137 DPRINT("Key name is %S\n", KeyName
.Buffer
);
139 Status
= RtlpCreateRegistryKeyPath(KeyName
.Buffer
);
140 if (!NT_SUCCESS(Status
))
142 DPRINT1("RtlpCreateRegistryKeyPath() failed with status %x\n", Status
);
146 Status
= RtlpGetRegistryHandle(
151 if (!NT_SUCCESS(Status
))
153 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
158 Length
= sizeof(DWORD
);
159 Status
= RtlWriteRegistryValue(
166 if (!NT_SUCCESS(Status
))
168 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
173 Length
= (wcslen(LegacyDriver
) + 1) * sizeof(WCHAR
);
174 Status
= RtlWriteRegistryValue(
181 if (!NT_SUCCESS(Status
))
183 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
188 Length
= (wcslen(Service
->DeviceDesc
) + 1) * sizeof(WCHAR
);
189 Status
= RtlWriteRegistryValue(
196 if (!NT_SUCCESS(Status
))
198 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
204 Length
= Length
= sizeof(DWORD
);
205 Status
= RtlWriteRegistryValue(
212 if (!NT_SUCCESS(Status
))
214 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
219 Length
= (wcslen(Service
->ServiceName
) + 1) * sizeof(WCHAR
);
220 Status
= RtlWriteRegistryValue(
225 Service
->ServiceName
,
227 if (!NT_SUCCESS(Status
))
229 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
237 /* Services section */
239 Status
= RtlpGetRegistryHandle(
240 RTL_REGISTRY_SERVICES
,
241 Service
->ServiceName
,
244 if (!NT_SUCCESS(Status
))
246 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status
);
250 Length
= (wcslen(Service
->DeviceDesc
) + 1) * sizeof(WCHAR
);
251 Status
= RtlWriteRegistryValue(
258 if (!NT_SUCCESS(Status
))
260 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
266 Length
= sizeof(DWORD
);
267 Status
= RtlWriteRegistryValue(
274 if (!NT_SUCCESS(Status
))
276 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
281 Length
= (wcslen(Service
->Group
) + 1) * sizeof(WCHAR
);
282 Status
= RtlWriteRegistryValue(
289 if (!NT_SUCCESS(Status
))
291 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
296 wcscpy(ImagePath
, L
"\\SystemRoot\\System32\\drivers\\");
297 wcscat(ImagePath
, Service
->ServiceName
);
298 wcscat(ImagePath
, L
".sys");
300 Length
= (wcslen(ImagePath
) + 1) * sizeof(WCHAR
);
301 Status
= RtlWriteRegistryValue(
308 if (!NT_SUCCESS(Status
))
310 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
315 DwordData
= Service
->Start
;
316 Length
= sizeof(DWORD
);
317 Status
= RtlWriteRegistryValue(
324 if (!NT_SUCCESS(Status
))
326 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
331 DwordData
= Service
->Type
;
332 Length
= sizeof(DWORD
);
333 Status
= RtlWriteRegistryValue(
340 if (!NT_SUCCESS(Status
))
342 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status
);
350 VOID
CreateDefaultRegistry()
355 Status
= RtlpCreateRegistryKeyPath(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
356 if (!NT_SUCCESS(Status
))
358 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status
);
362 Status
= RtlpCreateRegistryKeyPath(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
363 if (!NT_SUCCESS(Status
))
365 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status
);
369 for (i
= 0; Services
[i
].ServiceName
!= NULL
; i
++)
371 CreateDefaultRegistryForLegacyDriver(&Services
[i
]);
377 RtlpCheckFileNameExtension(PCHAR FileName
,
382 Ext
= strrchr(FileName
, '.');
383 if ((Extension
== NULL
) || (*Extension
== 0))
390 if (*Extension
!= '.')
393 if (_stricmp(Ext
, Extension
) == 0)
400 CreateSystemRootLink (PCSZ ParameterLine
)
402 UNICODE_STRING LinkName
;
403 UNICODE_STRING DeviceName
;
404 UNICODE_STRING ArcName
;
405 UNICODE_STRING BootPath
;
407 PWCHAR ArcNameBuffer
;
411 OBJECT_ATTRIBUTES ObjectAttributes
;
414 /* create local parameter line copy */
415 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
416 strcpy (ParamBuffer
, (char *)ParameterLine
);
418 DPRINT("%s\n", ParamBuffer
);
419 /* Format: <arc_name>\<path> [options...] */
421 /* cut options off */
422 p
= strchr (ParamBuffer
, ' ');
425 DPRINT("%s\n", ParamBuffer
);
428 p
= strchr (ParamBuffer
, '\\');
431 DPRINT("Boot path: %s\n", p
);
432 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
437 DPRINT("Boot path: %s\n", "\\");
438 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
440 DPRINT("Arc name: %s\n", ParamBuffer
);
442 /* Only arc name left - build full arc name */
443 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
444 swprintf (ArcNameBuffer
,
445 L
"\\ArcName\\%S", ParamBuffer
);
446 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
447 DPRINT1("Arc name: %wZ\n", &ArcName
);
449 /* free ParamBuffer */
450 ExFreePool (ParamBuffer
);
452 /* allocate device name string */
453 DeviceName
.Length
= 0;
454 DeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
455 DeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
457 InitializeObjectAttributes (&ObjectAttributes
,
463 Status
= NtOpenSymbolicLinkObject (&Handle
,
464 SYMBOLIC_LINK_ALL_ACCESS
,
466 if (!NT_SUCCESS(Status
))
468 RtlFreeUnicodeString (&BootPath
);
469 RtlFreeUnicodeString (&DeviceName
);
470 DPRINT1("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
473 RtlFreeUnicodeString (&ArcName
);
477 RtlFreeUnicodeString (&ArcName
);
479 Status
= NtQuerySymbolicLinkObject (Handle
,
483 if (!NT_SUCCESS(Status
))
485 RtlFreeUnicodeString (&BootPath
);
486 RtlFreeUnicodeString (&DeviceName
);
487 DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n",
492 DPRINT("Length: %lu DeviceName: %wZ\n", Length
, &DeviceName
);
494 RtlAppendUnicodeStringToString (&DeviceName
,
497 RtlFreeUnicodeString (&BootPath
);
498 DPRINT("DeviceName: %wZ\n", &DeviceName
);
500 /* create the '\SystemRoot' link */
501 RtlInitUnicodeString (&LinkName
,
504 Status
= IoCreateSymbolicLink (&LinkName
,
506 RtlFreeUnicodeString (&DeviceName
);
507 if (!NT_SUCCESS(Status
))
509 DbgPrint("IoCreateSymbolicLink() failed (Status %x)\n",
515 /* Check if '\SystemRoot'(LinkName) can be opened, otherwise crash it! */
516 InitializeObjectAttributes (&ObjectAttributes
,
522 Status
= NtOpenSymbolicLinkObject (&Handle
,
523 SYMBOLIC_LINK_ALL_ACCESS
,
525 if (!NT_SUCCESS(Status
))
527 DbgPrint("NtOpenSymbolicLinkObject() failed to open '\\SystemRoot' (Status %x)\n",
536 InitSystemSharedUserPage (PCSZ ParameterLine
)
538 PKUSER_SHARED_DATA SharedPage
;
540 UNICODE_STRING ArcDeviceName
;
541 UNICODE_STRING ArcName
;
542 UNICODE_STRING BootPath
;
543 UNICODE_STRING DriveDeviceName
;
544 UNICODE_STRING DriveName
;
545 WCHAR DriveNameBuffer
[20];
547 PWCHAR ArcNameBuffer
;
551 OBJECT_ATTRIBUTES ObjectAttributes
;
554 BOOLEAN BootDriveFound
;
556 SharedPage
= (PKUSER_SHARED_DATA
)KERNEL_SHARED_DATA_BASE
;
557 SharedPage
->DosDeviceMap
= 0;
558 SharedPage
->NtProductType
= NtProductWinNt
;
559 for (i
= 0; i
< 32; i
++)
561 SharedPage
->DosDeviceDriveType
[i
] = 0;
564 BootDriveFound
= FALSE
;
567 * Retrieve the current dos system path
568 * (e.g.: C:\reactos) from the given arc path
569 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
570 * Format: "<arc_name>\<path> [options...]"
573 /* create local parameter line copy */
574 ParamBuffer
= ExAllocatePool (PagedPool
, 256);
575 strcpy (ParamBuffer
, (char *)ParameterLine
);
576 DPRINT("%s\n", ParamBuffer
);
578 /* cut options off */
579 p
= strchr (ParamBuffer
, ' ');
584 DPRINT("%s\n", ParamBuffer
);
587 p
= strchr (ParamBuffer
, '\\');
590 DPRINT("Boot path: %s\n", p
);
591 RtlCreateUnicodeStringFromAsciiz (&BootPath
, p
);
596 DPRINT("Boot path: %s\n", "\\");
597 RtlCreateUnicodeStringFromAsciiz (&BootPath
, "\\");
599 DPRINT("Arc name: %s\n", ParamBuffer
);
601 /* Only arc name left - build full arc name */
602 ArcNameBuffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
603 swprintf (ArcNameBuffer
, L
"\\ArcName\\%S", ParamBuffer
);
604 RtlInitUnicodeString (&ArcName
, ArcNameBuffer
);
605 DPRINT("Arc name: %wZ\n", &ArcName
);
607 /* free ParamBuffer */
608 ExFreePool (ParamBuffer
);
610 /* allocate arc device name string */
611 ArcDeviceName
.Length
= 0;
612 ArcDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
613 ArcDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
615 InitializeObjectAttributes (&ObjectAttributes
,
621 Status
= NtOpenSymbolicLinkObject (&Handle
,
622 SYMBOLIC_LINK_ALL_ACCESS
,
624 RtlFreeUnicodeString (&ArcName
);
625 if (!NT_SUCCESS(Status
))
627 RtlFreeUnicodeString (&BootPath
);
628 RtlFreeUnicodeString (&ArcDeviceName
);
629 DbgPrint("NtOpenSymbolicLinkObject() failed (Status %x)\n",
635 Status
= NtQuerySymbolicLinkObject (Handle
,
639 if (!NT_SUCCESS(Status
))
641 RtlFreeUnicodeString (&BootPath
);
642 RtlFreeUnicodeString (&ArcDeviceName
);
643 DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n",
648 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length
, &ArcDeviceName
);
651 /* allocate device name string */
652 DriveDeviceName
.Length
= 0;
653 DriveDeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
654 DriveDeviceName
.Buffer
= ExAllocatePool (PagedPool
, 256 * sizeof(WCHAR
));
656 for (i
= 0; i
< 26; i
++)
658 swprintf (DriveNameBuffer
, L
"\\??\\%C:", 'A' + i
);
659 RtlInitUnicodeString (&DriveName
,
662 InitializeObjectAttributes (&ObjectAttributes
,
668 Status
= NtOpenSymbolicLinkObject (&Handle
,
669 SYMBOLIC_LINK_ALL_ACCESS
,
671 if (!NT_SUCCESS(Status
))
673 DPRINT("Failed to open link %wZ\n",
678 Status
= NtQuerySymbolicLinkObject (Handle
,
681 if (!NT_SUCCESS(Status
))
683 DPRINT("Failed query open link %wZ\n",
687 DPRINT("Opened link: %wZ ==> %wZ\n",
688 &DriveName
, &DriveDeviceName
);
690 if (!RtlCompareUnicodeString (&ArcDeviceName
, &DriveDeviceName
, FALSE
))
692 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i
, &BootPath
);
693 swprintf (SharedPage
->NtSystemRoot
,
694 L
"%C:%wZ", 'A' + i
, &BootPath
);
696 BootDriveFound
= TRUE
;
701 /* set bit in dos drives bitmap (drive available) */
702 SharedPage
->DosDeviceMap
|= (1<<i
);
705 RtlFreeUnicodeString (&BootPath
);
706 RtlFreeUnicodeString (&DriveDeviceName
);
707 RtlFreeUnicodeString (&ArcDeviceName
);
709 DPRINT("DosDeviceMap: 0x%x\n", SharedPage
->DosDeviceMap
);
711 if (BootDriveFound
== FALSE
)
713 DbgPrint("No system drive found!\n");
720 VOID
DumpBIOSMemoryMap(VOID
)
724 DbgPrint("Dumping BIOS memory map:\n");
725 DbgPrint("Memory map base: %d\n", KeLoaderBlock
.MmapAddr
);
726 DbgPrint("Memory map size: %d\n", KeLoaderBlock
.MmapLength
);
727 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount
);
728 for (i
= 0; i
< KeMemoryMapRangeCount
; i
++)
730 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
731 KeMemoryMap
[i
].BaseAddrLow
,
732 KeMemoryMap
[i
].LengthLow
,
733 KeMemoryMap
[i
].Type
);
743 static ULONG Scratch
;
745 EXCEPTION_DISPOSITION
746 ExpUnhandledException1(
747 PEXCEPTION_RECORD ExceptionRecord
,
748 PEXCEPTION_REGISTRATION ExceptionRegistration
,
750 PVOID DispatcherContext
)
752 DbgPrint("ExpUnhandledException1() called\n");
753 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
754 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
755 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
756 DbgPrint("Context 0x%X\n", Context
);
757 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
759 Context
->Eax
= (ULONG
)&Scratch
;
761 return ExceptionContinueExecution
;
765 EXCEPTION_DISPOSITION
766 ExpUnhandledException2(
767 PEXCEPTION_RECORD ExceptionRecord
,
768 PEXCEPTION_REGISTRATION ExceptionRegistration
,
770 PVOID DispatcherContext
)
772 DbgPrint("ExpUnhandledException2() called\n");
773 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord
);
774 DbgPrint(" Flags 0x%X\n", ExceptionRecord
->ExceptionFlags
);
775 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration
);
776 DbgPrint("Context 0x%X\n", Context
);
777 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext
);
780 Context
->Eax
= (ULONG
)&Scratch
;
782 return ExceptionContinueExecution
;
786 return ExceptionContinueSearch
;
793 // Put in mingw headers
797 PEXCEPTION_REGISTRATION RegistrationFrame
,
803 PVOID RegistrationFrame
);
805 extern EXCEPTION_DISPOSITION
808 PEXCEPTION_RECORD ExceptionRecord
,
809 PEXCEPTION_REGISTRATION RegistrationFrame
,
811 PVOID DispatcherContext
);
813 extern EXCEPTION_DISPOSITION
816 PEXCEPTION_RECORD ExceptionRecord
,
817 PEXCEPTION_REGISTRATION RegistrationFrame
,
819 PVOID DispatcherContext
);
823 PRTL_EXCEPTION_REGISTRATION
828 __asm__("movl %%ebp, %0\n\t" : "=a" (Value
));
830 return((PRTL_EXCEPTION_REGISTRATION
)Value
) - 1;
834 PRTL_EXCEPTION_REGISTRATION TestER
;
835 SCOPETABLE_ENTRY ScopeTable
;
836 PEXCEPTION_REGISTRATION OSPtr
;
839 DWORD CDECL
SEHFilterRoutine(VOID
)
841 DbgPrint("Within filter routine.\n");
842 return EXCEPTION_EXECUTE_HANDLER
;
843 //return EXCEPTION_CONTINUE_EXECUTION;
846 VOID CDECL
SEHHandlerRoutine(VOID
)
848 DbgPrint("Within exception handler.\n");
849 DbgPrint("System halted.\n");
856 RTL_EXCEPTION_REGISTRATION ER
;
857 LPEXCEPTION_POINTERS ExceptionPointers
;
858 PVOID StandardESPInFrame
;
860 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame
));
861 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame
);
863 ExceptionPointers
= NULL
;
865 ER
.OS
.handler
= _except_handler3
;
866 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER
.OS
.prev
));
867 DbgPrint("ER.OS.prev: 0x%X\n", ER
.OS
.prev
);
869 ER
.ScopeTable
= &ScopeTable
;
870 DbgPrint("ER.ScopeTable: 0x%X\n", ER
.ScopeTable
);
872 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER
.Ebp
));
873 DbgPrint("ER.Ebp: 0x%X\n", ER
.Ebp
);
875 ScopeTable
.PreviousTryLevel
= -1;
876 ScopeTable
.FilterRoutine
= SEHFilterRoutine
;
877 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable
.FilterRoutine
);
878 ScopeTable
.HandlerRoutine
= SEHHandlerRoutine
;
879 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable
.HandlerRoutine
);
883 DbgPrint("OSPtr: 0x%X\n", OSPtr
);
885 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr
));
887 /*__try1(__except_handler3)*/ if(1) {
888 ER
.TryLevel
= 0; // Entered first try... block
890 DbgPrint("Within guarded section.\n");
891 x
= (PULONG
)0xf2000000; *x
= 0;
892 DbgPrint("After exception.\n");
893 } /* __except1 */ if(0) {
896 DbgPrint("After exception2.\n");
898 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER
.OS
.prev
));
899 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
901 DbgPrint("Exiting.\n");
907 ExpInitializeExecutive(VOID
)
916 * Fail at runtime if someone has changed various structures without
917 * updating the offsets used for the assembler code.
919 assert(FIELD_OFFSET(KTHREAD
, InitialStack
) == KTHREAD_INITIAL_STACK
);
920 assert(FIELD_OFFSET(KTHREAD
, Teb
) == KTHREAD_TEB
);
921 assert(FIELD_OFFSET(KTHREAD
, KernelStack
) == KTHREAD_KERNEL_STACK
);
922 assert(FIELD_OFFSET(KTHREAD
, PreviousMode
) == KTHREAD_PREVIOUS_MODE
);
923 assert(FIELD_OFFSET(KTHREAD
, TrapFrame
) == KTHREAD_TRAP_FRAME
);
924 assert(FIELD_OFFSET(ETHREAD
, ThreadsProcess
) == ETHREAD_THREADS_PROCESS
);
925 assert(FIELD_OFFSET(KPROCESS
, DirectoryTableBase
) ==
926 KPROCESS_DIRECTORY_TABLE_BASE
);
927 assert(FIELD_OFFSET(KTRAP_FRAME
, Reserved9
) == KTRAP_FRAME_RESERVED9
);
928 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, regs
) == TF_REGS
);
929 assert(FIELD_OFFSET(KV86M_TRAP_FRAME
, orig_ebp
) == TF_ORIG_EBP
);
931 assert(FIELD_OFFSET(KPCR
, ExceptionList
) == KPCR_EXCEPTION_LIST
);
932 assert(FIELD_OFFSET(KPCR
, Self
) == KPCR_SELF
);
933 assert(FIELD_OFFSET(KPCR
, CurrentThread
) == KPCR_CURRENT_THREAD
);
937 KeLowerIrql(DISPATCH_LEVEL
);
941 MmInit1(FirstKrnlPhysAddr
,
944 (PADDRESS_RANGE
)&KeMemoryMap
,
945 KeMemoryMapRangeCount
);
947 /* create default nls tables */
951 * Initialize the kernel debugger
953 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
954 if (KdPollBreakIn ())
956 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C
);
962 KeLowerIrql(PASSIVE_LEVEL
);
965 PiInitProcessManager();
968 * Display version number and copyright/warranty message
970 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR
" (Build "
971 KERNEL_VERSION_BUILD_STR
")\n");
972 HalDisplayString(RES_STR_LEGAL_COPYRIGHT
);
973 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
974 "Public License, and you\n");
975 HalDisplayString("are welcome to change it and/or distribute copies of it "
977 HalDisplayString("conditions. There is absolutely no warranty for "
980 /* Initialize all processors */
981 KeNumberProcessors
= 0;
983 while (!HalAllProcessorsStarted())
985 PVOID ProcessorStack
;
987 if (KeNumberProcessors
!= 0)
989 KePrepareForApplicationProcessorInit(KeNumberProcessors
);
990 PsPrepareForApplicationProcessorInit(KeNumberProcessors
);
992 /* Allocate a stack for use when booting the processor */
993 /* FIXME: The nonpaged memory for the stack is not released after use */
994 ProcessorStack
= ExAllocatePool(NonPagedPool
, MM_STACK_SIZE
) + MM_STACK_SIZE
;
995 Ki386InitialStackArray
[((int)KeNumberProcessors
)] = (PVOID
)(ProcessorStack
- MM_STACK_SIZE
);
996 HalInitializeProcessor(KeNumberProcessors
, ProcessorStack
);
997 KeNumberProcessors
++;
1000 if (KeNumberProcessors
> 1)
1003 "Found %d system processors. [%lu MB Memory]\n",
1005 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
1010 "Found 1 system processor. [%lu MB Memory]\n",
1011 (KeLoaderBlock
.MemHigher
+ 1088)/ 1024);
1013 HalDisplayString(str
);
1016 * Initialize various critical subsystems
1018 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1023 LdrInitModuleManagement();
1024 CmInitializeRegistry();
1028 /* Report all resources used by hal */
1029 HalReportResourceUsage();
1031 // DumpBIOSMemoryMap();
1034 * Initalize services loaded at boot time
1036 DPRINT1("%d files loaded\n",KeLoaderBlock
.ModsCount
);
1037 for (i
=0; i
< KeLoaderBlock
.ModsCount
; i
++)
1039 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
1040 KeLoaderModules
[i
].String
,
1041 KeLoaderModules
[i
].ModStart
,
1042 KeLoaderModules
[i
].ModEnd
- KeLoaderModules
[i
].ModStart
);
1045 /* Pass 1: load nls files */
1046 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1048 name
= (PCHAR
)KeLoaderModules
[i
].String
;
1049 if (RtlpCheckFileNameExtension(name
, ".nls"))
1051 ULONG Mod2Start
= 0;
1053 ULONG Mod3Start
= 0;
1056 name
= (PCHAR
)KeLoaderModules
[i
+1].String
;
1057 if (RtlpCheckFileNameExtension(name
, ".nls"))
1059 Mod2Start
= (ULONG
)KeLoaderModules
[i
+1].ModStart
;
1060 Mod2End
= (ULONG
)KeLoaderModules
[i
+1].ModEnd
;
1062 name
= (PCHAR
)KeLoaderModules
[i
+2].String
;
1063 if (RtlpCheckFileNameExtension(name
, ".nls"))
1065 Mod3Start
= (ULONG
)KeLoaderModules
[i
+2].ModStart
;
1066 Mod3End
= (ULONG
)KeLoaderModules
[i
+2].ModEnd
;
1070 /* Initialize nls sections */
1071 RtlpInitNlsSections((ULONG
)KeLoaderModules
[i
].ModStart
,
1072 (ULONG
)KeLoaderModules
[i
].ModEnd
,
1081 /* Pass 2: load registry chunks passed in */
1082 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1084 start
= KeLoaderModules
[i
].ModStart
;
1085 length
= KeLoaderModules
[i
].ModEnd
- start
;
1086 name
= (PCHAR
)KeLoaderModules
[i
].String
;
1087 if (RtlpCheckFileNameExtension(name
, "") ||
1088 RtlpCheckFileNameExtension(name
, ".hiv"))
1090 CPRINT("Process registry chunk at %08lx\n", start
);
1091 CmImportHive((PCHAR
)start
, length
);
1096 * Enter the kernel debugger before starting up the boot drivers
1102 /* Pass 3: process boot loaded drivers */
1103 for (i
=1; i
< KeLoaderBlock
.ModsCount
; i
++)
1105 start
= KeLoaderModules
[i
].ModStart
;
1106 length
= KeLoaderModules
[i
].ModEnd
- start
;
1107 name
= (PCHAR
)KeLoaderModules
[i
].String
;
1108 if (RtlpCheckFileNameExtension(name
, ".sys") ||
1109 RtlpCheckFileNameExtension(name
, ".sym"))
1111 CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
1112 name
, start
, length
);
1113 LdrProcessDriver((PVOID
)start
, name
, length
);
1117 /* Create the SystemRoot symbolic link */
1118 CPRINT("CommandLine: %s\n", (PUCHAR
)KeLoaderBlock
.CommandLine
);
1120 CreateSystemRootLink ((PUCHAR
)KeLoaderBlock
.CommandLine
);
1122 #ifdef DBGPRINT_FILE_LOG
1123 /* On the assumption that we can now access disks start up the debug
1126 #endif /* DBGPRINT_FILE_LOG */
1129 CmInitializeRegistry2();
1132 CreateDefaultRegistry();
1135 PiInitDefaultLocale();
1138 * Start the motherboard enumerator (the HAL)
1140 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1143 * Load boot start drivers
1145 IopLoadBootStartDrivers();
1148 * Load Auto configured drivers
1150 LdrLoadAutoConfigDrivers();
1153 * Assign drive letters
1155 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
1161 * Initialize shared user page:
1162 * - set dos system path, dos device map, etc.
1164 InitSystemSharedUserPage ((PUCHAR
)KeLoaderBlock
.CommandLine
);
1171 * Launch initial process
1173 LdrLoadInitialProcess();
1175 PsTerminateSystemThread(STATUS_SUCCESS
);
1180 KiSystemStartup(BOOLEAN BootProcessor
)
1182 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1187 ExpInitializeExecutive();
1190 /* Do application processor initialization */
1191 KeApplicationProcessorInit();
1192 PsApplicationProcessorInit();
1193 KeLowerIrql(PASSIVE_LEVEL
);
1194 PsIdleThreadMain(NULL
);
1200 _main (ULONG MultiBootMagic
, PLOADER_PARAMETER_BLOCK _LoaderBlock
)
1202 * FUNCTION: Called by the boot loader to start the kernel
1204 * LoaderBlock = Pointer to boot parameters initialized by the boot
1206 * NOTE: The boot parameters are stored in low memory which will become
1207 * invalid after the memory managment is initialized so we make a local copy.
1212 ULONG last_kernel_address
;
1213 extern ULONG _bss_end__
;
1218 /* Low level architecture specific initialization */
1222 * Copy the parameters to a local buffer because lowmem will go away
1224 memcpy (&KeLoaderBlock
, _LoaderBlock
, sizeof(LOADER_PARAMETER_BLOCK
));
1225 memcpy (&KeLoaderModules
[1], (PVOID
)KeLoaderBlock
.ModsAddr
,
1226 sizeof(LOADER_MODULE
) * KeLoaderBlock
.ModsCount
);
1227 KeLoaderBlock
.ModsCount
++;
1228 KeLoaderBlock
.ModsAddr
= (ULONG
)&KeLoaderModules
;
1231 * FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
1232 * This should be done by the boot loader.
1234 strcpy (KeLoaderCommandLine
,
1235 "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
1236 strcat (KeLoaderCommandLine
, (PUCHAR
)KeLoaderBlock
.CommandLine
);
1238 KeLoaderBlock
.CommandLine
= (ULONG
)KeLoaderCommandLine
;
1239 strcpy(KeLoaderModuleStrings
[0], "ntoskrnl.exe");
1240 KeLoaderModules
[0].String
= (ULONG
)KeLoaderModuleStrings
[0];
1241 KeLoaderModules
[0].ModStart
= 0xC0000000;
1242 KeLoaderModules
[0].ModEnd
= PAGE_ROUND_UP((ULONG
)&_bss_end__
);
1243 for (i
= 1; i
< KeLoaderBlock
.ModsCount
; i
++)
1245 strcpy(KeLoaderModuleStrings
[i
], (PUCHAR
)KeLoaderModules
[i
].String
);
1246 KeLoaderModules
[i
].ModStart
-= 0x200000;
1247 KeLoaderModules
[i
].ModStart
+= 0xc0000000;
1248 KeLoaderModules
[i
].ModEnd
-= 0x200000;
1249 KeLoaderModules
[i
].ModEnd
+= 0xc0000000;
1250 KeLoaderModules
[i
].String
= (ULONG
)KeLoaderModuleStrings
[i
];
1254 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
1257 HalBase
= KeLoaderModules
[1].ModStart
;
1258 DriverBase
= KeLoaderModules
[KeLoaderBlock
.ModsCount
- 1].ModEnd
;
1263 LdrSafePEProcessModule((PVOID
)HalBase
, (PVOID
)DriverBase
, (PVOID
)0xC0000000, &DriverSize
);
1265 LdrHalBase
= (ULONG_PTR
)DriverBase
;
1266 last_kernel_address
= DriverBase
+ DriverSize
;
1269 * Process ntoskrnl.exe
1271 LdrSafePEProcessModule((PVOID
)0xC0000000, (PVOID
)0xC0000000, (PVOID
)DriverBase
, &DriverSize
);
1273 FirstKrnlPhysAddr
= KeLoaderModules
[0].ModStart
- 0xc0000000 + 0x200000;
1274 LastKrnlPhysAddr
= last_kernel_address
- 0xc0000000 + 0x200000;
1275 LastKernelAddress
= last_kernel_address
;
1278 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
1279 KeLoaderBlock
.Flags
&= ~MB_FLAGS_MMAP_INFO
;
1282 KeMemoryMapRangeCount
= 0;
1283 if (KeLoaderBlock
.Flags
& MB_FLAGS_MMAP_INFO
)
1285 /* We have a memory map from the nice BIOS */
1286 size
= *((PULONG
)(KeLoaderBlock
.MmapAddr
- sizeof(ULONG
)));
1288 while (i
< KeLoaderBlock
.MmapLength
)
1290 memcpy (&KeMemoryMap
[KeMemoryMapRangeCount
],
1291 (PVOID
)(KeLoaderBlock
.MmapAddr
+ i
),
1292 sizeof(ADDRESS_RANGE
));
1293 KeMemoryMapRangeCount
++;