Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkrnlinit.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
1.7.6.1
|