Alex Ionescu <ionucu@videotron.ca>
authorThomas Bluemel <thomas@reactsoft.com>
Sat, 12 Mar 2005 21:08:29 +0000 (21:08 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Sat, 12 Mar 2005 21:08:29 +0000 (21:08 +0000)
- Reorganized Bootup code. Most of the Executive initialization is now in ex/init.c
- Remove ExPostSystemEvent.
- Sped up Command-line parasing and wrote a function specificalyl for it, to ease extensibility
- Sped up and optimized loading modules from FreeLoader. The data is only looked up once and then the pointers are cached for easy re-use.
- Moved KeGetRecommendedSharedDataAlignmented to ke/main.c and implemented it.
- Moved subsystem-specific intialization to their own subsystem, like Io in ioinit and Cm in CmInit.

svn path=/trunk/; revision=13981

13 files changed:
reactos/ntoskrnl/cm/registry.c
reactos/ntoskrnl/ex/init.c
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/nls.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/io/bootlog.c
reactos/ntoskrnl/io/iomgr.c
reactos/ntoskrnl/ke/catch.c
reactos/ntoskrnl/ke/main.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/rtl/nls.c

index 304192c..e727569 100644 (file)
@@ -241,6 +241,31 @@ CmiCheckRegistry(BOOLEAN Verbose)
   CmiCheckByName(Verbose, L"User");
 }
 
