* 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.96 2001/06/04 11:26:12 chorns 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/ke.h>
#include <internal/io.h>
#include <internal/po.h>
-#include <napi/shared_data.h>
+#include <internal/cc.h>
+#include <internal/se.h>
#include <internal/v86m.h>
#include <internal/kd.h>
#include <internal/trap.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 NtGlobalFlag = 0;
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 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);
- DPRINT("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
- &ArcName,
- Status);
- RtlFreeUnicodeString (&ArcName);
-
- KeBugCheck (0x0);
- }
- RtlFreeUnicodeString (&ArcName);
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
- 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);
-
- /* create the '\SystemRoot' link */
- RtlInitUnicodeString (&LinkName,
- L"\\SystemRoot");
+/* FUNCTIONS ****************************************************************/
- Status = IoCreateSymbolicLink (&LinkName,
- &DeviceName);
- RtlFreeUnicodeString (&DeviceName);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("IoCreateSymbolicLink() failed (Status %x)\n",
- Status);
+static BOOLEAN
+RtlpCheckFileNameExtension(PCHAR FileName,
+ PCHAR Extension)
+{
+ PCHAR Ext;
- KeBugCheck (0x0);
- }
+ Ext = strrchr(FileName, '.');
+ if (Ext == NULL)
+ {
+ if ((Extension == NULL) || (*Extension == 0))
+ return TRUE;
+ else
+ return FALSE;
+ }
- /* Check if '\SystemRoot'(LinkName) can be opened, otherwise crash it! */
- InitializeObjectAttributes (&ObjectAttributes,
- &LinkName,
- 0,
- NULL,
- NULL);
+ if (*Extension != '.')
+ Ext++;
- 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);
+ 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);
}
}
-#ifndef NDEBUG
-
-VOID DumpBIOSMemoryMap(VOID)
+VOID STATIC
+MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
{
+ PHYSICAL_ADDRESS Page;
ULONG i;
- DbgPrint("Dumping BIOS memory map:\n");
- DbgPrint("Memory map base: %d\n", KeLoaderBlock.MmapAddr);
- DbgPrint("Memory map size: %d\n", KeLoaderBlock.MmapLength);
- DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount);
- for (i = 0; i < KeMemoryMapRangeCount; i++)
- {
- DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
- KeMemoryMap[i].BaseAddrLow,
- KeMemoryMap[i].LengthLow,
- KeMemoryMap[i].Type);
- }
- for (;;);
+ 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);
+ }
}
-#endif /* !NDEBUG */
-
VOID
ExpInitializeExecutive(VOID)
{
+ 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
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, 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);
-
+ 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++;
+ }
+
+ 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
*/
KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- if (KdPollBreakIn ())
- {
- DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
- }
-
+
MmInit2();
KeInit2();
KeLowerIrql(PASSIVE_LEVEL);
-
+
+ if (!SeInit1())
+ KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
+
ObInit();
+
+ if (!SeInit2())
+ KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
+
PiInitProcessManager();
-
- /*
- * 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");
+
+ KdInit1();
+
+ if (KdPollBreakIn ())
+ {
+ DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
+ }
/* Initialize all processors */
KeNumberProcessors = 0;
while (!HalAllProcessorsStarted())
{
+ PVOID ProcessorStack;
+
if (KeNumberProcessors != 0)
{
KePrepareForApplicationProcessorInit(KeNumberProcessors);
PsPrepareForApplicationProcessorInit(KeNumberProcessors);
}
- HalInitializeProcessor(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++;
}
- if (KeNumberProcessors > 1)
- {
- sprintf(str, "Found %d system processors.\n",
- KeNumberProcessors);
- }
- else
- {
- strcpy(str, "Found 1 system processor.\n");
- }
- HalDisplayString(str);
-
/*
* Initialize various critical subsystems
*/
- HalInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+ HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
ExInit();
IoInit();
CmInitializeRegistry();
NtInit();
MmInit3();
-
+ CcInit();
+ KdInit2();
+ FsRtlpInitFileLockingImplementation();
+
/* Report all resources used by hal */
- HalReportResourceUsage ();
+ HalReportResourceUsage();
+
+ /* Display the boot screen image if not disabled */
+ if (!NoBootScreen)
+ {
+ InbvEnableBootDriver(TRUE);
+ }
/*
- * Enter the kernel debugger before starting up the boot drivers
+ * Clear the screen to blue
*/
-#ifdef KDBG
- KdbEnter();
-#endif /* KDBG */
+ 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
*/
- DPRINT1("%d files loaded\n",KeLoaderBlock.ModsCount);
+ DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
for (i=0; i < KeLoaderBlock.ModsCount; i++)
{
- CPRINT("Module: %s\n", KeLoaderModules[i].String);
+ 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 1: load registry chunks passed in */
+ /* Pass 2: import hardware hive registry chunk */
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
{
start = KeLoaderModules[i].ModStart;
- if (strcmp ((PCHAR) start, "REGEDIT4") == 0)
+ length = KeLoaderModules[i].ModEnd - start;
+ name = (PCHAR)KeLoaderModules[i].String;
+ if (!_stricmp (name, "hardware") ||
+ !_stricmp (name, "hardware.hiv"))
{
- CPRINT("Process registry chunk at %08lx\n", start);
- CmImportHive((PCHAR) start);
+ CPRINT("Process hardware hive registry chunk at %08lx\n", start);
+ CmImportHardwareHive((PCHAR)start, length);
}
}
- /* Pass 2: process boot loaded drivers */
+ /* 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();
+#endif /* KDBG */
+
+ IoCreateDriverList();
+
+ 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 (strcmp ((PCHAR) start, "REGEDIT4") != 0)
+ if (RtlpCheckFileNameExtension(name, ".sys") ||
+ RtlpCheckFileNameExtension(name, ".sym"))
{
- CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
- name, start, length);
- LdrProcessDriver((PVOID)start, name, length);
+ 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);
-
- CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine);
+ Status = IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
+ if (!NT_SUCCESS(Status))
+ KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
#ifdef DBGPRINT_FILE_LOG
- /* On the assumption that we can now access disks start up the debug
+ /* On the assumption that we can now access disks start up the debug
logger thread */
DebugLogInit2();
#endif /* DBGPRINT_FILE_LOG */
-
- CmInitializeRegistry2();
+#ifdef KDBG
+ KdbInitProfiling2();
+#endif /* KDBG */
- /*
- * Start the motherboard enumerator (the HAL)
- */
- HalInitSystem (2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+ PiInitDefaultLocale();
+
+#if 0
/*
* Load boot start drivers
*/
IopLoadBootStartDrivers();
-
+#else
/*
* Load Auto configured drivers
*/
LdrLoadAutoConfigDrivers();
+#endif
+
+ IoDestroyDriverList();
/*
* Assign drive letters
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
*/
- LdrLoadInitialProcess();
-
+ 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);
+ KEBUGCHECK(0);
}
/* Do application processor initialization */
KeApplicationProcessorInit();
PsApplicationProcessorInit();
KeLowerIrql(PASSIVE_LEVEL);
PsIdleThreadMain(NULL);
- KeBugCheck(0);
+ KEBUGCHECK(0);
for(;;);
}
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);
+ 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.
+ * Convert a path specification in the grub format to one understood by the
+ * rest of the kernel.
*/
- strcpy (KeLoaderCommandLine,
- "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=COM1");
- strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
-
+ 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++)
- {
- strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
+ {
+ 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];
}
-
- last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
-
+
+#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)
{
i += size;
}
}
-
- KeInit1();
KiSystemStartup(1);
}