/*
- * ReactOS kernel
- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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.136 2002/09/07 17:08:31 chorns Exp $
- *
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
* PURPOSE: Initalizes the kernel
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * 28/05/98: Created
+ *
+ * PROGRAMMERS: Alex Ionescu (cleaned up code, moved Executiv stuff to ex/init.c)
+ * David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
-#include "../dbg/kdb.h"
-
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
-ULONG NtBuildNumber = KERNEL_VERSION_BUILD;
-ULONG NtGlobalFlag = 0;
-CHAR KeNumberProcessors;
-LOADER_PARAMETER_BLOCK KeLoaderBlock;
-ULONG KeDcacheFlushCount = 0;
-ULONG 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;
+#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
+
+
+ULONG NtMajorVersion = 4;
+ULONG NtMinorVersion = 0;
+ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0);
+#ifdef __GNUC__
+ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
+ULONG EXPORTED NtGlobalFlag = 0;
+CHAR EXPORTED KeNumberProcessors;
+KAFFINITY EXPORTED KeActiveProcessors;
+LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
+ULONG EXPORTED KeDcacheFlushCount = 0;
+ULONG EXPORTED KeIcacheFlushCount = 0;
+ULONG EXPORTED KiDmaIoCoherency = 0; /* RISC Architectures only */
+ULONG EXPORTED InitSafeBootMode = 0; /* KB83764 */
+#else
+/* Microsoft-style declarations */
+EXPORTED ULONG NtBuildNumber = KERNEL_VERSION_BUILD;
+EXPORTED ULONG NtGlobalFlag = 0;
+EXPORTED CHAR KeNumberProcessors;
+EXPORTED KAFFINITY KeActiveProcessors;
+EXPORTED LOADER_PARAMETER_BLOCK KeLoaderBlock;
+EXPORTED ULONG KeDcacheFlushCount = 0;
+EXPORTED ULONG KeIcacheFlushCount = 0;
+EXPORTED ULONG KiDmaIoCoherency = 0; /* RISC Architectures only */
+EXPORTED ULONG InitSafeBootMode = 0; /* KB83764 */
+#endif /* __GNUC__ */
+
+LOADER_MODULE KeLoaderModules[64];
+static CHAR KeLoaderModuleStrings[64][256];
+static CHAR KeLoaderCommandLine[256];
+ADDRESS_RANGE KeMemoryMap[64];
+ULONG KeMemoryMapRangeCount;
+ULONG_PTR FirstKrnlPhysAddr;
+ULONG_PTR LastKrnlPhysAddr;
+ULONG_PTR LastKernelAddress;
volatile BOOLEAN Initialized = FALSE;
-extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
-
-
-/* FUNCTIONS ****************************************************************/
-
-static BOOLEAN
-RtlpCheckFileNameExtension(PCHAR FileName,
- PCHAR Extension)
-{
- PCHAR Ext;
-
- Ext = strrchr(FileName, '.');
- if ((Extension == NULL) || (*Extension == 0))
- {
- if (Ext == NULL)
- return TRUE;
- else
- return FALSE;
- }
- if (*Extension != '.')
- Ext++;
-
- if (_stricmp(Ext, Extension) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-
-static VOID
-InitSystemSharedUserPage (PCSZ ParameterLine)
-{
- UNICODE_STRING ArcDeviceName;
- UNICODE_STRING ArcName;
- UNICODE_STRING BootPath;
- UNICODE_STRING DriveDeviceName;
- UNICODE_STRING DriveName;
- WCHAR DriveNameBuffer[20];
- PCHAR ParamBuffer;
- PWCHAR ArcNameBuffer;
- PCHAR p;
- NTSTATUS Status;
- ULONG Length;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE Handle;
- ULONG i;
- BOOLEAN BootDriveFound;
-
- /*
- * 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;
-
- /*
- * Retrieve the current dos system path
- * (e.g.: C:\reactos) from the given arc path
- * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
- * Format: "<arc_name>\<path> [options...]"
- */
-
- /* create local parameter line copy */
- ParamBuffer = ExAllocatePool (PagedPool, 256);
- strcpy (ParamBuffer, (char *)ParameterLine);
- DPRINT("%s\n", ParamBuffer);
-
- /* 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);
- DPRINT("Arc name: %wZ\n", &ArcName);
-
- /* free ParamBuffer */
- ExFreePool (ParamBuffer);
-
- /* allocate arc device name string */
- ArcDeviceName.Length = 0;
- ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
- ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
- InitializeObjectAttributes (&ObjectAttributes,
- &ArcName,
- OBJ_OPENLINK,
- NULL,
- NULL);
-
- Status = NtOpenSymbolicLinkObject (&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
- RtlFreeUnicodeString (&ArcName);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString (&BootPath);
- RtlFreeUnicodeString (&ArcDeviceName);
- CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
- Status);
-
- KeBugCheck (0x0);
- }
-
- Status = NtQuerySymbolicLinkObject (Handle,
- &ArcDeviceName,
- &Length);
- NtClose (Handle);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString (&BootPath);
- RtlFreeUnicodeString (&ArcDeviceName);
- CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
- Status);
+ULONG KeLargestCacheLine = 0x40; /* FIXME: Arch-specific */
- KeBugCheck (0x0);
- }
- DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
+/* We allocate 4 pages, but we only use 3. The 4th is to guarantee page alignment */
+ULONG kernel_stack[4096];
+ULONG double_trap_stack[4096];
+/* These point to the aligned 3 pages */
+ULONG init_stack;
+ULONG init_stack_top;
+ULONG trap_stack;
+ULONG trap_stack_top;
- /* allocate device name string */
- DriveDeviceName.Length = 0;
- DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
- DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+/* Cached modules from the loader block */
+PLOADER_MODULE CachedModules[MaximumCachedModuleType];
- for (i = 0; i < 26; i++)
- {
- swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
- RtlInitUnicodeString (&DriveName,
- DriveNameBuffer);
-
- InitializeObjectAttributes (&ObjectAttributes,
- &DriveName,
- OBJ_OPENLINK,
- NULL,
- NULL);
-
- Status = NtOpenSymbolicLinkObject (&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed to open link %wZ\n",
- &DriveName);
- continue;
- }
-
- Status = NtQuerySymbolicLinkObject (Handle,
- &DriveDeviceName,
- &Length);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed query open link %wZ\n",
- &DriveName);
- continue;
- }
- DPRINT("Opened link: %wZ ==> %wZ\n",
- &DriveName, &DriveDeviceName);
-
- if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
- {
- DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
- swprintf(SharedUserData->NtSystemRoot,
- L"%C:%wZ", 'A' + i, &BootPath);
-
- BootDriveFound = TRUE;
- }
-
- NtClose (Handle);
- }
-
- RtlFreeUnicodeString (&BootPath);
- RtlFreeUnicodeString (&DriveDeviceName);
- RtlFreeUnicodeString (&ArcDeviceName);
-
- DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
-
- if (BootDriveFound == FALSE)
- {
- DbgPrint("No system drive found!\n");
- KeBugCheck (0x0);
- }
-}
+/* FUNCTIONS ****************************************************************/
-VOID
-ExpVerifyOffsets()
+/*
+ * @implemented
+ */
+ULONG
+STDCALL
+KeGetRecommendedSharedDataAlignment(VOID)
{
- /*
- * 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(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(IKPCR, KPCR.Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
- assert(FIELD_OFFSET(IKPCR, KPCR.Self) == KPCR_SELF);
- assert(FIELD_OFFSET(IKPCR, KPCR.TSS) == KPCR_TSS);
- assert(FIELD_OFFSET(IKPCR, CurrentThread) == KPCR_CURRENT_THREAD);
- assert(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Ebp) == KV86M_REGISTERS_EBP);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Edi) == KV86M_REGISTERS_EDI);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Esi) == KV86M_REGISTERS_ESI);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Edx) == KV86M_REGISTERS_EDX);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Ecx) == KV86M_REGISTERS_ECX);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Ebx) == KV86M_REGISTERS_EBX);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Eax) == KV86M_REGISTERS_EAX);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Ds) == KV86M_REGISTERS_DS);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Es) == KV86M_REGISTERS_ES);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Fs) == KV86M_REGISTERS_FS);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Gs) == KV86M_REGISTERS_GS);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Eip) == KV86M_REGISTERS_EIP);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Cs) == KV86M_REGISTERS_CS);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Eflags) == KV86M_REGISTERS_EFLAGS);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Esp) == KV86M_REGISTERS_ESP);
- assert(FIELD_OFFSET(KV86M_REGISTERS, Ss) == KV86M_REGISTERS_SS);
+ return KeLargestCacheLine;
}
VOID
-ExpInitializeExecutive(VOID)
-{
- ULONG BootDriverCount;
- ULONG i;
- ULONG start;
- ULONG length;
- PCHAR name;
- CHAR str[50];
- NTSTATUS Status;
-
- ExpVerifyOffsets();
-
- LdrInit1();
-
- KeLowerIrql(DISPATCH_LEVEL);
-
- NtEarlyInitVdm();
-
- MmInit1(FirstKrnlPhysAddr,
- LastKrnlPhysAddr,
- LastKernelAddress,
- (PADDRESS_RANGE)&KeMemoryMap,
- KeMemoryMapRangeCount);
-
- /* create default nls tables */
- RtlpInitNlsTables();
-
- /*
- * 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);
- }
-
- /*
- * 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;
- 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++;
- }
-
- 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);
-
- /*
- * Initialize various critical subsystems
- */
- HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
- ExInit();
- IoInit();
- PoInit();
- LdrInitModuleManagement();
- CmInitializeRegistry();
- NtInit();
- MmInit3();
- CcInit();
- KdInit2();
-
- /* Report all resources used by hal */
- HalReportResourceUsage();
-
- /*
- * 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: load nls files */
- for (i = 1; i < KeLoaderBlock.ModsCount; i++)
- {
- name = (PCHAR)KeLoaderModules[i].String;
- if (RtlpCheckFileNameExtension(name, ".nls"))
- {
- ULONG Mod2Start = 0;
- ULONG Mod2End = 0;
- ULONG Mod3Start = 0;
- ULONG Mod3End = 0;
-
- name = (PCHAR)KeLoaderModules[i+1].String;
- if (RtlpCheckFileNameExtension(name, ".nls"))
- {
- Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
- Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
-
- name = (PCHAR)KeLoaderModules[i+2].String;
- if (RtlpCheckFileNameExtension(name, ".nls"))
- {
- Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
- Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
- }
- }
-
- /* Initialize nls sections */
- RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
- (ULONG)KeLoaderModules[i].ModEnd,
- Mod2Start,
- Mod2End,
- Mod3Start,
- Mod3End);
- break;
- }
- }
-
- /* Pass 2: load registry chunks passed in */
- for (i = 1; i < KeLoaderBlock.ModsCount; i++)
- {
- start = KeLoaderModules[i].ModStart;
- length = KeLoaderModules[i].ModEnd - start;
- name = (PCHAR)KeLoaderModules[i].String;
- if (RtlpCheckFileNameExtension(name, "") ||
- RtlpCheckFileNameExtension(name, ".hiv"))
- {
- CPRINT("Process registry chunk at %08lx\n", start);
- CmImportHive((PCHAR)start, length);
- }
- }
-
- /* Initialize volatile registry settings */
- CmInit2((PCHAR)KeLoaderBlock.CommandLine);
-
- /*
- * Enter the kernel debugger before starting up the boot drivers
- */
-#ifdef KDBG
- KdbEnter();
-#endif /* KDBG */
-
- IoCreateDriverList();
-
- /* 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++;
- }
-
- 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 */
-
-
- PiInitDefaultLocale();
-
- /*
- * Start the motherboard enumerator (the HAL)
- */
- HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-#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);
-
- /*
- * Launch initial process
- */
- LdrLoadInitialProcess();
-
- PsTerminateSystemThread(STATUS_SUCCESS);
-}
-
-
-VOID
+__attribute((noinline))
KiSystemStartup(BOOLEAN BootProcessor)
{
- HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
- if (BootProcessor)
- {
- /* Never returns */
- ExpInitializeExecutive();
- KeBugCheck(0);
+ DPRINT("KiSystemStartup(%d)\n", BootProcessor);
+
+ /* Initialize the Application Processor */
+ if (!BootProcessor) KeApplicationProcessorInit();
+
+ /* Initialize the Processor with HAL */
+ HalInitializeProcessor(KeNumberProcessors, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ /* Load the Kernel if this is the Boot CPU, else inialize the App CPU only */
+ if (BootProcessor) {
+
+ /* Initialize the Kernel Executive */
+ ExpInitializeExecutive();
+
+ /* Free Initial Memory */
+ MiFreeInitMemory();
+
+ /* Never returns */
+ PsTerminateSystemThread(STATUS_SUCCESS);
+ } else {
+
+ /* Do application processor initialization */
+ PsApplicationProcessorInit();
+
+ /* Lower IRQL and go to Idle Thread */
+ KeLowerIrql(PASSIVE_LEVEL);
+ PsIdleThreadMain(NULL);
}
- /* Do application processor initialization */
- KeApplicationProcessorInit();
- PsApplicationProcessorInit();
- KeLowerIrql(PASSIVE_LEVEL);
- PsIdleThreadMain(NULL);
- KeBugCheck(0);
- for(;;);
+
+ /* Bug Check and loop forever if anything failed */
+ KEBUGCHECK(0);
+ for(;;);
}
-VOID
-_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
/*
* FUNCTION: Called by the boot loader to start the kernel
* ARGUMENTS:
* 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.
*/
+VOID
+INIT_FUNCTION
+_main(ULONG MultiBootMagic,
+ PLOADER_PARAMETER_BLOCK _LoaderBlock)
{
- 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, PartNumber;
- 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(%ld)partition(%ld)%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);
- KeLoaderModules[i].ModStart -= 0x200000;
- KeLoaderModules[i].ModStart += 0xc0000000;
- KeLoaderModules[i].ModEnd -= 0x200000;
- KeLoaderModules[i].ModEnd += 0xc0000000;
- KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
+ ULONG i;
+ ULONG size;
+ ULONG HalBase;
+ ULONG DriverBase;
+ ULONG DriverSize;
+ PIMAGE_NT_HEADERS NtHeader;
+ PIMAGE_OPTIONAL_HEADER OptHead;
+ CHAR* s;
+
+ /* Set up the Stacks (Initial Kernel Stack and Double Trap Stack)*/
+ trap_stack = PAGE_ROUND_UP(&double_trap_stack);
+ trap_stack_top = trap_stack + 3 * PAGE_SIZE;
+ init_stack = PAGE_ROUND_UP(&kernel_stack);
+ init_stack_top = init_stack + 3 * PAGE_SIZE;
+
+ /* Copy the Loader Block Data locally since Low-Memory will be wiped */
+ memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+ memcpy(&KeLoaderModules[1],
+ (PVOID)KeLoaderBlock.ModsAddr,
+ sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
+ KeLoaderBlock.ModsCount++;
+ KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
+
+ /* Save the Base Address */
+ MmSystemRangeStart = (PVOID)KeLoaderBlock.KernelBase;
+
+ /* Set the Command Line */
+ strcpy(KeLoaderCommandLine, (PCHAR)_LoaderBlock->CommandLine);
+ KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
+
+ /* Write the first Module (the Kernel) */
+ strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
+ KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
+ KeLoaderModules[0].ModStart = KERNEL_BASE;
+
+ /* Read PE Data */
+ NtHeader = RtlImageNtHeader((PVOID)KeLoaderModules[0].ModStart);
+ OptHead = &NtHeader->OptionalHeader;
+
+ /* Set Kernel Ending */
+ KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart + PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
+
+ /* Create a block for each module */
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
+
+ /* Check if we have to copy the path or not */
+ if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0) {
+
+ strcpy(KeLoaderModuleStrings[i], s + 1);
+
+ } else {
+
+ strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
+ }
+
+ /* Substract the base Address in Physical Memory */
+ KeLoaderModules[i].ModStart -= 0x200000;
+
+ /* Add the Kernel Base Address in Virtual Memory */
+ KeLoaderModules[i].ModStart += KERNEL_BASE;
+
+ /* Substract the base Address in Physical Memory */
+ KeLoaderModules[i].ModEnd -= 0x200000;
+
+ /* Add the Kernel Base Address in Virtual Memory */
+ KeLoaderModules[i].ModEnd += KERNEL_BASE;
+
+ /* Select the proper String */
+ 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;
+ /* Choose last module address as the final kernel address */
+ LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
+
+ /* Low level architecture specific initialization */
+ KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
+
+ /* Select the HAL Base */
+ HalBase = KeLoaderModules[1].ModStart;
+
+ /* Choose Driver Base */
+ DriverBase = LastKernelAddress;
+ LdrHalBase = (ULONG_PTR)DriverBase;
+
+ /* Initialize Module Management */
+ LdrInitModuleManagement();
+
+ /* Load HAL.DLL with the PE Loader */
+ LdrSafePEProcessModule((PVOID)HalBase,
+ (PVOID)DriverBase,
+ (PVOID)KERNEL_BASE,
+ &DriverSize);
+
+ /* Increase the last kernel address with the size of HAL */
+ LastKernelAddress += PAGE_ROUND_UP(DriverSize);
+
+ /* Load the Kernel with the PE Loader */
+ LdrSafePEProcessModule((PVOID)KERNEL_BASE,
+ (PVOID)KERNEL_BASE,
+ (PVOID)DriverBase,
+ &DriverSize);
+
+ /* Now select the final beginning and ending Kernel Addresses */
+ FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KERNEL_BASE + 0x200000;
+ LastKrnlPhysAddr = LastKernelAddress - KERNEL_BASE + 0x200000;
+
+ 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;
+
+ /* Map it until we run out of size */
+ while (i < KeLoaderBlock.MmapLength) {
+
+ /* Copy into the Kernel Memory Map */
+ memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
+ (PVOID)(KeLoaderBlock.MmapAddr + i),
+ sizeof(ADDRESS_RANGE));
+
+ /* Increase Memory Map Count */
+ KeMemoryMapRangeCount++;
+
+ /* Increase Size */
+ i += size;
}
+
+ /* Save data */
+ KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
+ KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+
+ } else {
+
+ /* Nothing from BIOS */
+ KeLoaderBlock.MmapLength = 0;
+ KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
}
-
- KiSystemStartup(1);
+
+ /* Initialize the Debugger */
+ KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ /* Initialize HAL */
+ HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ /* Do general System Startup */
+ KiSystemStartup(1);
}
/* EOF */
-