+VOID
+INIT_FUNCTION
+STDCALL
+CmInitHives(BOOLEAN SetupBoot)
+{
+    PCHAR BaseAddress;
+    
+    /* Load Registry Hives. This one can be missing. */
+    if (CachedModules[SystemRegistry]) {
+        BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
+        CmImportSystemHive(BaseAddress,
+                           CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    }
+    
+    BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart;
+    CmImportHardwareHive(BaseAddress,
+                         CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    
+
+    /* Create dummy keys if no hardware hive was found */
+    CmImportHardwareHive (NULL, 0);
+
+    /* Initialize volatile registry settings */
+    if (SetupBoot == FALSE) CmInit2((PCHAR)KeLoaderBlock.CommandLine);
+}   
 
 VOID INIT_FUNCTION
 CmInitializeRegistry(VOID)
@@ -336,7 +361,6 @@ CmInitializeRegistry(VOID)
   CmiVolatileHive->RootSecurityCell = RootSecurityCell;
 #endif
 
-  KeInitializeSpinLock(&CmiKeyListLock);
 
   /* Create '\Registry\Machine' key. */
   RtlInitUnicodeString(&KeyName,
index fe66586..f422db9 100644 (file)
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/init.c
  * PURPOSE:         Executive initalization
  * 
- * PROGRAMMERS:     Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Added ExpInitializeExecutive
+ *                                                    and optimized/cleaned it.
+ *                  Eric Kohl (ekohl@abo.rhein-zeitung.de)
  */
 
 #include <ntoskrnl.h>
+#include <ntos/bootvid.h>
+#include "../dbg/kdb.h"
 #define NDEBUG
 #include <internal/debug.h>
 
 /* DATA **********************************************************************/
 
+extern ULONG MmCoreDumpType;
+extern CHAR KiTimerSystemAuditing;
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+extern ADDRESS_RANGE KeMemoryMap[64];
+extern ULONG KeMemoryMapRangeCount;
+extern ULONG_PTR FirstKrnlPhysAddr;
+extern ULONG_PTR LastKrnlPhysAddr;
+extern ULONG_PTR LastKernelAddress;
+extern LOADER_MODULE KeLoaderModules[64];
+extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
+#if 0
+extern LIST_ENTRY KiProfileListHead;
+extern LIST_ENTRY KiProfileSourceListHead;
+extern KSPIN_LOCK KiProfileLock;
+#endif
+
 /* FUNCTIONS ****************************************************************/
 
+static 
+VOID 
+INIT_FUNCTION
+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 = FALSE;
+
+   /*
+    * NOTE:
+    *   The shared user page has been zeroed-out right after creation.
+    *   There is NO need to do this again.
+    */
+    Ki386SetProcessorFeatures();
+    
+    /* Set the Version Data */
+    SharedUserData->NtProductType = NtProductWinNt;
+    SharedUserData->ProductTypeIsValid = TRUE;
+    SharedUserData->NtMajorVersion = 5;
+    SharedUserData->NtMinorVersion = 0;
+   
+    /*
+     * 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));
+
+    /* Open the Symbolic Link */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ArcName,
+                               OBJ_OPENLINK,
+                               NULL,
+                               NULL);
+    Status = NtOpenSymbolicLinkObject(&Handle,
+                                      SYMBOLIC_LINK_ALL_ACCESS,
+                                      &ObjectAttributes);
+    
+    /* Free the String */
+    RtlFreeUnicodeString(&ArcName);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Free the Strings */
+        RtlFreeUnicodeString(&BootPath);
+        RtlFreeUnicodeString(&ArcDeviceName);
+        CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status);
+        KEBUGCHECK(0);
+    }
+    
+    /* Query the Link */
+    Status = NtQuerySymbolicLinkObject(Handle,
+                                       &ArcDeviceName,
+                                       &Length);
+    NtClose (Handle);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Free the Strings */
+        RtlFreeUnicodeString(&BootPath);
+        RtlFreeUnicodeString(&ArcDeviceName);
+        CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status);
+        KEBUGCHECK(0);
+    }
+    DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
+
+    /* Allocate Device Name string */
+    DriveDeviceName.Length = 0;
+    DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
+    DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+
+    /* Loop Drives */
+    for (i = 0; i < 26; i++)  {
+        
+        /* Setup the String */
+        swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
+        RtlInitUnicodeString(&DriveName,
+                             DriveNameBuffer);
+        
+        /* Open the Symbolic Link */
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &DriveName,
+                                   OBJ_OPENLINK,
+                                   NULL,
+                                   NULL);
+        Status = NtOpenSymbolicLinkObject(&Handle,
+                                          SYMBOLIC_LINK_ALL_ACCESS,
+                                          &ObjectAttributes);
+        
+        /* If it failed, skip to the next drive */
+        if (!NT_SUCCESS(Status)) {
+            DPRINT("Failed to open link %wZ\n", &DriveName);
+            continue;
+        }
+        
+        /* Query it */
+        Status = NtQuerySymbolicLinkObject(Handle,
+                                           &DriveDeviceName,
+                                           &Length);
+        
+        /* If it failed, skip to the next drive */
+        if (!NT_SUCCESS(Status)) {
+            DPRINT("Failed to query link %wZ\n", &DriveName);
+            continue;
+        }
+        DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName, &DriveDeviceName);
+
+        /* See if we've found the boot drive */
+        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;
+        }
+
+        /* Close this Link */
+        NtClose (Handle);
+    }
+    
+    /* Free all the Strings we have in memory */
+    RtlFreeUnicodeString (&BootPath);
+    RtlFreeUnicodeString (&DriveDeviceName);
+    RtlFreeUnicodeString (&ArcDeviceName);
+
+    /* Make sure we found the Boot Drive */
+    if (BootDriveFound == FALSE) {
+        
+        DbgPrint("No system drive found!\n");
+        KEBUGCHECK (NO_BOOT_DEVICE);
+    }
+}
+
+inline
+VOID
+STDCALL
+ExecuteRuntimeAsserts(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, NpxState) == KTHREAD_NPX_STATE);
+    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(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
+    ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
+    ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
+    ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
+    ASSERT(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
+    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(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);  
+    ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
+    ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
+    ASSERT(FIELD_OFFSET(KTSS, Eflags) == KTSS_EFLAGS);
+    ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
+    ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
+}
+
+inline
+VOID
+STDCALL
+ParseAndCacheLoadedModules(PBOOLEAN SetupBoot)
+{
+    ULONG i;
+    PCHAR Name;
+    
+    /* Loop the Module List and get the modules we want */
+    for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
+       
+        /* Get the Name of this Module */
+        if (!(Name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'))) {
+      
+            /* Save the name */
+            Name = (PCHAR)KeLoaderModules[i].String;
+          
+        } else {
+      
+            /* No name, skip */
+            Name++;
+        }
+      
+        /* Now check for any of the modules we will need later */
+        if (!_stricmp(Name, "ansi.nls")) {
+          
+            CachedModules[AnsiCodepage] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "oem.nls")) {
+          
+            CachedModules[OemCodepage] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "casemap.nls")) {
+      
+            CachedModules[UnicodeCasemap] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "system") || !_stricmp(Name, "system.hiv")) {
+      
+            CachedModules[SystemRegistry] = &KeLoaderModules[i];
+            *SetupBoot = FALSE;
+      
+        } else if (!_stricmp(Name, "hardware") || !_stricmp(Name, "hardware.hiv")) {
+      
+            CachedModules[HardwareRegistry] = &KeLoaderModules[i];
+        }
+    }    
+}
+
+inline
+VOID
+STDCALL
+ParseCommandLine(PULONG MaxMem, 
+                 PBOOLEAN NoGuiBoot, 
+                 PBOOLEAN BootLog, 
+                 PBOOLEAN ForceAcpiDisable)
+{
+    PCHAR p1, p2; 
+    
+    p1 = (PCHAR)KeLoaderBlock.CommandLine;
+    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, "NOGUIBOOT", 9)) {
+            
+            p2 += 9;
+            *NoGuiBoot = TRUE;
+            
+        } else if (!_strnicmp(p2, "CRASHDUMP", 9)) {
+            
+            p2 += 9;
+            if (*p2 == ':') {
+                
+                p2++;
+                if (!_strnicmp(p2, "FULL", 4)) {
+                    
+                    MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
+                    
+                } else {
+                    
+                    MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
+                }
+            }
+        } else if (!_strnicmp(p2, "BOOTLOG", 7)) {
+            
+            p2 += 7;
+            *BootLog = TRUE;
+        } else if (!_strnicmp(p2, "NOACPI", 6)) {
+            
+            p2 += 6;
+            *ForceAcpiDisable = TRUE;
+        }
+        
+        p1 = p2;
+    }
+}
+
+VOID 
+INIT_FUNCTION
+STDCALL
+ExpInitializeExecutive(VOID)
+{
+    CHAR str[50];
+    UNICODE_STRING EventName;
+    HANDLE InitDoneEventHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    BOOLEAN NoGuiBoot = FALSE;
+    BOOLEAN BootLog = FALSE;
+    ULONG MaxMem = 0;
+    BOOLEAN SetupBoot = TRUE;
+    BOOLEAN ForceAcpiDisable = FALSE;
+    LARGE_INTEGER Timeout;
+    HANDLE ProcessHandle;
+    HANDLE ThreadHandle;
+    NTSTATUS Status;
+
+    /* Check if the structures match the ASM offset constants */
+    ExecuteRuntimeAsserts();
+    
+    /* Sets up the Text Sections of the Kernel and HAL for debugging */
+    LdrInit1();
+    
+    /* Lower the IRQL to Dispatch Level */
+    KeLowerIrql(DISPATCH_LEVEL);
+    
+    /* Sets up the VDM Data */
+    NtEarlyInitVdm();
+
+    /* Parse Command Line Settings */
+    ParseCommandLine(&MaxMem, &NoGuiBoot, &BootLog, &ForceAcpiDisable);
+    
+    /* Initialize Kernel Memory Address Space */
+    MmInit1(FirstKrnlPhysAddr,
+            LastKrnlPhysAddr,
+            LastKernelAddress,
+            (PADDRESS_RANGE)&KeMemoryMap,
+            KeMemoryMapRangeCount,
+            MaxMem > 8 ? MaxMem : 4096);
+
+    /* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */
+    ParseAndCacheLoadedModules(&SetupBoot);
+    
+    /* Initialize the kernel debugger */
+    KdInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+    
+    /* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */
+    KeInit2();
+
+    /* Bring back the IRQL to Passive */
+    KeLowerIrql(PASSIVE_LEVEL);
+    
+#if 0
+    /* Initialize Profiling */
+    InitializeListHead(&KiProfileListHead);
+    InitializeListHead(&KiProfileSourceListHead);
+    KeInitializeSpinLock(&KiProfileLock);
+#endif
+    
+    /* Load basic Security for other Managers */
+    if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
+
+    /* Create the Basic Object Manager Types to allow new Object Types */
+    ObInit();
+    
+    /* Initialize Lookaside Lists */
+    ExInit2();
+    
+    /* Set up Region Maps, Sections and the Paging File */
+    MmInit2();
+
+    /* Initialize Tokens now that the Object Manager is ready */
+    if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
+
+    /* Set 1 CPU for now, we'll increment this later */
+    KeNumberProcessors = 1;
+    
+    /* Initalize the Process Manager */
+    PiInitProcessManager();
+
+    /* Break into the Debugger if requested */
+    if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
+
+    /* Initialize all processors */
+    while (!HalAllProcessorsStarted()) {
+        
+        PVOID ProcessorStack;
+
+        /* Set up the Kernel and Process Manager for this CPU */
+        KePrepareForApplicationProcessorInit(KeNumberProcessors);
+        PsPrepareForApplicationProcessorInit(KeNumberProcessors);
+
+        /* Allocate a stack for use when booting the processor */
+        ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
+
+        /* Tell HAL a new CPU is being started */
+        HalStartNextProcessor(0, (ULONG)ProcessorStack - 2*sizeof(FX_SAVE_AREA));
+        KeNumberProcessors++;
+    }
+
+    /* Do Phase 1 HAL Initalization */
+    HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+    
+    /* Initialize Basic System Objects and Worker Threads */
+    ExInit3();
+    
+    /* Initialize the GDB Stub and break */
+    KdInit1();
+  
+    /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
+    IoInit();
+    
+    /* TBD */
+    PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable);
+  
+    /* Initialize the Registry (Hives are NOT yet loaded!) */
+    CmInitializeRegistry();
+  
+    /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
+    MmInit3();
+  
+    /* Initialize Cache Views */
+    CcInit();
+  
+    /* Hook System Interrupt for the Debugger */
+    KdInit2();
+    
+    /* Initialize File Locking */
+    FsRtlpInitFileLockingImplementation();
+
+    /* Report all resources used by hal */
+    HalReportResourceUsage();  
+
+    /* 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");
+
+    /* Display number of Processors */
+    sprintf(str,
+            "Found %d system processor(s). [%lu MB Memory]\n",
+            KeNumberProcessors,
+            (KeLoaderBlock.MemHigher + 1088)/ 1024);
+    HalDisplayString(str);
+
+    /* Print which Debugger is being used */
+    KdInit3();
+
+    /* Import and create NLS Data and Sections */
+    RtlpInitNls();
+
+    /* Import and Load Registry Hives */
+    CmInitHives(SetupBoot);
+    
+    /* Initialize the time zone information from the registry */
+    ExpInitTimeZoneInfo();
+   
+  /* Enter the kernel debugger before starting up the boot drivers */
+#ifdef KDBG
+    KdbEnter();
+#endif /* KDBG */
+
+    /* Setup Drivers and Root Device Node */
+    IoInit2(BootLog);
+
+    /* Display the boot screen image if not disabled */
+    if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
+    
+    /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
+    IoInit3();
+       
+    /* Initialize the Default Locale */
+    PiInitDefaultLocale();
+    
+    /* Initialize shared user page. Set dos system path, dos device map, etc. */
+    InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
+
+    /* Create 'ReactOSInitDone' event */
+    RtlInitUnicodeString(&EventName, L"\\ReactOSInitDone");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &EventName,
+                               0,
+                               NULL,
+                               NULL);
+    Status = ZwCreateEvent(&InitDoneEventHandle,
+                           EVENT_ALL_ACCESS,
+                           &ObjectAttributes,
+                           SynchronizationEvent,
+                           FALSE);
+    
+    /* Check for Success */
+    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);
+    
+    /* Check for success, Bugcheck if we failed */
+    if (!NT_SUCCESS(Status)) {
+        
+        KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    /* Wait on the Completion Event */
+    if (InitDoneEventHandle != INVALID_HANDLE_VALUE) {
+
+        HANDLE Handles[2]; /* Init event, Initial process */
+
+        /* Setup the Handles to wait on */
+        Handles[0] = InitDoneEventHandle;
+        Handles[1] = ProcessHandle;
+
+        /* Wait for the system to be initialized */
+        Timeout.QuadPart = (LONGLONG)-1200000000;  /* 120 second timeout */
+        Status = ZwWaitForMultipleObjects(2,
+                                          Handles,
+                                          WaitAny,
+                                          FALSE,
+                                          &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);
+        }
+
+        /* Disable the Boot Logo */
+        if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+
+        /* Signal the Event and close the handle */
+        ZwSetEvent(InitDoneEventHandle, NULL);
+        ZwClose(InitDoneEventHandle);
+    
+    } else {
+        
+        /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
+        if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+
+        /* Crash the system if the initial process terminates within 5 seconds. */
+        Timeout.QuadPart = (LONGLONG)-50000000;  /* 5 second timeout */
+        Status = ZwWaitForSingleObject(ProcessHandle,
+                                       FALSE,
+                                       &Timeout);
+        
+        /* Check for timeout, crash if the initial process didn't initalize */
+        if (Status != STATUS_TIMEOUT) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
+    }
+    
+    /* Enable the Clock, close remaining handles */
+    KiTimerSystemAuditing = 1;
+    ZwClose(ThreadHandle);
+    ZwClose(ProcessHandle);
+}
+
 VOID INIT_FUNCTION
 ExInit2(VOID)
 {
@@ -35,15 +666,7 @@ ExInit3 (VOID)
   ExpInitializeProfileImplementation();
   ExpWin32kInit();
   ExpInitUuids();
-}
-
-
-VOID STDCALL
-ExPostSystemEvent (ULONG       Unknown1,
-                  ULONG        Unknown2,
-                  ULONG        Unknown3)
-{
-  /* doesn't do anything */
+  ExpInitializeCallbacks();
 }
 
 /* EOF */
