* 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.81 2001/03/18 19:35:12 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 "../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 ****************************************************************/
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
-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);
-
- /* 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);
}
}
-extern NTSTATUS STDCALL
-Ke386CallBios(UCHAR Int, KV86M_REGISTERS* Regs);
-
-struct __attribute__((packed)) vesa_info
+VOID STATIC
+MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
{
- UCHAR Signature[4];
- USHORT Version;
- ULONG OEMName;
- ULONG Capabilities;
- ULONG SupportedModes;
- USHORT TotalVideoMemory;
- USHORT OEMVersion;
- ULONG VendorName;
- ULONG ProductName;
- ULONG ProductRevisionString;
- UCHAR Reserved[478];
-};
+ 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
-TestV86Mode(VOID)
+ExpInitializeExecutive(VOID)
{
+ LARGE_INTEGER Timeout;
+ HANDLE ProcessHandle;
+ HANDLE ThreadHandle;
+ ULONG BootDriverCount;
ULONG i;
- extern UCHAR OrigIVT[1024];
- KV86M_REGISTERS regs;
+ ULONG start;
+ ULONG length;
+ PCHAR name;
+ CHAR str[50];
NTSTATUS Status;
- struct vesa_info* vi;
+ 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();
+
+ 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,
+ 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);
+
+ 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++;
+ }
- for (i = 0; i < (640 / 4); i++)
+ 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++)
{
- MmCreateVirtualMapping(NULL,
- (PVOID)(i * 4096),
- PAGE_EXECUTE_READWRITE,
- (ULONG)MmAllocPage(0));
+ 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);
+ }
}
- for (; i < (1024 / 4); i++)
+
+ /* Create dummy keys if no hardware hive was found */
+ CmImportHardwareHive (NULL, 0);
+
+ /* Initialize volatile registry settings */
+ if (SetupBoot == FALSE)
{
- MmCreateVirtualMapping(NULL,
- (PVOID)(i * 4096),
- PAGE_EXECUTE_READ,
- i * 4096);
+ CmInit2((PCHAR)KeLoaderBlock.CommandLine);
}
- vi = (struct vesa_info*)0x20000;
- vi->Signature[0] = 'V';
- vi->Signature[1] = 'B';
- vi->Signature[2] = 'E';
- vi->Signature[3] = '2';
- memset(®s, 0, sizeof(regs));
- regs.Eax = 0x4F00;
- regs.Es = 0x2000;
- regs.Edi = 0x0;
- memcpy((PVOID)0x0, OrigIVT, 1024);
- Status = Ke386CallBios(0x10, ®s);
- DbgPrint("Finished (Status %x, CS:EIP %x:%x)\n", Status, regs.Cs,
- regs.Eip);
- DbgPrint("Eax %x\n", regs.Eax);
- DbgPrint("Signature %.4s\n", vi->Signature);
- DbgPrint("TotalVideoMemory %dKB\n", vi->TotalVideoMemory * 64);
+
+ /*
+ * 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 (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);
+
+#ifdef DBGPRINT_FILE_LOG
+ /* On the assumption that we can now access disks start up the debug
+ logger thread */
+ DebugLogInit2();
+#endif /* DBGPRINT_FILE_LOG */
+
+#ifdef KDBG
+ KdbInitProfiling2();
+#endif /* KDBG */
+
+
+ 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
* invalid after the memory managment is initialized so we make a local copy.
*/
{
- ULONG i;
- ULONG last_kernel_address;
- ULONG start;
- PCHAR name;
- extern ULONG _bss_end__;
-
- /*
- * 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++)
- {
- 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];
- }
-
- /*
- * Initialization phase 0
- */
- HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- KeInit1();
- KeLowerIrql(DISPATCH_LEVEL);
+ 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);
- /*
- * 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");
+ 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];
+ }
- /*
- * 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);
-
- last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
-
- NtEarlyInitVdm();
- MmInit1(KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000,
- last_kernel_address - 0xc0000000 + 0x200000,
- last_kernel_address);
+#ifdef HAL_DBG
+ HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+#endif
- /*
- * Initialize the kernel debugger
- */
- KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- if (KdPollBreakIn ())
- {
- DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
- }
+ HalBase = KeLoaderModules[1].ModStart;
+ DriverBase =
+ PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
- /*
- * Initialization phase 1
- * Initalize various critical subsystems
- */
- HalInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
- MmInit2();
- KeInit2();
+ /*
+ * Process hal.dll
+ */
+ LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
- /*
- * Allow interrupts
- */
- KeLowerIrql(PASSIVE_LEVEL);
-
- ObInit();
- PiInitProcessManager();
- ExInit();
- IoInit();
- LdrInitModuleManagement();
- CmInitializeRegistry();
- NtInit();
- MmInit3();
-
- /* Report all resources used by hal */
- HalReportResourceUsage ();
-
- /*
- * 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);
- }
+ LdrHalBase = (ULONG_PTR)DriverBase;
+ last_kernel_address = DriverBase + DriverSize;
- /* 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);
- }
- }
+ /*
+ * Process ntoskrnl.exe
+ */
+ LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
- /* 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);
- }
- }
+ FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
+ LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
+ LastKernelAddress = last_kernel_address;
- DbgPrint("About to try MmAllocateContiguousAlignedMemory\n");
- do
- {
-extern PVOID STDCALL
-MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
- IN PHYSICAL_ADDRESS HighestAcceptableAddress,
- IN ULONG Alignment);
- PVOID v;
- PHYSICAL_ADDRESS p;
- p.QuadPart = 16*1024*1024;
- v = MmAllocateContiguousAlignedMemory(12*1024, p,
- 64*1024);
- if (v != NULL)
- {
- DbgPrint("Worked\n");
- }
- else
- {
- DbgPrint("Failed\n");
- }
- }
- while (0);
+#ifndef ACPI
+ /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
+ KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
+#endif
- /* Create the SystemRoot symbolic link */
- DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
- CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine);
+ 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;
+ }
+ }
-#ifdef DBGPRINT_FILE_LOG
- /* 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);
-
- /*
- * Launch initial process
- */
- LdrLoadInitialProcess();
-
- DbgPrint("Finished main()\n");
- PsTerminateSystemThread(STATUS_SUCCESS);
+ KiSystemStartup(1);
}
/* EOF */