ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

krnlinit.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/ke/krnlinit.c
00005  * PURPOSE:         Portable part of kernel initialization
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 #include <internal/napi.h>
00015 
00016 /* GLOBALS *******************************************************************/
00017 
00018 /* Portable CPU Features and Flags */
00019 USHORT KeProcessorArchitecture;
00020 USHORT KeProcessorLevel;
00021 USHORT KeProcessorRevision;
00022 ULONG KeFeatureBits;
00023 KAFFINITY KeActiveProcessors = 1;
00024 
00025 /* System call count */
00026 ULONG KiServiceLimit = NUMBER_OF_SYSCALLS;
00027 
00028 /* ARC Loader Block */
00029 PLOADER_PARAMETER_BLOCK KeLoaderBlock;
00030 
00031 /* PRCB Array */
00032 PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS];
00033 
00034 /* Number of processors */
00035 UCHAR KeNumberProcessors = 0;
00036 
00037 /* NUMA Node Support */
00038 KNODE KiNode0;
00039 PKNODE KeNodeBlock[1];
00040 UCHAR KeNumberNodes = 1;
00041 UCHAR KeProcessNodeSeed;
00042 
00043 /* Initial Process and Thread */
00044 ETHREAD KiInitialThread;
00045 EPROCESS KiInitialProcess;
00046 
00047 /* System-defined Spinlocks */
00048 KSPIN_LOCK KiDispatcherLock;
00049 KSPIN_LOCK MmPfnLock;
00050 KSPIN_LOCK MmSystemSpaceLock;
00051 KSPIN_LOCK CcBcbSpinLock;
00052 KSPIN_LOCK CcMasterSpinLock;
00053 KSPIN_LOCK CcVacbSpinLock;
00054 KSPIN_LOCK CcWorkQueueSpinLock;
00055 KSPIN_LOCK NonPagedPoolLock;
00056 KSPIN_LOCK MmNonPagedPoolLock;
00057 KSPIN_LOCK IopCancelSpinLock;
00058 KSPIN_LOCK IopVpbSpinLock;
00059 KSPIN_LOCK IopDatabaseLock;
00060 KSPIN_LOCK IopCompletionLock;
00061 KSPIN_LOCK NtfsStructLock;
00062 KSPIN_LOCK AfdWorkQueueSpinLock;
00063 KSPIN_LOCK KiTimerTableLock[16];
00064 KSPIN_LOCK KiReverseStallIpiLock;
00065 
00066 /* FUNCTIONS *****************************************************************/
00067 
00068 VOID
00069 NTAPI
00070 INIT_FUNCTION
00071 KiInitSystem(VOID)
00072 {
00073     ULONG i;
00074 
00075     /* Initialize Bugcheck Callback data */
00076     InitializeListHead(&KeBugcheckCallbackListHead);
00077     InitializeListHead(&KeBugcheckReasonCallbackListHead);
00078     KeInitializeSpinLock(&BugCheckCallbackLock);
00079 
00080     /* Initialize the Timer Expiration DPC */
00081     KeInitializeDpc(&KiTimerExpireDpc, KiTimerExpiration, NULL);
00082     KeSetTargetProcessorDpc(&KiTimerExpireDpc, 0);
00083 
00084     /* Initialize Profiling data */
00085     KeInitializeSpinLock(&KiProfileLock);
00086     InitializeListHead(&KiProfileListHead);
00087     InitializeListHead(&KiProfileSourceListHead);
00088 
00089     /* Loop the timer table */
00090     for (i = 0; i < TIMER_TABLE_SIZE; i++)
00091     {
00092         /* Initialize the list and entries */
00093         InitializeListHead(&KiTimerTableListHead[i].Entry);
00094         KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
00095         KiTimerTableListHead[i].Time.LowPart = 0;
00096     }
00097 
00098     /* Initialize the Swap event and all swap lists */
00099     KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE);
00100     InitializeListHead(&KiProcessInSwapListHead);
00101     InitializeListHead(&KiProcessOutSwapListHead);
00102     InitializeListHead(&KiStackInSwapListHead);
00103 
00104     /* Initialize the mutex for generic DPC calls */
00105     ExInitializeFastMutex(&KiGenericCallDpcMutex);
00106 
00107     /* Initialize the syscall table */
00108     KeServiceDescriptorTable[0].Base = MainSSDT;
00109     KeServiceDescriptorTable[0].Count = NULL;
00110     KeServiceDescriptorTable[0].Limit = KiServiceLimit;
00111     KeServiceDescriptorTable[1].Limit = 0;
00112     KeServiceDescriptorTable[0].Number = MainSSPT;
00113 
00114     /* Copy the the current table into the shadow table for win32k */
00115     RtlCopyMemory(KeServiceDescriptorTableShadow,
00116                   KeServiceDescriptorTable,
00117                   sizeof(KeServiceDescriptorTable));
00118 }
00119 
00120 LARGE_INTEGER
00121 NTAPI
00122 INIT_FUNCTION
00123 KiComputeReciprocal(IN LONG Divisor,
00124                     OUT PUCHAR Shift)
00125 {
00126     LARGE_INTEGER Reciprocal = {{0, 0}};
00127     LONG BitCount = 0, Remainder = 1;
00128 
00129     /* Start by calculating the remainder */
00130     while (Reciprocal.HighPart >= 0)
00131     {
00132         /* Increase the loop (bit) count */
00133         BitCount++;
00134 
00135         /* Calculate the current fraction */
00136         Reciprocal.HighPart = (Reciprocal.HighPart << 1) |
00137                               (Reciprocal.LowPart >> 31);
00138         Reciprocal.LowPart <<= 1;
00139 
00140         /* Double the remainder and see if we went past the divisor */
00141         Remainder <<= 1;
00142         if (Remainder >= Divisor)
00143         {
00144             /* Set the low-bit and calculate the new remainder */
00145             Remainder -= Divisor;
00146             Reciprocal.LowPart |= 1;
00147         }
00148     }
00149 
00150     /* Check if we have a remainder */
00151     if (Remainder)
00152     {
00153         /* Check if the current fraction value is too large */
00154         if ((Reciprocal.LowPart == 0xFFFFFFFF) &&
00155             (Reciprocal.HighPart == (LONG)0xFFFFFFFF))
00156         {
00157             /* Set the high bit and reduce the bit count */
00158             Reciprocal.LowPart = 0;
00159             Reciprocal.HighPart = 0x80000000;
00160             BitCount--;
00161         }
00162         else
00163         {
00164             /* Check if only the lowest bits got too large */
00165             if (Reciprocal.LowPart == 0xFFFFFFFF)
00166             {
00167                 /* Reset them and increase the high bits instead */
00168                 Reciprocal.LowPart = 0;
00169                 Reciprocal.HighPart++;
00170             }
00171             else
00172             {
00173                 /* All is well, increase the low bits */
00174                 Reciprocal.LowPart++;
00175             }
00176         }
00177     }
00178 
00179     /* Now calculate the actual shift and return the reciprocal */
00180     *Shift = (UCHAR)BitCount - 64;
00181     return Reciprocal;
00182 }
00183 
00184 VOID
00185 NTAPI
00186 INIT_FUNCTION
00187 KiInitSpinLocks(IN PKPRCB Prcb,
00188                 IN CCHAR Number)
00189 {
00190     ULONG i;
00191 
00192     /* Initialize Dispatcher Fields */
00193     Prcb->QueueIndex = 1;
00194     Prcb->ReadySummary = 0;
00195     Prcb->DeferredReadyListHead.Next = NULL;
00196     for (i = 0; i < MAXIMUM_PRIORITY; i++)
00197     {
00198         /* Initialize the ready list */
00199         InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
00200     }
00201 
00202     /* Initialize DPC Fields */
00203     InitializeListHead(&Prcb->DpcData[DPC_NORMAL].DpcListHead);
00204     KeInitializeSpinLock(&Prcb->DpcData[DPC_NORMAL].DpcLock);
00205     Prcb->DpcData[DPC_NORMAL].DpcQueueDepth = 0;
00206     Prcb->DpcData[DPC_NORMAL].DpcCount = 0;
00207     Prcb->DpcRoutineActive = FALSE;
00208     Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
00209     Prcb->MinimumDpcRate = KiMinimumDpcRate;
00210     Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
00211     KeInitializeDpc(&Prcb->CallDpc, NULL, NULL);
00212     KeSetTargetProcessorDpc(&Prcb->CallDpc, Number);
00213     KeSetImportanceDpc(&Prcb->CallDpc, HighImportance);
00214 
00215     /* Initialize the Wait List Head */
00216     InitializeListHead(&Prcb->WaitListHead);
00217 
00218     /* Initialize Queued Spinlocks */
00219     Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;
00220     Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;
00221     Prcb->LockQueue[LockQueueExpansionLock].Next = NULL;
00222     Prcb->LockQueue[LockQueueExpansionLock].Lock = NULL;
00223     Prcb->LockQueue[LockQueuePfnLock].Next = NULL;
00224     Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;
00225     Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;
00226     Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;
00227     Prcb->LockQueue[LockQueueBcbLock].Next = NULL;
00228     Prcb->LockQueue[LockQueueBcbLock].Lock = &CcBcbSpinLock;
00229     Prcb->LockQueue[LockQueueMasterLock].Next = NULL;
00230     Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;
00231     Prcb->LockQueue[LockQueueVacbLock].Next = NULL;
00232     Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;
00233     Prcb->LockQueue[LockQueueWorkQueueLock].Next = NULL;
00234     Prcb->LockQueue[LockQueueWorkQueueLock].Lock = &CcWorkQueueSpinLock;
00235     Prcb->LockQueue[LockQueueNonPagedPoolLock].Next = NULL;
00236     Prcb->LockQueue[LockQueueNonPagedPoolLock].Lock = &NonPagedPoolLock;
00237     Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Next = NULL;
00238     Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Lock = &MmNonPagedPoolLock;
00239     Prcb->LockQueue[LockQueueIoCancelLock].Next = NULL;
00240     Prcb->LockQueue[LockQueueIoCancelLock].Lock = &IopCancelSpinLock;
00241     Prcb->LockQueue[LockQueueIoVpbLock].Next = NULL;
00242     Prcb->LockQueue[LockQueueIoVpbLock].Lock = &IopVpbSpinLock;
00243     Prcb->LockQueue[LockQueueIoDatabaseLock].Next = NULL;
00244     Prcb->LockQueue[LockQueueIoDatabaseLock].Lock = &IopDatabaseLock;
00245     Prcb->LockQueue[LockQueueIoCompletionLock].Next = NULL;
00246     Prcb->LockQueue[LockQueueIoCompletionLock].Lock = &IopCompletionLock;
00247     Prcb->LockQueue[LockQueueNtfsStructLock].Next = NULL;
00248     Prcb->LockQueue[LockQueueNtfsStructLock].Lock = &NtfsStructLock;
00249     Prcb->LockQueue[LockQueueAfdWorkQueueLock].Next = NULL;
00250     Prcb->LockQueue[LockQueueAfdWorkQueueLock].Lock = &AfdWorkQueueSpinLock;
00251     Prcb->LockQueue[LockQueueUnusedSpare16].Next = NULL;
00252     Prcb->LockQueue[LockQueueUnusedSpare16].Lock = NULL;
00253 
00254     /* Loop timer locks */
00255     for (i = 0; i < LOCK_QUEUE_TIMER_TABLE_LOCKS; i++)
00256     {
00257         /* Initialize the lock and setup the Queued Spinlock */
00258         KeInitializeSpinLock(&KiTimerTableLock[i]);
00259         Prcb->LockQueue[LockQueueTimerTableLock + i].Next = NULL;
00260         Prcb->LockQueue[LockQueueTimerTableLock + i].Lock =
00261             &KiTimerTableLock[i];
00262     }
00263 
00264     /* Initialize the PRCB lock */
00265     KeInitializeSpinLock(&Prcb->PrcbLock);
00266 
00267     /* Check if this is the boot CPU */
00268     if (!Number)
00269     {
00270         /* Initialize the lock themselves */
00271         KeInitializeSpinLock(&KiDispatcherLock);
00272         KeInitializeSpinLock(&KiReverseStallIpiLock);
00273         KeInitializeSpinLock(&MmPfnLock);
00274         KeInitializeSpinLock(&MmSystemSpaceLock);
00275         KeInitializeSpinLock(&CcBcbSpinLock);
00276         KeInitializeSpinLock(&CcMasterSpinLock);
00277         KeInitializeSpinLock(&CcVacbSpinLock);
00278         KeInitializeSpinLock(&CcWorkQueueSpinLock);
00279         KeInitializeSpinLock(&IopCancelSpinLock);
00280         KeInitializeSpinLock(&IopCompletionLock);
00281         KeInitializeSpinLock(&IopDatabaseLock);
00282         KeInitializeSpinLock(&IopVpbSpinLock);
00283         KeInitializeSpinLock(&NonPagedPoolLock);
00284         KeInitializeSpinLock(&MmNonPagedPoolLock);
00285         KeInitializeSpinLock(&NtfsStructLock);
00286         KeInitializeSpinLock(&AfdWorkQueueSpinLock);
00287     }
00288 }
00289 
00290 BOOLEAN
00291 NTAPI
00292 INIT_FUNCTION
00293 KeInitSystem(VOID)
00294 {
00295     /* Check if Threaded DPCs are enabled */
00296     if (KeThreadDpcEnable)
00297     {
00298         /* FIXME: TODO */
00299         DPRINT1("Threaded DPCs not yet supported\n");
00300     }
00301 
00302     /* Initialize non-portable parts of the kernel */
00303     KiInitMachineDependent();
00304     return TRUE;
00305 }

Generated on Sat May 26 2012 04:36:19 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.