index 3596bfe..8ae57b1 100644 (file)
@@ -105,17 +105,12 @@ VOID
 ExpInitializeCallbacks(VOID);
 VOID
 ExpInitUuids(VOID);
+VOID
+STDCALL
+ExpInitializeExecutive(VOID);
 
 /* OTHER FUNCTIONS **********************************************************/
 
-#ifdef _ENABLE_THRDEVTPAIR
-VOID
-ExpSwapThreadEventPair(
-       IN struct _ETHREAD* Thread,
-       IN struct _KEVENT_PAIR* EventPair
-       );
-#endif /* _ENABLE_THRDEVTPAIR */
-
 LONGLONG 
 FASTCALL
 ExfpInterlockedExchange64(LONGLONG volatile * Destination,
index b23f612..3d2c432 100644 (file)
@@ -412,7 +412,7 @@ IoDestroyDriverList(VOID);
 /* bootlog.c */
 
 VOID
-IopInitBootLog(VOID);
+IopInitBootLog(BOOLEAN StartBootLog);
 
 VOID
 IopStartBootLog(VOID);
index 525e8f6..5d1dbaa 100644 (file)
@@ -116,6 +116,17 @@ typedef struct _KPROFILE
   struct _EPROCESS *Process;
 } KPROFILE, *PKPROFILE;
 
