* 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.154 2003/05/15 11:05:20 ekohl 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/registry.h>
#include <internal/nls.h>
#include <reactos/bugcodes.h>
+#include <ntos/bootvid.h>
#ifdef HALDBG
#include <internal/ntosdbg.h>
CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
Status);
- KeBugCheck (0x0);
+ KEBUGCHECK (0x0);
}
Status = NtQuerySymbolicLinkObject (Handle,
CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
Status);
- KeBugCheck (0x0);
+ KEBUGCHECK (0x0);
}
DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
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
ExpInitializeExecutive(VOID)
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
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(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, ExceptionList) == KPCR_EXCEPTION_LIST);
+
+ assert(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
- assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
+ 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();
-
+
+ p1 = (PCHAR)KeLoaderBlock.CommandLine;
+
+ MaxMem = 0;
+ while(*p1 && (p2 = strchr(p1, '/')))
+ {
+ p2++;
+ if (!_strnicmp(p2, "MAXMEM", 6))
+ {
+ 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);
-
- /* Create default nls tables */
- RtlpInitNlsTables();
-
+ 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++;
+ }
+
+ if (!_stricmp (name, "ansi.nls"))
+ {
+ RtlpImportAnsiCodePage((PUSHORT)start, length);
+ }
+ }
+
+ /* Import OEM 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++;
+ }
+
+ if (!_stricmp (name, "oem.nls"))
+ {
+ RtlpImportOemCodePage((PUSHORT)start, length);
+ }
+ }
+
+ /* Import Unicode casemap 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++;
+ }
+
+ if (!_stricmp (name, "casemap.nls"))
+ {
+ RtlpImportUnicodeCasemap((PUSHORT)start, length);
+ }
+ }
+
+ /* Create initial NLS tables */
+ RtlpCreateInitialNlsTables();
+
/*
* Initialize the kernel debugger
*/
KeLowerIrql(PASSIVE_LEVEL);
if (!SeInit1())
- KeBugCheck(SECURITY_INITIALIZATION_FAILED);
+ KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
ObInit();
if (!SeInit2())
- KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
+ KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
PiInitProcessManager();
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
}
- /*
- * 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");
-
/* Initialize all processors */
KeNumberProcessors = 0;
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,
}
HalDisplayString(str);
- /*
- * Initialize various critical subsystems
- */
- HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+ KdInit3();
- ExInit();
- IoInit();
- PoInit();
- LdrInitModuleManagement();
- CmInitializeRegistry();
- NtInit();
- MmInit3();
- /* Create the nls section */
- RtlpInitNlsSection();
+ /* Create the NLS section */
+ RtlpCreateNlsSection();
- CcInit();
- KdInit2();
- FsRtlpInitFileLockingImplementation();
-
- /* Report all resources used by hal */
- HalReportResourceUsage();
-
/*
* Initalize services loaded at boot time
*/
KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
}
- /* Pass 2: import system hive registry chunk */
+ /* Pass 1: import system hive registry chunk */
SetupBoot = TRUE;
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
{
}
}
- /* Pass 3: import hardware hive registry chunk */
+ /* Pass 2: import hardware hive registry chunk */
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
{
start = KeLoaderModules[i].ModStart;
/* Create dummy keys if no hardware hive was found */
CmImportHardwareHive (NULL, 0);
-
/* Initialize volatile registry settings */
if (SetupBoot == FALSE)
{
IoInit2();
- /* Pass 4: process boot loaded drivers */
+ /* Pass 3: process boot loaded drivers */
BootDriverCount = 0;
for (i=1; i < KeLoaderBlock.ModsCount; i++)
{
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);
+ KEBUGCHECK(0);
}
/* Create ARC names for boot devices */
CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
if (!NT_SUCCESS(Status))
- KeBugCheck(INACCESSIBLE_BOOT_DEVICE);
+ KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
#ifdef DBGPRINT_FILE_LOG
/* On the assumption that we can now access disks start up the debug
PiInitDefaultLocale();
- /*
- * Start the motherboard enumerator (the HAL)
- */
- HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
#if 0
/*
* Load boot start drivers
*/
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
*/
&ThreadHandle);
if (!NT_SUCCESS(Status))
{
- KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
- /*
- * Crash the system if the initial process terminates within 5 seconds.
- */
- Timeout.QuadPart = -50000000LL;
- Status = NtWaitForSingleObject(ProcessHandle,
- FALSE,
- &Timeout);
- if (Status != STATUS_TIMEOUT)
+ 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
{
- KeBugCheckEx(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ /* 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);
{
/* Never returns */
ExpInitializeExecutive();
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
/* Do application processor initialization */
KeApplicationProcessorInit();
PsApplicationProcessorInit();
KeLowerIrql(PASSIVE_LEVEL);
PsIdleThreadMain(NULL);
- KeBugCheck(0);
+ KEBUGCHECK(0);
for(;;);
}