VOID DECLSPEC_NORETURN HalpTrap06() { /* Restore ES/DS to known good values first */ Ke386SetEs(KGDT_R3_DATA | RPL_MASK); Ke386SetDs(KGDT_R3_DATA | RPL_MASK); Ke386SetFs(KGDT_R0_PCR); /* Restore the stack */ KeGetPcr()->TSS->Esp0 = HalpSavedEsp0; /* Return back to where we left */ longjmp(HalpSavedContext, 1); UNREACHABLE; }
VOID NTAPI INIT_FUNCTION KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { ULONG Cpu; PKTHREAD InitialThread; ULONG InitialStack; PKGDTENTRY Gdt; PKIDTENTRY Idt; KIDTENTRY NmiEntry, DoubleFaultEntry; PKTSS Tss; PKIPCR Pcr; /* Boot cycles timestamp */ BootCycles = __rdtsc(); /* Save the loader block and get the current CPU */ KeLoaderBlock = LoaderBlock; Cpu = KeNumberProcessors; if (!Cpu) { /* If this is the boot CPU, set FS and the CPU Number*/ Ke386SetFs(KGDT_R0_PCR); __writefsdword(KPCR_PROCESSOR_NUMBER, Cpu); /* Set the initial stack and idle thread as well */ LoaderBlock->KernelStack = (ULONG_PTR)P0BootStack; LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread; } /* Save the initial thread and stack */ InitialStack = LoaderBlock->KernelStack; InitialThread = (PKTHREAD)LoaderBlock->Thread; /* Clean the APC List Head */ InitializeListHead(&InitialThread->ApcState.ApcListHead[KernelMode]); /* Initialize the machine type */ KiInitializeMachineType(); /* Skip initial setup if this isn't the Boot CPU */ if (Cpu) goto AppCpuInit; /* Get GDT, IDT, PCR and TSS pointers */ KiGetMachineBootPointers(&Gdt, &Idt, &Pcr, &Tss); /* Setup the TSS descriptors and entries */ Ki386InitializeTss(Tss, Idt, Gdt); /* Initialize the PCR */ RtlZeroMemory(Pcr, PAGE_SIZE); KiInitializePcr(Cpu, Pcr, Idt, Gdt, Tss, InitialThread, (PVOID)KiDoubleFaultStack); /* Set us as the current process */ InitialThread->ApcState.Process = &KiInitialProcess.Pcb; /* Clear DR6/7 to cleanup bootloader debugging */ __writefsdword(KPCR_TEB, 0); __writefsdword(KPCR_DR6, 0); __writefsdword(KPCR_DR7, 0); /* Setup the IDT */ KeInitExceptions(); /* Load Ring 3 selectors for DS/ES */ Ke386SetDs(KGDT_R3_DATA | RPL_MASK); Ke386SetEs(KGDT_R3_DATA | RPL_MASK); /* Save NMI and double fault traps */ RtlCopyMemory(&NmiEntry, &Idt[2], sizeof(KIDTENTRY)); RtlCopyMemory(&DoubleFaultEntry, &Idt[8], sizeof(KIDTENTRY)); /* Copy kernel's trap handlers */ RtlCopyMemory(Idt, (PVOID)KiIdtDescriptor.Base, KiIdtDescriptor.Limit + 1); /* Restore NMI and double fault */ RtlCopyMemory(&Idt[2], &NmiEntry, sizeof(KIDTENTRY)); RtlCopyMemory(&Idt[8], &DoubleFaultEntry, sizeof(KIDTENTRY)); AppCpuInit: /* Loop until we can release the freeze lock */ do { /* Loop until execution can continue */ while (*(volatile PKSPIN_LOCK*)&KiFreezeExecutionLock == (PVOID)1); } while(InterlockedBitTestAndSet((PLONG)&KiFreezeExecutionLock, 0)); /* Setup CPU-related fields */ __writefsdword(KPCR_NUMBER, Cpu); __writefsdword(KPCR_SET_MEMBER, 1 << Cpu); __writefsdword(KPCR_SET_MEMBER_COPY, 1 << Cpu); __writefsdword(KPCR_PRCB_SET_MEMBER, 1 << Cpu); /* Initialize the Processor with HAL */ HalInitializeProcessor(Cpu, KeLoaderBlock); /* Set active processors */ KeActiveProcessors |= __readfsdword(KPCR_SET_MEMBER); KeNumberProcessors++; /* Check if this is the boot CPU */ if (!Cpu) { /* Initialize debugging system */ KdInitSystem(0, KeLoaderBlock); /* Check for break-in */ if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); } /* Raise to HIGH_LEVEL */ KfRaiseIrql(HIGH_LEVEL); /* Switch to new kernel stack and start kernel bootstrapping */ KiSwitchToBootStack(InitialStack & ~3); }