+/* Cached modules from the loader block */
+typedef enum _CACHED_MODULE_TYPE {
+    AnsiCodepage,
+    OemCodepage,
+    UnicodeCasemap,
+    SystemRegistry,
+    HardwareRegistry,
+    MaximumCachedModuleType,
+} CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE;
+extern PLOADER_MODULE CachedModules[MaximumCachedModuleType];
+
 VOID STDCALL 
 DbgBreakPointNoBugCheck(VOID);
 
index 46906e3..84787cb 100644 (file)
@@ -29,6 +29,7 @@ extern ULONG NlsUnicodeTableOffset;
 extern PUSHORT NlsUnicodeUpcaseTable;
 extern PUSHORT NlsUnicodeLowercaseTable;
 
+VOID STDCALL RtlpInitNls(VOID);
 VOID RtlpImportAnsiCodePage(PUSHORT TableBase, ULONG Size);
 VOID RtlpImportOemCodePage(PUSHORT TableBase, ULONG Size);
 VOID RtlpImportUnicodeCasemap(PUSHORT TableBase, ULONG Size);
index a98537f..972b42a 100644 (file)
@@ -49,10 +49,12 @@ VOID ExpInitializeProfileImplementation(VOID);
  */
 VOID MmInitSystem(ULONG Phase, PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG LastKernelAddress);
 VOID IoInit(VOID);
-VOID IoInit2(VOID);
+VOID IoInit2(BOOLEAN BootLog);
+VOID STDCALL IoInit3(VOID);
 VOID ObInit(VOID);
 VOID PsInit(VOID);
 VOID CmInitializeRegistry(VOID);
+VOID STDCALL CmInitHives(BOOLEAN SetupBoot);
 VOID CmInit2(PCHAR CommandLine);
 VOID CmShutdownRegistry(VOID);
 BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
index 71dc17b..9324dd9 100644 (file)
@@ -27,13 +27,14 @@ static ERESOURCE IopBootLogResource;
 /* FUNCTIONS ****************************************************************/
 
 VOID INIT_FUNCTION
-IopInitBootLog(VOID)
+IopInitBootLog(BOOLEAN StartBootLog)
 {
   ExInitializeResourceLite(&IopBootLogResource);
+  if (StartBootLog) IopStartBootLog();
 }
 
 
-VOID
+VOID INIT_FUNCTION
 IopStartBootLog(VOID)
 {
   IopBootLogCreate = TRUE;
index eff2a12..64ae143 100644 (file)
@@ -11,6 +11,7 @@
 /* INCLUDES ****************************************************************/
 
 #include <ntoskrnl.h>
+#include "../dbg/kdb.h"
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -562,14 +563,17 @@ IoInit (VOID)
 }
 
 
