mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
[NTOSKRNL/AMD64]
- Add portable kernel initialization code for amd64 only. - Modify amd64 init code accordingly svn path=/trunk/; revision=53714
This commit is contained in:
@@ -312,6 +312,7 @@ elseif(ARCH MATCHES amd64)
|
||||
ke/amd64/interrupt.c
|
||||
ke/amd64/irql.c
|
||||
ke/amd64/kiinit.c
|
||||
ke/amd64/krnlinit.c
|
||||
ke/amd64/spinlock.c
|
||||
ke/amd64/stubs.c
|
||||
ke/amd64/thrdini.c
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <asm.inc>
|
||||
#include <ksamd64.inc>
|
||||
|
||||
EXTERN KiInitializeKernelAndGotoIdleLoop:PROC
|
||||
EXTERN KiSystemStartupBootStack:PROC
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
@@ -21,42 +21,22 @@ EXTERN KiInitializeKernelAndGotoIdleLoop:PROC
|
||||
|
||||
/**
|
||||
* VOID
|
||||
* KiSetupStackAndInitializeKernel(
|
||||
* IN PKPROCESS InitProcess, <rsp + 0x08, rcx>
|
||||
* IN PKTHREAD InitThread, <rsp + 0x10, rdx>
|
||||
* IN PVOID IdleStack, <rsp + 0x18, r8>
|
||||
* IN PKPRCB Prcb, <rsp + 0x20, r9>
|
||||
* IN CCHAR Number, <rsp + 0x28>
|
||||
* IN PLOADER_PARAMETER_BLOCK LoaderBlock) <rsp + 0x30>
|
||||
* KiSwitchToBootStack(
|
||||
* IN ULONG_PTR InitialStack<rcx>)
|
||||
*/
|
||||
PUBLIC KiSetupStackAndInitializeKernel
|
||||
.PROC KiSetupStackAndInitializeKernel
|
||||
|
||||
/* Save current stack */
|
||||
mov rsi, rsp
|
||||
PUBLIC KiSwitchToBootStack
|
||||
.PROC KiSwitchToBootStack
|
||||
|
||||
/* Setup the new stack */
|
||||
mov ax, HEX(18)
|
||||
mov ss, ax
|
||||
mov rsp, r8
|
||||
mov rsp, rcx
|
||||
sub rsp, HEX(300) // FIXME
|
||||
|
||||
/* Copy stack parameters to the new stack */
|
||||
sub rsp, HEX(38)
|
||||
.ENDPROLOG
|
||||
|
||||
mov rdi, rsp
|
||||
movsq
|
||||
movsq
|
||||
movsq
|
||||
movsq
|
||||
movsq
|
||||
movsq
|
||||
movsq
|
||||
jmp KiSystemStartupBootStack
|
||||
|
||||
jmp KiInitializeKernelAndGotoIdleLoop
|
||||
|
||||
.ENDP KiSetupStackAndInitializeKernel
|
||||
.ENDP KiSwitchToBootStack
|
||||
|
||||
END
|
||||
|
||||
|
||||
@@ -369,41 +369,6 @@ KiGetCacheInformation(VOID)
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiInitializeTss(IN PKTSS64 Tss,
|
||||
IN UINT64 Stack)
|
||||
{
|
||||
PKGDTENTRY64 TssEntry;
|
||||
|
||||
/* Get pointer to the GDT entry */
|
||||
TssEntry = KiGetGdtEntry(KeGetPcr()->GdtBase, KGDT64_SYS_TSS);
|
||||
|
||||
/* Initialize the GDT entry */
|
||||
KiInitGdtEntry(TssEntry, (ULONG64)Tss, sizeof(KTSS64), AMD64_TSS, 0);
|
||||
|
||||
/* Zero out the TSS */
|
||||
RtlZeroMemory(Tss, sizeof(KTSS64));
|
||||
|
||||
/* FIXME: I/O Map? */
|
||||
Tss->IoMapBase = 0x68;
|
||||
|
||||
/* Setup ring 0 stack pointer */
|
||||
Tss->Rsp0 = Stack;
|
||||
|
||||
/* Setup a stack for Double Fault Traps */
|
||||
Tss->Ist[1] = (ULONG64)KiDoubleFaultStack;
|
||||
|
||||
/* Setup a stack for CheckAbort Traps */
|
||||
Tss->Ist[2] = (ULONG64)KiDoubleFaultStack;
|
||||
|
||||
/* Setup a stack for NMI Traps */
|
||||
Tss->Ist[3] = (ULONG64)KiDoubleFaultStack;
|
||||
|
||||
/* Load the task register */
|
||||
__ltr(KGDT64_SYS_TSS);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KeFlushCurrentTb(VOID)
|
||||
|
||||
+141
-201
@@ -70,6 +70,15 @@ KiInitMachineDependent(VOID)
|
||||
DPRINT1("PAT support detected but not yet taken advantage of!\n");
|
||||
}
|
||||
|
||||
/* Allocate the IOPM save area. */
|
||||
// Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
|
||||
// PAGE_SIZE * 2,
|
||||
// TAG('K', 'e', ' ', ' '));
|
||||
// if (!Ki386IopmSaveArea)
|
||||
// {
|
||||
// /* Bugcheck. We need this for V86/VDM support. */
|
||||
// KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +119,7 @@ KiInitializePcr(IN PKIPCR Pcr,
|
||||
|
||||
/* Set the Processor Number and current Processor Mask */
|
||||
Pcr->Prcb.Number = (UCHAR)ProcessorNumber;
|
||||
Pcr->Prcb.SetMember = 1 << ProcessorNumber;
|
||||
Pcr->Prcb.SetMember = 1ULL << ProcessorNumber;
|
||||
|
||||
/* Get GDT and IDT descriptors */
|
||||
__sgdt(&GdtDescriptor.Limit);
|
||||
@@ -147,14 +156,20 @@ KiInitializePcr(IN PKIPCR Pcr,
|
||||
Pcr->Irql = PASSIVE_LEVEL;
|
||||
KeSetCurrentIrql(PASSIVE_LEVEL);
|
||||
|
||||
/* Set GS base */
|
||||
__writemsr(X86_MSR_GSBASE, (ULONG64)Pcr);
|
||||
__writemsr(X86_MSR_KERNEL_GSBASE, (ULONG64)Pcr);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeCpuFeatures(ULONG Cpu)
|
||||
KiInitializeCpu(PKPRCB Prcb)
|
||||
{
|
||||
ULONG FeatureBits;
|
||||
|
||||
/* Detect and set the CPU Type */
|
||||
KiSetProcessorType();
|
||||
|
||||
/* Get the processor features for this CPU */
|
||||
FeatureBits = KiGetFeatureBits();
|
||||
|
||||
@@ -172,7 +187,7 @@ KiInitializeCpuFeatures(ULONG Cpu)
|
||||
FeatureBits |= KF_NX_ENABLED;
|
||||
|
||||
/* Save feature bits */
|
||||
KeGetCurrentPrcb()->FeatureBits = FeatureBits;
|
||||
Prcb->FeatureBits = FeatureBits;
|
||||
|
||||
/* Enable fx save restore support */
|
||||
__writecr4(__readcr4() | CR4_FXSR);
|
||||
@@ -188,170 +203,139 @@ KiInitializeCpuFeatures(ULONG Cpu)
|
||||
|
||||
/* Disable x87 fpu exceptions */
|
||||
__writecr0(__readcr0() & ~CR0_NE);
|
||||
|
||||
|
||||
/* LDT is unused */
|
||||
__lldt(0);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiInitializeTss(IN PKTSS64 Tss,
|
||||
IN UINT64 Stack)
|
||||
{
|
||||
PKGDTENTRY64 TssEntry;
|
||||
|
||||
/* Get pointer to the GDT entry */
|
||||
TssEntry = KiGetGdtEntry(KeGetPcr()->GdtBase, KGDT64_SYS_TSS);
|
||||
|
||||
/* Initialize the GDT entry */
|
||||
KiInitGdtEntry(TssEntry, (ULONG64)Tss, sizeof(KTSS64), AMD64_TSS, 0);
|
||||
|
||||
/* Zero out the TSS */
|
||||
RtlZeroMemory(Tss, sizeof(KTSS64));
|
||||
|
||||
/* FIXME: I/O Map? */
|
||||
Tss->IoMapBase = 0x68;
|
||||
|
||||
/* Setup ring 0 stack pointer */
|
||||
Tss->Rsp0 = Stack;
|
||||
|
||||
/* Setup a stack for Double Fault Traps */
|
||||
Tss->Ist[1] = (ULONG64)KiDoubleFaultStack;
|
||||
|
||||
/* Setup a stack for CheckAbort Traps */
|
||||
Tss->Ist[2] = (ULONG64)KiDoubleFaultStack;
|
||||
|
||||
/* Setup a stack for NMI Traps */
|
||||
Tss->Ist[3] = (ULONG64)KiDoubleFaultStack;
|
||||
|
||||
/* Load the task register */
|
||||
__ltr(KGDT64_SYS_TSS);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||
IN PKTHREAD InitThread,
|
||||
IN PVOID IdleStack,
|
||||
IN PKPRCB Prcb,
|
||||
IN CCHAR Number,
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
INIT_FUNCTION
|
||||
KiInitializeKernelMachineDependent(
|
||||
IN PKPRCB Prcb,
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
ULONG PageDirectory[2];
|
||||
PVOID DpcStack;
|
||||
|
||||
/* Detect and set the CPU Type */
|
||||
KiSetProcessorType();
|
||||
|
||||
/* Initialize the Power Management Support for this PRCB */
|
||||
// PoInitializePrcb(Prcb);
|
||||
|
||||
/* Save CPU state */
|
||||
KiSaveProcessorControlState(&Prcb->ProcessorState);
|
||||
|
||||
/* Get cache line information for this CPU */
|
||||
KiGetCacheInformation();
|
||||
|
||||
/* Initialize spinlocks and DPC data */
|
||||
KiInitSpinLocks(Prcb, Number);
|
||||
|
||||
/* Check if this is the Boot CPU */
|
||||
if (Number == 0)
|
||||
{
|
||||
/* Set Node Data */
|
||||
KeNodeBlock[0] = &KiNode0;
|
||||
Prcb->ParentNode = KeNodeBlock[0];
|
||||
KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
|
||||
|
||||
/* Set boot-level flags */
|
||||
KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
|
||||
KeProcessorLevel = (USHORT)Prcb->CpuType;
|
||||
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
|
||||
|
||||
/* Set the current MP Master KPRCB to the Boot PRCB */
|
||||
Prcb->MultiThreadSetMaster = Prcb;
|
||||
|
||||
/* Lower to APC_LEVEL */
|
||||
KeLowerIrql(APC_LEVEL);
|
||||
|
||||
/* Initialize some spinlocks */
|
||||
KeInitializeSpinLock(&KiFreezeExecutionLock);
|
||||
|
||||
/* Initialize portable parts of the OS */
|
||||
KiInitSystem();
|
||||
|
||||
/* Initialize the Idle Process and the Process Listhead */
|
||||
InitializeListHead(&KiProcessListHead);
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KeInitializeProcess(InitProcess,
|
||||
0,
|
||||
0xFFFFFFFF,
|
||||
PageDirectory,
|
||||
FALSE);
|
||||
InitProcess->QuantumReset = MAXCHAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("SMP Boot support not yet present\n");
|
||||
}
|
||||
|
||||
/* HACK for MmUpdatePageDir */
|
||||
((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
|
||||
|
||||
/* Setup the Idle Thread */
|
||||
KeInitializeThread(InitProcess,
|
||||
InitThread,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
IdleStack);
|
||||
|
||||
InitThread->NextProcessor = Number;
|
||||
InitThread->Priority = HIGH_PRIORITY;
|
||||
InitThread->State = Running;
|
||||
InitThread->Affinity = 1 << Number;
|
||||
InitThread->WaitIrql = DISPATCH_LEVEL;
|
||||
InitProcess->ActiveProcessors = 1 << Number;
|
||||
/* Set boot-level flags */
|
||||
KeI386CpuType = Prcb->CpuType;
|
||||
KeI386CpuStep = Prcb->CpuStep;
|
||||
KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
|
||||
KeProcessorLevel = (USHORT)Prcb->CpuType;
|
||||
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
|
||||
|
||||
/* Set basic CPU Features that user mode can read */
|
||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
|
||||
(KeFeatureBits & KF_MMX) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
|
||||
(KeFeatureBits & KF_CMPXCHG8B) ? TRUE: FALSE;
|
||||
(Prcb->FeatureBits & KF_MMX) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
||||
((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI)) ? TRUE: FALSE;
|
||||
((Prcb->FeatureBits & KF_FXSR) && (Prcb->FeatureBits & KF_XMMI)) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
||||
((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI64)) ? TRUE: FALSE;
|
||||
((Prcb->FeatureBits & KF_FXSR) && (Prcb->FeatureBits & KF_XMMI64)) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
||||
(KeFeatureBits & KF_3DNOW) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
|
||||
(KeFeatureBits & KF_RDTSC) ? TRUE: FALSE;
|
||||
(Prcb->FeatureBits & KF_3DNOW) ? TRUE: FALSE;
|
||||
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
|
||||
|
||||
/* Set up the thread-related fields in the PRCB */
|
||||
Prcb->CurrentThread = InitThread;
|
||||
Prcb->NextThread = NULL;
|
||||
Prcb->IdleThread = InitThread;
|
||||
/* Set the default NX policy (opt-in) */
|
||||
SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN;
|
||||
|
||||
/* Initialize the Kernel Executive */
|
||||
ExpInitializeExecutive(Number, LoaderBlock);
|
||||
|
||||
/* Only do this on the boot CPU */
|
||||
if (Number == 0)
|
||||
/* Check if NPX is always on */
|
||||
if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON"))
|
||||
{
|
||||
/* Calculate the time reciprocal */
|
||||
KiTimeIncrementReciprocal =
|
||||
KiComputeReciprocal(KeMaximumIncrement,
|
||||
&KiTimeIncrementShiftCount);
|
||||
|
||||
/* Update DPC Values in case they got updated by the executive */
|
||||
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
|
||||
Prcb->MinimumDpcRate = KiMinimumDpcRate;
|
||||
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
|
||||
|
||||
/* Allocate the DPC Stack */
|
||||
DpcStack = MmCreateKernelStack(FALSE, 0);
|
||||
if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
|
||||
Prcb->DpcStack = DpcStack;
|
||||
|
||||
/* Allocate the IOPM save area. */
|
||||
// Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
|
||||
// PAGE_SIZE * 2,
|
||||
// TAG('K', 'e', ' ', ' '));
|
||||
// if (!Ki386IopmSaveArea)
|
||||
// {
|
||||
// /* Bugcheck. We need this for V86/VDM support. */
|
||||
// KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0);
|
||||
// }
|
||||
/* Set it always on */
|
||||
SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON;
|
||||
Prcb->FeatureBits |= KF_NX_ENABLED;
|
||||
}
|
||||
else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT"))
|
||||
{
|
||||
/* Set it in opt-out mode */
|
||||
SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT;
|
||||
Prcb->FeatureBits |= KF_NX_ENABLED;
|
||||
}
|
||||
else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) ||
|
||||
(strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE")))
|
||||
{
|
||||
/* Set the feature bits */
|
||||
Prcb->FeatureBits |= KF_NX_ENABLED;
|
||||
}
|
||||
else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) ||
|
||||
(strstr(KeLoaderBlock->LoadOptions, "EXECUTE")))
|
||||
{
|
||||
/* Set disabled mode */
|
||||
SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF;
|
||||
Prcb->FeatureBits |= KF_NX_DISABLED;
|
||||
}
|
||||
|
||||
/* Raise to Dispatch */
|
||||
KfRaiseIrql(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/* Set the Idle Priority to 0. This will jump into Phase 1 */
|
||||
KeSetPriorityThread(InitThread, 0);
|
||||
static LDR_DATA_TABLE_ENTRY LdrCoreEntries[3];
|
||||
|
||||
/* If there's no thread scheduled, put this CPU in the Idle summary */
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
|
||||
KiReleasePrcbLock(Prcb);
|
||||
void
|
||||
KiInitModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLIST_ENTRY Entry;
|
||||
ULONG i;
|
||||
|
||||
/* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
|
||||
KfRaiseIrql(HIGH_LEVEL);
|
||||
LoaderBlock->Prcb = 0;
|
||||
/* Initialize the list head */
|
||||
InitializeListHead(&PsLoadedModuleList);
|
||||
|
||||
/* Loop the first 3 entries */
|
||||
for (Entry = LoaderBlock->LoadOrderListHead.Flink, i = 0;
|
||||
Entry != &LoaderBlock->LoadOrderListHead && i < 3;
|
||||
Entry = Entry->Flink, i++)
|
||||
{
|
||||
/* Get the data table entry */
|
||||
LdrEntry = CONTAINING_RECORD(Entry,
|
||||
LDR_DATA_TABLE_ENTRY,
|
||||
InLoadOrderLinks);
|
||||
|
||||
/* Copy the entry */
|
||||
LdrCoreEntries[i] = *LdrEntry;
|
||||
|
||||
/* Insert the copy into the list */
|
||||
InsertTailList(&PsLoadedModuleList, &LdrCoreEntries[i].InLoadOrderLinks);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
ULONG Cpu;
|
||||
CCHAR Cpu;
|
||||
PKTHREAD InitialThread;
|
||||
ULONG64 InitialStack;
|
||||
PKIPCR Pcr;
|
||||
@@ -367,11 +351,12 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
KeLoaderBlock = LoaderBlock;
|
||||
|
||||
/* Get the current CPU number */
|
||||
Cpu = KeNumberProcessors++; // FIXME
|
||||
Cpu = (CCHAR)KeNumberProcessors++; // FIXME
|
||||
|
||||
/* LoaderBlock initialization for Cpu 0 */
|
||||
if (Cpu == 0)
|
||||
{
|
||||
FrLdrDbgPrint("LoaderBlock->Prcb=%p\n", LoaderBlock->Prcb);
|
||||
/* Set the initial stack, idle thread and process */
|
||||
LoaderBlock->KernelStack = (ULONG_PTR)P0BootStack;
|
||||
LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread;
|
||||
@@ -385,13 +370,6 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
/* Set the PRCB for this Processor */
|
||||
KiProcessorBlock[Cpu] = &Pcr->Prcb;
|
||||
|
||||
/* Set GS base */
|
||||
__writemsr(X86_MSR_GSBASE, (ULONG64)Pcr);
|
||||
__writemsr(X86_MSR_KERNEL_GSBASE, (ULONG64)Pcr);
|
||||
|
||||
/* LDT is unused */
|
||||
__lldt(0);
|
||||
|
||||
/* Align stack to 16 bytes */
|
||||
LoaderBlock->KernelStack &= ~(16 - 1);
|
||||
|
||||
@@ -399,9 +377,6 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
InitialStack = LoaderBlock->KernelStack; // Checkme
|
||||
InitialThread = (PKTHREAD)LoaderBlock->Thread;
|
||||
|
||||
/* Clean the APC List Head */
|
||||
InitializeListHead(&InitialThread->ApcState.ApcListHead[KernelMode]);
|
||||
|
||||
/* Set us as the current process */
|
||||
InitialThread->ApcState.Process = (PVOID)LoaderBlock->Process;
|
||||
|
||||
@@ -409,34 +384,34 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
KiInitializePcr(Pcr, Cpu, InitialThread, (PVOID)KiDoubleFaultStack);
|
||||
|
||||
/* Initialize the CPU features */
|
||||
KiInitializeCpuFeatures(Cpu);
|
||||
KiInitializeCpu(&Pcr->Prcb);
|
||||
|
||||
/* Initial setup for the boot CPU */
|
||||
if (Cpu == 0)
|
||||
{
|
||||
/* Initialize the module list (ntos, hal, kdcom) */
|
||||
KiInitModuleList(LoaderBlock);
|
||||
|
||||
/* Setup the TSS descriptors and entries */
|
||||
KiInitializeTss(Pcr->TssBase, InitialStack);
|
||||
|
||||
/* Setup the IDT */
|
||||
KeInitExceptions();
|
||||
|
||||
/* HACK: misuse this function to pass a function pointer to kdcom */
|
||||
KdDebuggerInitialize1((PVOID)FrLdrDbgPrint);
|
||||
|
||||
/* Initialize debugging system */
|
||||
/* Initialize debugging system */
|
||||
KdInitSystem(0, KeLoaderBlock);
|
||||
|
||||
/* Check for break-in */
|
||||
if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||
|
||||
/* Hack! Wait for the debugger! */
|
||||
#ifdef _WINKD_
|
||||
#ifdef _WINKD_x
|
||||
while (!KdPollBreakIn());
|
||||
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||
#endif
|
||||
}
|
||||
|
||||
DPRINT("Pcr = %p, Gdt = %p, Idt = %p, Tss = %p\n",
|
||||
DPRINT1("Pcr = %p, Gdt = %p, Idt = %p, Tss = %p\n",
|
||||
Pcr, Pcr->GdtBase, Pcr->IdtBase, Pcr->TssBase);
|
||||
|
||||
/* Acquire lock */
|
||||
@@ -444,13 +419,13 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
/* Loop until lock is free */
|
||||
while ((*(volatile KSPIN_LOCK*)&KiFreezeExecutionLock) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the Processor with HAL */
|
||||
HalInitializeProcessor(Cpu, KeLoaderBlock);
|
||||
|
||||
/* Set processor as active */
|
||||
KeActiveProcessors |= 1 << Cpu;
|
||||
KeActiveProcessors |= 1ULL << Cpu;
|
||||
|
||||
/* Release lock */
|
||||
InterlockedAnd64((PLONG64)&KiFreezeExecutionLock, 0);
|
||||
@@ -458,45 +433,10 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
/* Raise to HIGH_LEVEL */
|
||||
KfRaiseIrql(HIGH_LEVEL);
|
||||
|
||||
/* Machine specific kernel initialization */
|
||||
if (Cpu == 0) KiInitializeKernelMachineDependent(&Pcr->Prcb, LoaderBlock);
|
||||
|
||||
/* Switch to new kernel stack and start kernel bootstrapping */
|
||||
KiSetupStackAndInitializeKernel(&KiInitialProcess.Pcb,
|
||||
InitialThread,
|
||||
(PVOID)InitialStack,
|
||||
&Pcr->Prcb,
|
||||
(CCHAR)Cpu,
|
||||
KeLoaderBlock);
|
||||
KiSwitchToBootStack(InitialStack & ~3);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeKernelAndGotoIdleLoop(IN PKPROCESS InitProcess,
|
||||
IN PKTHREAD InitThread,
|
||||
IN PVOID IdleStack,
|
||||
IN PKPRCB Prcb,
|
||||
IN CCHAR Number,
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
// DbgBreakPointWithStatus(0);
|
||||
|
||||
/* Initialize kernel */
|
||||
KiInitializeKernel(InitProcess,
|
||||
InitThread,
|
||||
IdleStack,
|
||||
Prcb,
|
||||
Number,
|
||||
KeLoaderBlock);
|
||||
|
||||
/* Set the priority of this thread to 0 */
|
||||
InitThread->Priority = 0;
|
||||
|
||||
/* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */
|
||||
_enable();
|
||||
KeLowerIrql(DISPATCH_LEVEL);
|
||||
|
||||
/* Set the right wait IRQL */
|
||||
InitThread->WaitIrql = DISPATCH_LEVEL;
|
||||
|
||||
/* Jump into the idle loop */
|
||||
KiIdleLoop();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/krnlinit.c
|
||||
* PURPOSE: Portable part of kernel initialization
|
||||
* PROGRAMMERS: Timo Kreuzer ([email protected])
|
||||
* Alex Ionescu ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
extern ULONG_PTR MainSSDT[];
|
||||
extern UCHAR MainSSPT[];
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
INIT_FUNCTION
|
||||
KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||
IN PKTHREAD InitThread,
|
||||
IN PVOID IdleStack,
|
||||
IN PKPRCB Prcb,
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitalizeHandBuiltThread(
|
||||
IN PKTHREAD Thread,
|
||||
IN PKPROCESS Process,
|
||||
IN PVOID Stack)
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
|
||||
/* Setup the Thread */
|
||||
KeInitializeThread(Process, Thread, NULL, NULL, NULL, NULL, NULL, Stack);
|
||||
|
||||
Thread->NextProcessor = Prcb->Number;
|
||||
Thread->Priority = HIGH_PRIORITY;
|
||||
Thread->State = Running;
|
||||
Thread->Affinity = (ULONG_PTR)1 << Prcb->Number;
|
||||
Thread->WaitIrql = DISPATCH_LEVEL;
|
||||
Process->ActiveProcessors |= (ULONG_PTR)1 << Prcb->Number;
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
INIT_FUNCTION
|
||||
KiSystemStartupBootStack(VOID)
|
||||
{
|
||||
PLOADER_PARAMETER_BLOCK LoaderBlock = KeLoaderBlock; // hack
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
PKTHREAD Thread = (PKTHREAD)KeLoaderBlock->Thread;
|
||||
PKPROCESS Process = Thread->ApcState.Process;
|
||||
PVOID KernelStack = (PVOID)KeLoaderBlock->KernelStack;
|
||||
|
||||
/* Initialize the Power Management Support for this PRCB */
|
||||
PoInitializePrcb(Prcb);
|
||||
|
||||
/* Save CPU state */
|
||||
KiSaveProcessorControlState(&Prcb->ProcessorState);
|
||||
|
||||
/* Get cache line information for this CPU */
|
||||
KiGetCacheInformation();
|
||||
|
||||
/* Initialize spinlocks and DPC data */
|
||||
KiInitSpinLocks(Prcb, Prcb->Number);
|
||||
|
||||
/* Set up the thread-related fields in the PRCB */
|
||||
Prcb->CurrentThread = Thread;
|
||||
Prcb->NextThread = NULL;
|
||||
Prcb->IdleThread = Thread;
|
||||
|
||||
/* Initialize PRCB pool lookaside pointers */
|
||||
ExInitPoolLookasidePointers();
|
||||
|
||||
/* Check if this is the boot cpu */
|
||||
if (Prcb->Number == 0)
|
||||
{
|
||||
/* Initialize the kernel */
|
||||
KiInitializeKernel(Process, Thread, KernelStack, Prcb, LoaderBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize the startup thread */
|
||||
KiInitalizeHandBuiltThread(Thread, Process, KernelStack);
|
||||
|
||||
/* Initialize cpu with HAL */
|
||||
if (!HalInitSystem(0, LoaderBlock))
|
||||
{
|
||||
/* Initialization failed */
|
||||
KeBugCheck(HAL_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/* Raise to Dispatch */
|
||||
KfRaiseIrql(DISPATCH_LEVEL);
|
||||
|
||||
/* Set the Idle Priority to 0. This will jump into Phase 1 */
|
||||
KeSetPriorityThread(Thread, 0);
|
||||
|
||||
/* If there's no thread scheduled, put this CPU in the Idle summary */
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
if (!Prcb->NextThread) KiIdleSummary |= (ULONG_PTR)1 << Prcb->Number;
|
||||
KiReleasePrcbLock(Prcb);
|
||||
|
||||
/* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
|
||||
KfRaiseIrql(HIGH_LEVEL);
|
||||
LoaderBlock->Prcb = 0;
|
||||
|
||||
/* Set the priority of this thread to 0 */
|
||||
Thread = KeGetCurrentThread();
|
||||
Thread->Priority = 0;
|
||||
|
||||
/* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */
|
||||
_enable();
|
||||
KeLowerIrql(DISPATCH_LEVEL);
|
||||
|
||||
/* Set the right wait IRQL */
|
||||
Thread->WaitIrql = DISPATCH_LEVEL;
|
||||
|
||||
/* Jump into the idle loop */
|
||||
KiIdleLoop();
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
INIT_FUNCTION
|
||||
KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||
IN PKTHREAD InitThread,
|
||||
IN PVOID IdleStack,
|
||||
IN PKPRCB Prcb,
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
ULONG PageDirectory[2];
|
||||
PVOID DpcStack;
|
||||
ULONG i;
|
||||
|
||||
/* Set Node Data */
|
||||
KeNodeBlock[0] = &KiNode0;
|
||||
Prcb->ParentNode = KeNodeBlock[0];
|
||||
KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
|
||||
|
||||
/* Set boot-level flags */
|
||||
KeFeatureBits = Prcb->FeatureBits;
|
||||
|
||||
/* Set the current MP Master KPRCB to the Boot PRCB */
|
||||
Prcb->MultiThreadSetMaster = Prcb;
|
||||
|
||||
/* Lower to APC_LEVEL */
|
||||
KeLowerIrql(APC_LEVEL);
|
||||
|
||||
/* Initialize Bugcheck Callback data */
|
||||
InitializeListHead(&KeBugcheckCallbackListHead);
|
||||
InitializeListHead(&KeBugcheckReasonCallbackListHead);
|
||||
KeInitializeSpinLock(&BugCheckCallbackLock);
|
||||
|
||||
/* Initialize the Timer Expiration DPC */
|
||||
KeInitializeDpc(&KiTimerExpireDpc, KiTimerExpiration, NULL);
|
||||
KeSetTargetProcessorDpc(&KiTimerExpireDpc, 0);
|
||||
|
||||
/* Initialize Profiling data */
|
||||
KeInitializeSpinLock(&KiProfileLock);
|
||||
InitializeListHead(&KiProfileListHead);
|
||||
InitializeListHead(&KiProfileSourceListHead);
|
||||
|
||||
/* Loop the timer table */
|
||||
for (i = 0; i < TIMER_TABLE_SIZE; i++)
|
||||
{
|
||||
/* Initialize the list and entries */
|
||||
InitializeListHead(&KiTimerTableListHead[i].Entry);
|
||||
KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
|
||||
KiTimerTableListHead[i].Time.LowPart = 0;
|
||||
}
|
||||
|
||||
/* Initialize the Swap event and all swap lists */
|
||||
KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE);
|
||||
InitializeListHead(&KiProcessInSwapListHead);
|
||||
InitializeListHead(&KiProcessOutSwapListHead);
|
||||
InitializeListHead(&KiStackInSwapListHead);
|
||||
|
||||
/* Initialize the mutex for generic DPC calls */
|
||||
ExInitializeFastMutex(&KiGenericCallDpcMutex);
|
||||
|
||||
/* Initialize the syscall table */
|
||||
KeServiceDescriptorTable[0].Base = MainSSDT;
|
||||
KeServiceDescriptorTable[0].Count = NULL;
|
||||
KeServiceDescriptorTable[0].Limit = KiServiceLimit;
|
||||
KeServiceDescriptorTable[1].Limit = 0;
|
||||
KeServiceDescriptorTable[0].Number = MainSSPT;
|
||||
|
||||
/* Copy the the current table into the shadow table for win32k */
|
||||
RtlCopyMemory(KeServiceDescriptorTableShadow,
|
||||
KeServiceDescriptorTable,
|
||||
sizeof(KeServiceDescriptorTable));
|
||||
|
||||
/* Initialize the Idle Process and the Process Listhead */
|
||||
InitializeListHead(&KiProcessListHead);
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KeInitializeProcess(InitProcess,
|
||||
0,
|
||||
0xFFFFFFFF,
|
||||
PageDirectory,
|
||||
FALSE);
|
||||
InitProcess->QuantumReset = MAXCHAR;
|
||||
|
||||
/* Initialize the startup thread */
|
||||
KiInitalizeHandBuiltThread(InitThread, InitProcess, IdleStack);
|
||||
|
||||
/* Initialize the Kernel Executive */
|
||||
ExpInitializeExecutive(0, LoaderBlock);
|
||||
|
||||
/* Calculate the time reciprocal */
|
||||
KiTimeIncrementReciprocal =
|
||||
KiComputeReciprocal(KeMaximumIncrement,
|
||||
&KiTimeIncrementShiftCount);
|
||||
|
||||
/* Update DPC Values in case they got updated by the executive */
|
||||
Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
|
||||
Prcb->MinimumDpcRate = KiMinimumDpcRate;
|
||||
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
|
||||
|
||||
/* Allocate the DPC Stack */
|
||||
DpcStack = MmCreateKernelStack(FALSE, 0);
|
||||
if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
|
||||
Prcb->DpcStack = DpcStack;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user