* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: main.c,v 1.86 2001/04/10 17:48:17 dwelch Exp $
+/* $Id: main.c,v 1.167 2003/08/11 18:50:12 chorns Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
#include <internal/ntoskrnl.h>
#include <reactos/resource.h>
#include <internal/mm.h>
+#include <internal/ifs.h>
#include <internal/module.h>
#include <internal/ldr.h>
#include <internal/ex.h>
#include <internal/ps.h>
#include <internal/ke.h>
#include <internal/io.h>
-#include <napi/shared_data.h>
+#include <internal/po.h>
+#include <internal/cc.h>
+#include <internal/se.h>
#include <internal/v86m.h>
#include <internal/kd.h>
#include <internal/trap.h>
-#include <internal/config.h>
#include "../dbg/kdb.h"
+#include <internal/registry.h>
+#include <internal/nls.h>
+#include <reactos/bugcodes.h>
+#include <ntos/bootvid.h>
+
+#ifdef HALDBG
+#include <internal/ntosdbg.h>
+#else
+#define ps(args...)
+#endif
#define NDEBUG
#include <internal/debug.h>
ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
ULONG EXPORTED NtGlobalFlag = 0;
-CHAR EXPORTED KeNumberProcessors = 1;
+CHAR EXPORTED KeNumberProcessors;
LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
+ULONG EXPORTED KeDcacheFlushCount = 0;
+ULONG EXPORTED KeIcacheFlushCount = 0;
static LOADER_MODULE KeLoaderModules[64];
static UCHAR KeLoaderModuleStrings[64][256];
static UCHAR KeLoaderCommandLine[256];
+static ADDRESS_RANGE KeMemoryMap[64];
+static ULONG KeMemoryMapRangeCount;
+static ULONG FirstKrnlPhysAddr;
+static ULONG LastKrnlPhysAddr;
+static ULONG LastKernelAddress;
+volatile BOOLEAN Initialized = FALSE;
-/* FUNCTIONS ****************************************************************/
-
-static VOID
-CreateSystemRootLink (PCSZ ParameterLine)
-{
- UNICODE_STRING LinkName;
- UNICODE_STRING DeviceName;
- UNICODE_STRING ArcName;
- UNICODE_STRING BootPath;
- PCHAR ParamBuffer;
- PWCHAR ArcNameBuffer;
- PCHAR p;
- NTSTATUS Status;
- ULONG Length;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE Handle;
-
- /* create local parameter line copy */
- ParamBuffer = ExAllocatePool (PagedPool, 256);
- strcpy (ParamBuffer, (char *)ParameterLine);
-
- DPRINT("%s\n", ParamBuffer);
- /* Format: <arc_name>\<path> [options...] */
-
- /* cut options off */
- p = strchr (ParamBuffer, ' ');
- if (p)
- *p = 0;
- DPRINT("%s\n", ParamBuffer);
-
- /* extract path */
- p = strchr (ParamBuffer, '\\');
- if (p)
- {
- DPRINT("Boot path: %s\n", p);
- RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
- *p = 0;
- }
- else
- {
- DPRINT("Boot path: %s\n", "\\");
- RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
- }
- DPRINT("Arc name: %s\n", ParamBuffer);
-
- /* Only arc name left - build full arc name */
- ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
- swprintf (ArcNameBuffer,
- L"\\ArcName\\%S", ParamBuffer);
- RtlInitUnicodeString (&ArcName, ArcNameBuffer);
- DPRINT1("Arc name: %wZ\n", &ArcName);
-
- /* free ParamBuffer */
- ExFreePool (ParamBuffer);
-
- /* allocate device name string */
- DeviceName.Length = 0;
- DeviceName.MaximumLength = 256 * sizeof(WCHAR);
- DeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
- InitializeObjectAttributes (&ObjectAttributes,
- &ArcName,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenSymbolicLinkObject (&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString (&BootPath);
- RtlFreeUnicodeString (&DeviceName);
- DbgPrint("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
- &ArcName,
- Status);
- RtlFreeUnicodeString (&ArcName);
-
- KeBugCheck (0x0);
- }
- RtlFreeUnicodeString (&ArcName);
-
- Status = NtQuerySymbolicLinkObject (Handle,
- &DeviceName,
- &Length);
- NtClose (Handle);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString (&BootPath);
- RtlFreeUnicodeString (&DeviceName);
- DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n",
- Status);
-
- KeBugCheck (0x0);
- }
- DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);
-
- RtlAppendUnicodeStringToString (&DeviceName,
- &BootPath);
-
- RtlFreeUnicodeString (&BootPath);
- DPRINT("DeviceName: %wZ\n", &DeviceName);
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
- /* create the '\SystemRoot' link */
- RtlInitUnicodeString (&LinkName,
- L"\\SystemRoot");
- Status = IoCreateSymbolicLink (&LinkName,
- &DeviceName);
- RtlFreeUnicodeString (&DeviceName);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("IoCreateSymbolicLink() failed (Status %x)\n",
- Status);
-
- KeBugCheck (0x0);
- }
-
- /* Check if '\SystemRoot'(LinkName) can be opened, otherwise crash it! */
- InitializeObjectAttributes (&ObjectAttributes,
- &LinkName,
- 0,
- NULL,
- NULL);
+/* FUNCTIONS ****************************************************************/
- Status = NtOpenSymbolicLinkObject (&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("NtOpenSymbolicLinkObject() failed to open '\\SystemRoot' (Status %x)\n",
- Status);
- KeBugCheck (0x0);
- }
- NtClose(Handle);
+static BOOLEAN
+RtlpCheckFileNameExtension(PCHAR FileName,
+ PCHAR Extension)
+{
+ PCHAR Ext;
+
+ Ext = strrchr(FileName, '.');
+ if (Ext == NULL)
+ {
+ if ((Extension == NULL) || (*Extension == 0))
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ if (*Extension != '.')
+ Ext++;
+
+ if (_stricmp(Ext, Extension) == 0)
+ return TRUE;
+ else
+ return FALSE;
}
static VOID
InitSystemSharedUserPage (PCSZ ParameterLine)
{
- PKUSER_SHARED_DATA SharedPage;
-
UNICODE_STRING ArcDeviceName;
UNICODE_STRING ArcName;
UNICODE_STRING BootPath;
ULONG i;
BOOLEAN BootDriveFound;
- SharedPage = (PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE;
- SharedPage->DosDeviceMap = 0;
- SharedPage->NtProductType = NtProductWinNt;
- for (i = 0; i < 32; i++)
- {
- SharedPage->DosDeviceDriveType[i] = 0;
- }
+ /*
+ * NOTE:
+ * The shared user page has been zeroed-out right after creation.
+ * There is NO need to do this again.
+ */
+
+ SharedUserData->NtProductType = NtProductWinNt;
BootDriveFound = FALSE;
p = strchr (ParamBuffer, '\\');
if (p)
{
- DPRINT("Boot path: %s\n", p);
- RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
- *p = 0;
+ DPRINT("Boot path: %s\n", p);
+ RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
+ *p = 0;
}
else
{
- DPRINT("Boot path: %s\n", "\\");
- RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
+ DPRINT("Boot path: %s\n", "\\");
+ RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
}
DPRINT("Arc name: %s\n", ParamBuffer);
-
+
/* Only arc name left - build full arc name */
ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
InitializeObjectAttributes (&ObjectAttributes,
&ArcName,
- 0,
+ OBJ_OPENLINK,
NULL,
NULL);
{
RtlFreeUnicodeString (&BootPath);
RtlFreeUnicodeString (&ArcDeviceName);
- DbgPrint("NtOpenSymbolicLinkObject() failed (Status %x)\n",
+ CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
Status);
- KeBugCheck (0x0);
+ KEBUGCHECK (0x0);
}
Status = NtQuerySymbolicLinkObject (Handle,
{
RtlFreeUnicodeString (&BootPath);
RtlFreeUnicodeString (&ArcDeviceName);
- DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n",
+ CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
Status);
- KeBugCheck (0x0);
+ KEBUGCHECK (0x0);
}
DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
InitializeObjectAttributes (&ObjectAttributes,
&DriveName,
- 0,
+ OBJ_OPENLINK,
NULL,
NULL);
if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
{
DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
- swprintf (SharedPage->NtSystemRoot,
- L"%C:%wZ", 'A' + i, &BootPath);
-
- BootDriveFound = TRUE;
+ swprintf(SharedUserData->NtSystemRoot,
+ L"%C:%wZ", 'A' + i, &BootPath);
+
+ BootDriveFound = TRUE;
}
NtClose (Handle);
-
- /* set bit in dos drives bitmap (drive available) */
- SharedPage->DosDeviceMap |= (1<<i);
}
RtlFreeUnicodeString (&BootPath);
RtlFreeUnicodeString (&DriveDeviceName);
RtlFreeUnicodeString (&ArcDeviceName);
- DPRINT("DosDeviceMap: 0x%x\n", SharedPage->DosDeviceMap);
+ DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
if (BootDriveFound == FALSE)
{
DbgPrint("No system drive found!\n");
- KeBugCheck (0x0);
+ KEBUGCHECK (0x0);
}
}
+VOID STATIC
+MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
+{
+ PHYSICAL_ADDRESS Page;
+ ULONG i;
+
+ for (i = 0; i < PAGE_ROUND_UP(Length)/PAGE_SIZE; i++)
+ {
+ Page = MmGetPhysicalAddressForProcess(NULL, StartAddress + i * PAGE_SIZE);
+ MmDeleteVirtualMapping(NULL, StartAddress + i * PAGE_SIZE, FALSE, NULL, NULL);
+ MmDereferencePage(Page);
+ }
+}
+
VOID
-_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
-/*
- * FUNCTION: Called by the boot loader to start the kernel
- * ARGUMENTS:
- * LoaderBlock = Pointer to boot parameters initialized by the boot
- * loader
- * NOTE: The boot parameters are stored in low memory which will become
- * invalid after the memory managment is initialized so we make a local copy.
- */
+ExpInitializeExecutive(VOID)
{
- ULONG i;
- ULONG last_kernel_address;
- ULONG start;
- PCHAR name;
- extern ULONG _bss_end__;
+ LARGE_INTEGER Timeout;
+ HANDLE ProcessHandle;
+ HANDLE ThreadHandle;
+ ULONG BootDriverCount;
+ ULONG i;
+ ULONG start;
+ ULONG length;
+ PCHAR name;
+ CHAR str[50];
+ NTSTATUS Status;
+ BOOLEAN SetupBoot;
+ PCHAR p1, p2;
+ ULONG MaxMem;
+ BOOLEAN NoBootScreen = FALSE;
+ UNICODE_STRING Name;
+ HANDLE InitDoneEventHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+ /*
+ * Fail at runtime if someone has changed various structures without
+ * updating the offsets used for the assembler code.
+ */
+ assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
+ assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
+ assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
+ assert(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
+ assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
+ assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
+ assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
+ assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
+ assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
+ KPROCESS_DIRECTORY_TABLE_BASE);
+ assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
+ assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
+ assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
+
+ assert(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
+ assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
+ assert(FIELD_OFFSET(IKPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
+ assert(FIELD_OFFSET(IKPCR, Self) == KPCR_SELF);
+ assert(FIELD_OFFSET(IKPCR, CurrentThread) == KPCR_CURRENT_THREAD);
+
+ LdrInit1();
+
+ KeLowerIrql(DISPATCH_LEVEL);
+
+ NtEarlyInitVdm();
- /*
- * Copy the parameters to a local buffer because lowmem will go away
- */
- memcpy (&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
- memcpy (&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
- sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
- KeLoaderBlock.ModsCount++;
- KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
-
- /*
- * FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
- * This should be done by the boot loader.
- */
- strcpy (KeLoaderCommandLine,
- "multi(0)disk(0)rdisk(0)partition(1)\\reactos ");
- strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
-
- KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
- strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
- KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
- KeLoaderModules[0].ModStart = 0xC0000000;
- KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
- for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ p1 = (PCHAR)KeLoaderBlock.CommandLine;
+
+ MaxMem = 0;
+ while(*p1 && (p2 = strchr(p1, '/')))
+ {
+ p2++;
+ if (!_strnicmp(p2, "MAXMEM", 6))
{
- strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
- KeLoaderModules[i].ModStart -= 0x200000;
- KeLoaderModules[i].ModStart += 0xc0000000;
- KeLoaderModules[i].ModEnd -= 0x200000;
- KeLoaderModules[i].ModEnd += 0xc0000000;
- KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
+ p2 += 6;
+ while (isspace(*p2)) p2++;
+ if (*p2 == '=')
+ {
+ p2++;
+ while(isspace(*p2)) p2++;
+ if (isdigit(*p2))
+ {
+ while (isdigit(*p2))
+ {
+ MaxMem = MaxMem * 10 + *p2 - '0';
+ p2++;
+ }
+ break;
+ }
+ }
}
+ else if (!_strnicmp(p2, "NOBOOTSCREEN", 12))
+ {
+ p2 += 12;
+ NoBootScreen = TRUE;
+ }
+ p1 = p2;
+ }
+
+ MmInit1(FirstKrnlPhysAddr,
+ LastKrnlPhysAddr,
+ LastKernelAddress,
+ (PADDRESS_RANGE)&KeMemoryMap,
+ KeMemoryMapRangeCount,
+ MaxMem > 8 ? MaxMem : 4096);
+
+ /* Import ANSI code page table */
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ start = KeLoaderModules[i].ModStart;
+ length = KeLoaderModules[i].ModEnd - start;
+
+ name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+ if (name == NULL)
+ {
+ name = (PCHAR)KeLoaderModules[i].String;
+ }
+ else
+ {
+ name++;
+ }
- /*
- * Initialization phase 0
- */
- HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- KeInit1();
- LdrInit1();
- KeLowerIrql(DISPATCH_LEVEL);
+ if (!_stricmp (name, "ansi.nls"))
+ {
+ RtlpImportAnsiCodePage((PUSHORT)start, length);
+ }
+ }
- /*
- * Display version number and copyright/warranty message
- */
- HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
- KERNEL_VERSION_BUILD_STR")\n");
- HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
- HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
- "Public License, and you\n");
- HalDisplayString("are welcome to change it and/or distribute copies of it "
- "under certain\n");
- HalDisplayString("conditions. There is absolutely no warranty for ReactOS.\n");
+ /* Import OEM code page table */
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ start = KeLoaderModules[i].ModStart;
+ length = KeLoaderModules[i].ModEnd - start;
- /*
- * Fail at runtime if someone has changed various structures without
- * updating the offsets used for the assembler code
- */
- assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
- assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
- assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
- assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
- assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
- assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
- assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) ==
- KPROCESS_PAGE_TABLE_DIRECTORY);
- assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
- assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
- assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
-
- last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
-
- NtEarlyInitVdm();
- MmInit1(KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000,
- last_kernel_address - 0xc0000000 + 0x200000,
- last_kernel_address);
+ name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+ if (name == NULL)
+ {
+ name = (PCHAR)KeLoaderModules[i].String;
+ }
+ else
+ {
+ name++;
+ }
- /*
- * Initialize the kernel debugger
- */
- KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- if (KdPollBreakIn ())
- {
- DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
- }
+ if (!_stricmp (name, "oem.nls"))
+ {
+ RtlpImportOemCodePage((PUSHORT)start, length);
+ }
+ }
- /*
- * Initialization phase 1
- * Initalize various critical subsystems
- */
- HalInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- MmInit2();
- KeInit2();
+ /* Import Unicode casemap table */
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ start = KeLoaderModules[i].ModStart;
+ length = KeLoaderModules[i].ModEnd - start;
- /*
- * Allow interrupts
- */
- KeLowerIrql(PASSIVE_LEVEL);
-
- ObInit();
- PiInitProcessManager();
- ExInit();
- IoInit();
- LdrInitModuleManagement();
- CmInitializeRegistry();
- NtInit();
- MmInit3();
-
- /* Report all resources used by hal */
- HalReportResourceUsage ();
+ name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+ if (name == NULL)
+ {
+ name = (PCHAR)KeLoaderModules[i].String;
+ }
+ else
+ {
+ name++;
+ }
- /*
- * Enter the kernel debugger before starting up the boot drivers
- */
+ if (!_stricmp (name, "casemap.nls"))
+ {
+ RtlpImportUnicodeCasemap((PUSHORT)start, length);
+ }
+ }
+
+ /* Create initial NLS tables */
+ RtlpCreateInitialNlsTables();
+
+ /*
+ * Initialize the kernel debugger
+ */
+ KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ MmInit2();
+ KeInit2();
+
+ KeLowerIrql(PASSIVE_LEVEL);
+
+ if (!SeInit1())
+ KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
+
+ ObInit();
+
+ if (!SeInit2())
+ KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
+
+ PiInitProcessManager();
+
+ KdInit1();
+
+ if (KdPollBreakIn ())
+ {
+ DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
+ }
+
+ /* Initialize all processors */
+ KeNumberProcessors = 0;
+
+ while (!HalAllProcessorsStarted())
+ {
+ PVOID ProcessorStack;
+
+ if (KeNumberProcessors != 0)
+ {
+ KePrepareForApplicationProcessorInit(KeNumberProcessors);
+ PsPrepareForApplicationProcessorInit(KeNumberProcessors);
+ }
+ /* Allocate a stack for use when booting the processor */
+ /* FIXME: The nonpaged memory for the stack is not released after use */
+ ProcessorStack =
+ ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
+ Ki386InitialStackArray[((int)KeNumberProcessors)] =
+ (PVOID)(ProcessorStack - MM_STACK_SIZE);
+ HalInitializeProcessor(KeNumberProcessors, ProcessorStack);
+ KeNumberProcessors++;
+ }
+
+ /*
+ * Initialize various critical subsystems
+ */
+ HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ ExInit();
+ IoInit();
+ PoInit();
+ LdrInitModuleManagement();
+ CmInitializeRegistry();
+ NtInit();
+ MmInit3();
+ CcInit();
+ KdInit2();
+ FsRtlpInitFileLockingImplementation();
+
+ /* Report all resources used by hal */
+ HalReportResourceUsage();
+
+ /* Display the boot screen image if not disabled */
+ if (!NoBootScreen)
+ {
+ InbvEnableBootDriver(TRUE);
+ }
+
+ /*
+ * Clear the screen to blue
+ */
+ HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ /*
+ * Display version number and copyright/warranty message
+ */
+ HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
+ KERNEL_VERSION_BUILD_STR")\n");
+ HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
+ HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
+ "Public License, and you\n");
+ HalDisplayString("are welcome to change it and/or distribute copies of it "
+ "under certain\n");
+ HalDisplayString("conditions. There is absolutely no warranty for "
+ "ReactOS.\n\n");
+
+ if (KeNumberProcessors > 1)
+ {
+ sprintf(str,
+ "Found %d system processors. [%lu MB Memory]\n",
+ KeNumberProcessors,
+ (KeLoaderBlock.MemHigher + 1088)/ 1024);
+ }
+ else
+ {
+ sprintf(str,
+ "Found 1 system processor. [%lu MB Memory]\n",
+ (KeLoaderBlock.MemHigher + 1088)/ 1024);
+ }
+ HalDisplayString(str);
+
+ KdInit3();
+
+
+ /* Create the NLS section */
+ RtlpCreateNlsSection();
+
+ /*
+ * Initalize services loaded at boot time
+ */
+ DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
+ for (i=0; i < KeLoaderBlock.ModsCount; i++)
+ {
+ CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
+ KeLoaderModules[i].String,
+ KeLoaderModules[i].ModStart,
+ KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
+ }
+
+ /* Pass 1: import system hive registry chunk */
+ SetupBoot = TRUE;
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ start = KeLoaderModules[i].ModStart;
+ length = KeLoaderModules[i].ModEnd - start;
+
+ DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String);
+ name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
+ if (name == NULL)
+ {
+ name = (PCHAR)KeLoaderModules[i].String;
+ }
+ else
+ {
+ name++;
+ }
+
+ if (!_stricmp (name, "system") ||
+ !_stricmp (name, "system.hiv"))
+ {
+ CPRINT("Process system hive registry chunk at %08lx\n", start);
+ SetupBoot = FALSE;
+ CmImportSystemHive((PCHAR)start, length);
+ }
+ }
+
+ /* Pass 2: import hardware hive registry chunk */
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ start = KeLoaderModules[i].ModStart;
+ length = KeLoaderModules[i].ModEnd - start;
+ name = (PCHAR)KeLoaderModules[i].String;
+ if (!_stricmp (name, "hardware") ||
+ !_stricmp (name, "hardware.hiv"))
+ {
+ CPRINT("Process hardware hive registry chunk at %08lx\n", start);
+ CmImportHardwareHive((PCHAR)start, length);
+ }
+ }
+
+ /* Create dummy keys if no hardware hive was found */
+ CmImportHardwareHive (NULL, 0);
+
+ /* Initialize volatile registry settings */
+ if (SetupBoot == FALSE)
+ {
+ CmInit2((PCHAR)KeLoaderBlock.CommandLine);
+ }
+
+ /*
+ * Enter the kernel debugger before starting up the boot drivers
+ */
#ifdef KDBG
- KdbEnter();
+ KdbEnter();
#endif /* KDBG */
-
- /*
- * Initalize services loaded at boot time
- */
- DPRINT1("%d files loaded\n",KeLoaderBlock.ModsCount);
- for (i=0; i < KeLoaderBlock.ModsCount; i++)
- {
- DPRINT1("module: %s\n", KeLoaderModules[i].String);
- }
- /* Pass 1: load registry chunks passed in */
- for (i = 1; i < KeLoaderBlock.ModsCount; i++)
- {
- start = KeLoaderModules[i].ModStart;
- if (strcmp ((PCHAR) start, "REGEDIT4") == 0)
- {
- DPRINT1("process registry chunk at %08lx\n", start);
- CmImportHive((PCHAR) start);
- }
- }
+ IoCreateDriverList();
- /* Pass 2: process boot loaded drivers */
- for (i=1; i < KeLoaderBlock.ModsCount; i++)
- {
- start = KeLoaderModules[i].ModStart;
- name = (PCHAR)KeLoaderModules[i].String;
- if (strcmp ((PCHAR) start, "REGEDIT4") != 0)
- {
- DPRINT1("process module '%s' at %08lx\n", name, start);
- LdrProcessDriver((PVOID)start, name);
+ IoInit2();
+
+ /* Pass 3: process boot loaded drivers */
+ BootDriverCount = 0;
+ for (i=1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ start = KeLoaderModules[i].ModStart;
+ length = KeLoaderModules[i].ModEnd - start;
+ name = (PCHAR)KeLoaderModules[i].String;
+ if (RtlpCheckFileNameExtension(name, ".sys") ||
+ RtlpCheckFileNameExtension(name, ".sym"))
+ {
+ CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n",
+ name, start, length);
+ LdrInitializeBootStartDriver((PVOID)start, name, length);
+ }
+ if (RtlpCheckFileNameExtension(name, ".sys"))
+ BootDriverCount++;
+ }
+
+ /* Pass 4: free memory for all boot files, except ntoskrnl.exe and hal.dll */
+ for (i = 2; i < KeLoaderBlock.ModsCount; i++)
+ {
+#ifdef KDBG
+ /* Do not free the memory from symbol files, if the kernel debugger is activ */
+ if (!RtlpCheckFileNameExtension(name, ".sym"))
+#endif
+ {
+ MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart,
+ KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
}
- }
+ }
+
+ if (BootDriverCount == 0)
+ {
+ DbgPrint("No boot drivers available.\n");
+ KEBUGCHECK(0);
+ }
+
+ /* Create ARC names for boot devices */
+ IoCreateArcNames();
+
+ /* Create the SystemRoot symbolic link */
+ CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
+ Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
+ if (!NT_SUCCESS(Status))
+ KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
- /* Create the SystemRoot symbolic link */
- DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
- CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine);
-
#ifdef DBGPRINT_FILE_LOG
- /* On the assumption that we can now access disks start up the debug
- logger thread */
- DebugLogInit2();
+ /* On the assumption that we can now access disks start up the debug
+ logger thread */
+ DebugLogInit2();
#endif /* DBGPRINT_FILE_LOG */
-
- CmInitializeRegistry2();
-
- /*
- * Load Auto configured drivers
- */
- LdrLoadAutoConfigDrivers();
-
- /*
- * Assign drive letters
- */
- IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
- NULL,
- NULL,
- NULL);
- /*
- * Initialize shared user page:
- * - set dos system path, dos device map, etc.
- */
- InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
+#ifdef KDBG
+ KdbInitProfiling2();
+#endif /* KDBG */
- /*
- * Launch initial process
- */
- LdrLoadInitialProcess();
- DbgPrint("Finished main()\n");
- PsTerminateSystemThread(STATUS_SUCCESS);
+ PiInitDefaultLocale();
+
+#if 0
+ /*
+ * Load boot start drivers
+ */
+ IopLoadBootStartDrivers();
+#else
+ /*
+ * Load Auto configured drivers
+ */
+ LdrLoadAutoConfigDrivers();
+#endif
+
+ IoDestroyDriverList();
+
+ /*
+ * Assign drive letters
+ */
+ IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
+ NULL,
+ NULL,
+ NULL);
+
+ /*
+ * Initialize shared user page:
+ * - set dos system path, dos device map, etc.
+ */
+ InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
+
+ /* Create 'ReactOSInitDone' event */
+ RtlInitUnicodeString(&Name, L"\\ReactOSInitDone");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ 0,
+ NULL,
+ NULL);
+ Status = NtCreateEvent(&InitDoneEventHandle,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes,
+ FALSE, /* Synchronization event */
+ FALSE); /* Not signalled */
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
+ InitDoneEventHandle = INVALID_HANDLE_VALUE;
+ }
+
+ /*
+ * Launch initial process
+ */
+ Status = LdrLoadInitialProcess(&ProcessHandle,
+ &ThreadHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ if (InitDoneEventHandle != INVALID_HANDLE_VALUE)
+ {
+ HANDLE Handles[2]; /* Init event, Initial process */
+
+ Handles[0] = InitDoneEventHandle;
+ Handles[1] = ProcessHandle;
+
+ /* Wait for the system to be initialized */
+ Timeout.QuadPart = -1200000000LL; /* 120 second timeout */
+ Status = NtWaitForMultipleObjects(((LONG) sizeof(Handles) / sizeof(HANDLE)),
+ Handles,
+ WaitAny,
+ FALSE, /* Non-alertable */
+ &Timeout);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
+ }
+ else if (Status == STATUS_TIMEOUT)
+ {
+ DPRINT1("WARNING: System not initialized after 120 seconds.\n");
+ }
+ else if (Status == STATUS_WAIT_0 + 1)
+ {
+ /*
+ * Crash the system if the initial process was terminated.
+ */
+ KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ if (!NoBootScreen)
+ {
+ InbvEnableBootDriver(FALSE);
+ }
+
+ NtSetEvent(InitDoneEventHandle, NULL);
+
+ NtClose(InitDoneEventHandle);
+ }
+ else
+ {
+ /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
+ if (!NoBootScreen)
+ {
+ InbvEnableBootDriver(FALSE);
+ }
+
+ /*
+ * Crash the system if the initial process terminates within 5 seconds.
+ */
+ Timeout.QuadPart = -50000000LL;
+ Status = NtWaitForSingleObject(ProcessHandle,
+ FALSE,
+ &Timeout);
+ if (Status != STATUS_TIMEOUT)
+ {
+ KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+ }
+
+ NtClose(ThreadHandle);
+ NtClose(ProcessHandle);
+
+ PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+
+VOID
+KiSystemStartup(BOOLEAN BootProcessor)
+{
+ HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ if (BootProcessor)
+ {
+ /* Never returns */
+ ExpInitializeExecutive();
+ KEBUGCHECK(0);
+ }
+ /* Do application processor initialization */
+ KeApplicationProcessorInit();
+ PsApplicationProcessorInit();
+ KeLowerIrql(PASSIVE_LEVEL);
+ PsIdleThreadMain(NULL);
+ KEBUGCHECK(0);
+ for(;;);
+}
+
+VOID
+_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
+/*
+ * FUNCTION: Called by the boot loader to start the kernel
+ * ARGUMENTS:
+ * LoaderBlock = Pointer to boot parameters initialized by the boot
+ * loader
+ * NOTE: The boot parameters are stored in low memory which will become
+ * invalid after the memory managment is initialized so we make a local copy.
+ */
+{
+ ULONG i;
+ ULONG size;
+ ULONG last_kernel_address;
+ extern ULONG _bss_end__;
+ ULONG HalBase;
+ ULONG DriverBase;
+ ULONG DriverSize;
+
+ /* Low level architecture specific initialization */
+ KeInit1();
+
+ /*
+ * Copy the parameters to a local buffer because lowmem will go away
+ */
+ memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+ memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
+ sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
+ KeLoaderBlock.ModsCount++;
+ KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
+
+ /*
+ * Convert a path specification in the grub format to one understood by the
+ * rest of the kernel.
+ */
+ if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
+ {
+ ULONG DiskNumber = 0, PartNumber = 0;
+ PCH p;
+ CHAR Temp[256];
+ PCH options;
+ PCH s1;
+
+ if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
+ ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
+ {
+ DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0';
+ PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0';
+ }
+ strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]);
+ if ((options = strchr(Temp, ' ')) != NULL)
+ {
+ *options = 0;
+ options++;
+ }
+ else
+ {
+ options = "";
+ }
+ if ((s1 = strrchr(Temp, '/')) != NULL)
+ {
+ *s1 = 0;
+ if ((s1 = strrchr(Temp, '/')) != NULL)
+ {
+ *s1 = 0;
+ }
+ }
+ sprintf(KeLoaderCommandLine,
+ "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
+ DiskNumber, PartNumber + 1, Temp, options);
+
+ p = KeLoaderCommandLine;
+ while (*p != 0 && *p != ' ')
+ {
+ if ((*p) == '/')
+ {
+ (*p) = '\\';
+ }
+ p++;
+ }
+ DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
+ }
+ else
+ {
+ strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine);
+ }
+ KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
+
+ strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
+ KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
+ KeLoaderModules[0].ModStart = 0xC0000000;
+ KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+ {
+ CHAR* s;
+ if ((s = strrchr((PUCHAR)KeLoaderModules[i].String, '/')) != 0)
+ {
+ strcpy(KeLoaderModuleStrings[i], s + 1);
+ }
+ else
+ {
+ strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
+ }
+ KeLoaderModules[i].ModStart -= 0x200000;
+ KeLoaderModules[i].ModStart += 0xc0000000;
+ KeLoaderModules[i].ModEnd -= 0x200000;
+ KeLoaderModules[i].ModEnd += 0xc0000000;
+ KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
+ }
+
+#ifdef HAL_DBG
+ HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+#endif
+
+ HalBase = KeLoaderModules[1].ModStart;
+ DriverBase =
+ PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
+
+ /*
+ * Process hal.dll
+ */
+ LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
+
+ LdrHalBase = (ULONG_PTR)DriverBase;
+ last_kernel_address = DriverBase + DriverSize;
+
+ /*
+ * Process ntoskrnl.exe
+ */
+ LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
+
+ FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
+ LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
+ LastKernelAddress = last_kernel_address;
+
+#ifndef ACPI
+ /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
+ KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
+#endif
+
+ KeMemoryMapRangeCount = 0;
+ if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
+ {
+ /* We have a memory map from the nice BIOS */
+ size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
+ i = 0;
+ while (i < KeLoaderBlock.MmapLength)
+ {
+ memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
+ (PVOID)(KeLoaderBlock.MmapAddr + i),
+ sizeof(ADDRESS_RANGE));
+ KeMemoryMapRangeCount++;
+ i += size;
+ }
+ }
+
+ KiSystemStartup(1);
}
/* EOF */