-VOID INIT_FUNCTION
-IoInit2(VOID)
+VOID 
+INIT_FUNCTION
+IoInit2(BOOLEAN BootLog)
 {
   PDEVICE_NODE DeviceNode;
   PDRIVER_OBJECT DriverObject;
   MODULE_OBJECT ModuleObject;
   NTSTATUS Status;
 
+  IoCreateDriverList();
+          
   KeInitializeSpinLock (&IoStatisticsLock);
 
   /* Initialize raw filesystem driver */
@@ -614,6 +618,56 @@ IoInit2(VOID)
   IopInvalidateDeviceRelations(
     IopRootDeviceNode,
     BusRelations);
+  
+     /* Start boot logging */
+    IopInitBootLog(BootLog);
+  
+    /* Load boot start drivers */
+    IopInitializeBootDrivers();
+}
+
+VOID
+STDCALL
+INIT_FUNCTION
+IoInit3(VOID)
+{
+    NTSTATUS Status;
+    
+    /* Create ARC names for boot devices */
+    IoCreateArcNames();
+
+    /* Create the SystemRoot symbolic link */
+    CPRINT("CommandLine: %s\n", (PCHAR)KeLoaderBlock.CommandLine);
+    Status = IoCreateSystemRootLink((PCHAR)KeLoaderBlock.CommandLine);
+    if (!NT_SUCCESS(Status)) {
+        DbgPrint("IoCreateSystemRootLink FAILED: (0x%x) - ", Status);
+        DbgPrintErrorMessage (Status);
+        KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
+    }
+
+    /* Start Profiling on a Debug Build */
+#if defined(KDBG)
+    KdbInit();
+#endif /* KDBG */
+
+    /* I/O is now setup for disk access, so start the debugging logger thread. */
+    if (KdDebugState & KD_DEBUG_FILELOG) DebugLogInit2();
+
+    /* Load services for devices found by PnP manager */
+    IopInitializePnpServices(IopRootDeviceNode, FALSE);
+
+    /* Load system start drivers */
+    IopInitializeSystemDrivers();
+    IoDestroyDriverList();
+
+    /* Stop boot logging */
+    IopStopBootLog();
+
+    /* Assign drive letters */
+    IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
+                         NULL,
+                         NULL,
+                         NULL);    
 }
 
 /*
index afb3bc0..737e50b 100644 (file)
@@ -257,17 +257,4 @@ ExRaiseHardError (
        UNIMPLEMENTED;
 }
 
-/*
- * @unimplemented
- */
-ULONG
-STDCALL
-KeGetRecommendedSharedDataAlignment(
-       VOID
-       )
-{
-       UNIMPLEMENTED;
-       return 0;
-}
-
 /* EOF */
index 4786dad..b25d272 100644 (file)
@@ -1,37 +1,24 @@
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/main.c
  * PURPOSE:         Initalizes the kernel
  *
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * 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"
-#include <ntos/bootvid.h>
-#include <napi/core.h>
-
-#ifdef HALDBG
-#include <internal/ntosdbg.h>
-#else
-#if defined(_MSC_VER) && (_MSC_VER <= 1200)
-#define ps
-#else
-#define ps(args...)
-#endif /* HALDBG */
-
-#endif
-
 #define NDEBUG
 #include <internal/debug.h>
 
 /* GLOBALS *******************************************************************/
 
 #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
+
+
 ULONG NtMajorVersion = 4;
 ULONG NtMinorVersion = 0;
 ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0);
@@ -58,19 +45,17 @@ EXPORTED ULONG KiDmaIoCoherency = 0; /* RISC Architectures only */
 EXPORTED ULONG InitSafeBootMode = 0; /* KB83764 */
 #endif /* __GNUC__ */
 
-static LOADER_MODULE KeLoaderModules[64];
+LOADER_MODULE KeLoaderModules[64];
 static CHAR KeLoaderModuleStrings[64][256];
 static CHAR KeLoaderCommandLine[256];
-static ADDRESS_RANGE KeMemoryMap[64];
-static ULONG KeMemoryMapRangeCount;
-static ULONG_PTR FirstKrnlPhysAddr;
-static ULONG_PTR LastKrnlPhysAddr;
-static ULONG_PTR LastKernelAddress;
+ADDRESS_RANGE KeMemoryMap[64];
+ULONG KeMemoryMapRangeCount;
+ULONG_PTR FirstKrnlPhysAddr;
+ULONG_PTR LastKrnlPhysAddr;
+ULONG_PTR LastKernelAddress;
 volatile BOOLEAN Initialized = FALSE;
-extern ULONG MmCoreDumpType;
-extern CHAR KiTimerSystemAuditing;
 
-extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+ULONG KeLargestCacheLine = 0x40; /* FIXME: Arch-specific */
 
 /* We allocate 4 pages, but we only use 3. The 4th is to guarantee page alignment */
 ULONG kernel_stack[4096];
@@ -82,796 +67,59 @@ ULONG init_stack_top;
 ULONG trap_stack;
 ULONG trap_stack_top;
 
-/* FUNCTIONS ****************************************************************/
-
-static VOID INIT_FUNCTION
-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.
-    */
-
-   Ki386SetProcessorFeatures();
-
-   SharedUserData->NtProductType = NtProductWinNt;
-   SharedUserData->ProductTypeIsValid = TRUE;
-   SharedUserData->NtMajorVersion = 5;
-   SharedUserData->NtMinorVersion = 0;
-
-   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);
-
-       KEBUGCHECK (0x0);
-     }
-   DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
-
-
-   /* allocate device name string */
-   DriveDeviceName.Length = 0;
-   DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
-   DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
-   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);
-
-   if (BootDriveFound == FALSE)
-     {
-       DbgPrint("No system drive found!\n");
-       KEBUGCHECK (NO_BOOT_DEVICE);
-     }
-}
-
-VOID INIT_FUNCTION
-ExpInitializeExecutive(VOID)
-{
-  LARGE_INTEGER Timeout;
-  HANDLE ProcessHandle;
-  HANDLE ThreadHandle;
-  ULONG i;
-  ULONG start;
-  ULONG length;
-  PCHAR name;
-  CHAR str[50];
-  NTSTATUS Status;
-  BOOLEAN SetupBoot;
-  PCHAR p1, p2;
-  ULONG MaxMem;
-  BOOLEAN NoGuiBoot = 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, NpxState) == KTHREAD_NPX_STATE);
-  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(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
-  ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == 
-        KPROCESS_DIRECTORY_TABLE_BASE);
-  ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
-  ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
-  ASSERT(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
-  ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
-  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(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);  
-  ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
-
-  ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
-  ASSERT(FIELD_OFFSET(KTSS, Eflags) == KTSS_EFLAGS);
-  ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
-
-  ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
-
-  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, "NOGUIBOOT", 9))
-     {
-       p2 += 9;
-       NoGuiBoot = TRUE;
-     }
-     else if (!_strnicmp(p2, "CRASHDUMP", 9))
-     {
-       p2 += 9;
-       if (*p2 == ':')
-        {
-          p2++;
-          if (!_strnicmp(p2, "FULL", 4))
-            {
-              MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
-            }
-          else
-            {
-              MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
-            }
-        }
-     }
-     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 (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  KeInit2();
-  
-#if 0
-  if (KeMemoryMapRangeCount > 0)
-    {
-      DPRINT1("MemoryMap:\n");
-      for (i = 0; i < KeMemoryMapRangeCount; i++)
-        {
-          switch(KeMemoryMap[i].Type)
-            {
-              case 1:
-               strcpy(str, "(usable)");
-               break;
-             case 2:
-               strcpy(str, "(reserved)");
-               break;
-             case 3:
-               strcpy(str, "(ACPI data)");
-               break;
-             case 4:
-               strcpy(str, "(ACPI NVS)");
-               break;
-             default:
-               sprintf(str, "type %lu", KeMemoryMap[i].Type);
-            }
-          DPRINT1("%08x - %08x %s\n", KeMemoryMap[i].BaseAddrLow, KeMemoryMap[i].BaseAddrLow + KeMemoryMap[i].LengthLow, str);
-       }
-    }
-#endif
-
-  KeLowerIrql(PASSIVE_LEVEL);
-
-  if (!SeInit1())
-    KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
-
-  ObInit();
-  ExInit2();
-  MmInit2();
-
-  if (!SeInit2())
-    KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
-
-  KeNumberProcessors = 1;
-
-  PiInitProcessManager();
-
-  if (KdPollBreakIn ())
-    {
-      DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
-    }
-
-  /* Initialize all processors */
-  while (!HalAllProcessorsStarted())
-    {
-      PVOID ProcessorStack;
-
-      KePrepareForApplicationProcessorInit(KeNumberProcessors);
-      PsPrepareForApplicationProcessorInit(KeNumberProcessors);
-
-      /* Allocate a stack for use when booting the processor */
-      ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
-
-      HalStartNextProcessor(0, (ULONG)ProcessorStack - 2*sizeof(FX_SAVE_AREA));
-      KeNumberProcessors++;
-    }
-
-  /*
-   * Initialize various critical subsystems
-   */
-  HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  ExInit3();
-  KdInit1();
-  IoInit();
-  PoInit(&KeLoaderBlock, FALSE);
-  CmInitializeRegistry();
-  MmInit3();
-  CcInit();
-  KdInit2();
-  FsRtlpInitFileLockingImplementation();
-
-  /* Report all resources used by hal */
-  HalReportResourceUsage();  
-
-  /*
-   * 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();
+/* Cached modules from the loader block */
+PLOADER_MODULE CachedModules[MaximumCachedModuleType];
 
+/* FUNCTIONS ****************************************************************/
 
-  /* Create the NLS section */
-  RtlpCreateNlsSection();
-
-  /*
-   * Initalize services loaded at boot time
-   */
-  DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
-  for (i=0; i < KeLoaderBlock.ModsCount; i++)
-    {
-      CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
-       KeLoaderModules[i].String,
-       KeLoaderModules[i].ModStart,
-       KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
-    }
-
-  /* Pass 1: import system hive registry chunk */
-  SetupBoot = TRUE;
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-
-      DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String);
-      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
-      if (name == NULL)
-       {
-         name = (PCHAR)KeLoaderModules[i].String;
-       }
-      else
-       {
-         name++;
-       }
-
-      if (!_stricmp (name, "system") ||
-         !_stricmp (name, "system.hiv"))
-       {
-         CPRINT("Process system hive registry chunk at %08lx\n", start);
-         SetupBoot = FALSE;
-         CmImportSystemHive((PCHAR)start, length);
-       }
-    }
-
-  /* Pass 2: import hardware hive registry chunk */
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-      name = (PCHAR)KeLoaderModules[i].String;
-      if (!_stricmp (name, "hardware") ||
-         !_stricmp (name, "hardware.hiv"))
-       {
-         CPRINT("Process hardware hive registry chunk at %08lx\n", start);
-         CmImportHardwareHive((PCHAR)start, length);
-       }
-    }
-
-  /* Create dummy keys if no hardware hive was found */
-  CmImportHardwareHive (NULL, 0);
-
-  /* Initialize volatile registry settings */
-  if (SetupBoot == FALSE)
-    {
-      CmInit2((PCHAR)KeLoaderBlock.CommandLine);
-    }
-
-  /* Initialize the time zone information from the registry */
-  ExpInitTimeZoneInfo();
-
-  /*
-   * Enter the kernel debugger before starting up the boot drivers
-   */
-#ifdef KDBG
-  KdbEnter();
-#endif /* KDBG */
-
-  IoCreateDriverList();
-
-  IoInit2();
-
-  /* Initialize Callbacks before drivers */
-  ExpInitializeCallbacks();
-
-  /* Start boot logging */
-  IopInitBootLog();
-  p1 = (PCHAR)KeLoaderBlock.CommandLine;
-  while (*p1 && (p2 = strchr(p1, '/')))
-  {
-    p2++;
-    if (!_strnicmp(p2, "BOOTLOG", 7))
-    {
-      p2 += 7;
-      IopStartBootLog();
-    }
-
-    p1 = p2;
-  }
-
-  /*
-   * Load boot start drivers
-   */
-  IopInitializeBootDrivers();
-
-  /* Display the boot screen image if not disabled */
-  if (!NoGuiBoot)
-    {
-      InbvEnableBootDriver(TRUE);
-    }
-
-  /* Create ARC names for boot devices */
-  IoCreateArcNames();
-
-  /* Create the SystemRoot symbolic link */
-  CPRINT("CommandLine: %s\n", (PCHAR)KeLoaderBlock.CommandLine);
-  DPRINT1("MmSystemRangeStart: 0x%x PageDir: 0x%x\n", MmSystemRangeStart, KeLoaderBlock.PageDirectoryStart);
-  Status = IoCreateSystemRootLink((PCHAR)KeLoaderBlock.CommandLine);
-  if (!NT_SUCCESS(Status))
-  {
-    DbgPrint ( "IoCreateSystemRootLink FAILED: (0x%x) - ", Status );
-    DbgPrintErrorMessage ( Status );
-    KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
-  }
-
-#if defined(KDBG)
-  KdbInit();
-#endif /* KDBG */
-#if defined(KDBG) || defined(DBG)
-  KdbInitProfiling2();
-#endif /* KDBG || DBG */
-
-  /* On the assumption that we can now access disks start up the debug
-   * logger thread */
-  if ((KdDebuggerEnabled == TRUE) && (KdDebugState & KD_DEBUG_FILELOG))
-    {
-      DebugLogInit2();
-    }
-
-  PiInitDefaultLocale();
-
-  /*
-   * Load services for devices found by PnP manager
-   */
-  IopInitializePnpServices(IopRootDeviceNode, FALSE);
-
-  /*
-   * Load system start drivers
-   */
-  IopInitializeSystemDrivers();
-
-  IoDestroyDriverList();
-
-  /* Stop boot logging */
-  IopStopBootLog();
-
-  /*
-   * Assign drive letters
-   */
-  IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
-                       NULL,
-                       NULL,
-                       NULL);
-
-  /*
-   * Initialize shared user page:
-   *  - set dos system path, dos device map, etc.
-   */
-  InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
-
-  /* Create 'ReactOSInitDone' event */
-  RtlInitUnicodeString(&Name, L"\\ReactOSInitDone");
-  InitializeObjectAttributes(&ObjectAttributes,
-    &Name,
-    0,
-    NULL,
-    NULL);
-  Status = ZwCreateEvent(&InitDoneEventHandle,
-    EVENT_ALL_ACCESS,
-    &ObjectAttributes,
-    SynchronizationEvent,
-    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 = (LONGLONG)-1200000000;  /* 120 second timeout */
-      Status = ZwWaitForMultipleObjects(((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 (!NoGuiBoot)
-        {
-          InbvEnableBootDriver(FALSE);
-        }
-
-      ZwSetEvent(InitDoneEventHandle, NULL);
-
-      ZwClose(InitDoneEventHandle);
-    }
-  else
-    {
-      /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
-      if (!NoGuiBoot)
-        {
-          InbvEnableBootDriver(FALSE);
-        }
-
-      /*
-       * Crash the system if the initial process terminates within 5 seconds.
-       */
-      Timeout.QuadPart = (LONGLONG)-50000000;  /* 5 second timeout */
-      Status = ZwWaitForSingleObject(ProcessHandle,
-                                FALSE,
-                                &Timeout);
-      if (Status != STATUS_TIMEOUT)
-        {
-          KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
-        }
-    }
 /*
- * Tell ke/timer.c it's okay to run.
+ * @implemented
  */
-
-  KiTimerSystemAuditing = 1;
-
-  ZwClose(ThreadHandle);
-  ZwClose(ProcessHandle);
+ULONG
+STDCALL
+KeGetRecommendedSharedDataAlignment(VOID)
+{
+    return KeLargestCacheLine;
 }
 
-VOID __attribute((noinline))
+VOID
+__attribute((noinline))
 KiSystemStartup(BOOLEAN BootProcessor)
 {
-  DPRINT1("KiSystemStartup(%d)\n", BootProcessor);
-  if (BootProcessor)
-  {
-  }
-  else
-  {
-     KeApplicationProcessorInit();
-  }
-
-  HalInitializeProcessor(KeNumberProcessors, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  if (BootProcessor)
-  {
-     ExpInitializeExecutive();
-     MiFreeInitMemory();
-     /* Never returns */
-     PsTerminateSystemThread(STATUS_SUCCESS);
-  }
-  else
-  {
-     /* Do application processor initialization */
-     PsApplicationProcessorInit();
-     KeLowerIrql(PASSIVE_LEVEL);
-     PsIdleThreadMain(NULL);
-  }
-  KEBUGCHECK(0);
-  for(;;);
+    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);
+    }
+    
+    /* Bug Check and loop forever if anything failed */
+    KEBUGCHECK(0);
+    for(;;);
 }
 
-VOID INIT_FUNCTION
-_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
 /*
  * FUNCTION: Called by the boot loader to start the kernel
  * ARGUMENTS:
@@ -880,173 +128,158 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
  * 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 HalBase;
-  ULONG DriverBase;
-  ULONG DriverSize;
-
-  /* Set up the Stacks */
-  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;
+    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 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;
-
-  /* Save the Base Address */
-  MmSystemRangeStart = (PVOID)KeLoaderBlock.KernelBase;
+    /* 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;
   
-  /*
-   * 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 = ((PCHAR)_LoaderBlock->CommandLine)[3] - '0';
-         PartNumber = ((PCHAR)_LoaderBlock->CommandLine)[5] - '0';
-       }
-      strcpy(Temp, &((PCHAR)_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, (PCHAR)_LoaderBlock->CommandLine);
-    }
-  KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
+    /* Set the Command Line */
+    strcpy(KeLoaderCommandLine, (PCHAR)_LoaderBlock->CommandLine);
+    KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
   
-  strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
-  KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
-  KeLoaderModules[0].ModStart = KERNEL_BASE;
-  /* Take this value from the PE... */
-    PIMAGE_NT_HEADERS      NtHeader = RtlImageNtHeader((PVOID)KeLoaderModules[0].ModStart);
-    PIMAGE_OPTIONAL_HEADER OptHead  = &NtHeader->OptionalHeader;
+    /* 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);
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {      
-      CHAR* s;
-      if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0)
-       {
-         strcpy(KeLoaderModuleStrings[i], s + 1);
-       }
-      else
-       {
-         strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
-       }
-      KeLoaderModules[i].ModStart -= 0x200000;
-      KeLoaderModules[i].ModStart += KERNEL_BASE;
-      KeLoaderModules[i].ModEnd -= 0x200000;
-      KeLoaderModules[i].ModEnd += KERNEL_BASE;
-      KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
+    
+    /* 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];
     }
 
-  LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
-
-  /* Low level architecture specific initialization */
-  KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
-
-  HalBase = KeLoaderModules[1].ModStart;
-  DriverBase = LastKernelAddress;
-  LdrHalBase = (ULONG_PTR)DriverBase;
-
-  LdrInitModuleManagement();
-
-  /*
-   * Process hal.dll
-   */
-  LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)KERNEL_BASE, &DriverSize);
-
-  LastKernelAddress += PAGE_ROUND_UP(DriverSize);
-
-  /*
-   * Process ntoskrnl.exe
-   */
-  LdrSafePEProcessModule((PVOID)KERNEL_BASE, (PVOID)KERNEL_BASE, (PVOID)DriverBase, &DriverSize);
-
-  /* Now our imports from HAL are fixed. This is the first */
-  /* time in the boot process that we can use HAL          */
-
-  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;
-      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;
         }
-      KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
-      KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
-    }
-  else
-    {
-      KeLoaderBlock.MmapLength = 0;
-      KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+        
+        /* Save data */
+        KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
+        KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+        
+    } else {
+        
+        /* Nothing from BIOS */
+        KeLoaderBlock.MmapLength = 0;
+        KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
     }
-
-  KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-  HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  DPRINT1("_main (%x, %x)\n", MultiBootMagic, _LoaderBlock);
-
-
-  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 */
-
index 461ebe6..9444fe0 100644 (file)
@@ -122,7 +122,6 @@ ExIsResourceAcquiredExclusiveLite@4
 ExIsResourceAcquiredSharedLite@4
 ExLocalTimeToSystemTime@8
 ExNotifyCallback@12
-ExPostSystemEvent@12
 ExQueryPoolBlockSize@8
 ExQueueWorkItem@8
 ExRaiseAccessViolation@0
index c56345c..82e6729 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/rtl/nls.c
@@ -36,7 +35,32 @@ ULONG NlsUnicodeTableOffset = 0;
 
 /* FUNCTIONS *****************************************************************/
 
-
+VOID 
+INIT_FUNCTION
+STDCALL
+RtlpInitNls(VOID)
+{
+    ULONG_PTR BaseAddress;
+    
+    /* Import NLS Data */ 
+    BaseAddress = CachedModules[AnsiCodepage]->ModStart;
+    RtlpImportAnsiCodePage((PUSHORT)BaseAddress,
+                           CachedModules[AnsiCodepage]->ModEnd - BaseAddress);
+    
+    BaseAddress = CachedModules[OemCodepage]->ModStart;
+    RtlpImportOemCodePage((PUSHORT)BaseAddress,
+                          CachedModules[OemCodepage]->ModEnd - BaseAddress);
+    
+    BaseAddress = CachedModules[UnicodeCasemap]->ModStart;
+    RtlpImportUnicodeCasemap((PUSHORT)BaseAddress,
+                             CachedModules[UnicodeCasemap]->ModEnd - BaseAddress);
+    
+    /* Create initial NLS tables */
+    RtlpCreateInitialNlsTables();
+    
+    /* Create the NLS section */
+    RtlpCreateNlsSection();    
+}
 
 VOID INIT_FUNCTION
 RtlpImportAnsiCodePage(PUSHORT TableBase,