首先,时钟中断属于硬件中断,IRQL为28,仅次于蓝屏,电源和IPI,属于很高级别了,所以不知道接下来的调试会不会很顺利,不说了,试试看看
擦,搜索了下,WRK居然没有时钟中断函数,看来不愧是阉割版,那看看reactos里面有没
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts) { ULONG_PTR EFlags; /* Save EFlags and disable interrupts */ EFlags = __readeflags(); _disable(); /* Initialize and mask the PIC */ HalpInitializeLegacyPIC(); /* Initialize the I/O APIC */ ApicInitializeIOApic(); /* Manually reserve some vectors */ HalpVectorToIndex[APIC_CLOCK_VECTOR] = 8; HalpVectorToIndex[APC_VECTOR] = 99; HalpVectorToIndex[DISPATCH_VECTOR] = 99; /* Set interrupt handlers in the IDT */ KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, HalpClockInterrupt); // 注册时钟中断函数 #ifndef _M_AMD64 KeRegisterInterruptHandler(APC_VECTOR, HalpApcInterrupt); // 注册APC中断函数 KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt); // 注册DPC中断函数 #endif /* Register the vectors for APC and dispatch interrupts */ HalpRegisterVector(IDT_INTERNAL, 0, APC_VECTOR, APC_LEVEL); HalpRegisterVector(IDT_INTERNAL, 0, DISPATCH_VECTOR, DISPATCH_LEVEL); /* Restore interrupt state */ if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK; __writeeflags(EFlags); }
阴差阳错,搜索HalpClockInterrupt时居然看到了时钟中断,APC,和DPC的注册过程,注册过程是HalpInitializePICs初始化的,那么这个函数又是被谁调用的呢,继续跟踪发现是在HalInitSystem中被调用的
windows真不要脸,这个函数也没公布,只公布了原型:
HalInitSystem (IN ULONG Phase,IN PLOADER_PARAMETER_BLOCK LoaderBlock);
看原型,这跟Reactos中定义的一样啊,所以还是看看reactos吧:
BOOLEAN NTAPI INIT_FUNCTION HalInitSystem(IN ULONG BootPhase,IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PKPRCB Prcb = KeGetCurrentPrcb(); /* Check the boot phase */ if (BootPhase == 0) // 看情况是阶段0初始化的时候,才能注册时钟中断 { /* Phase 0... save bus type */ HalpBusType = LoaderBlock->u.I386.MachineType & 0xFF; /* Get command-line parameters */ HalpGetParameters(LoaderBlock); /* Check for PRCB version mismatch */ if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { /* No match, bugcheck */ KeBugCheckEx(MISMATCHED_HAL, 1, Prcb->MajorVersion, PRCB_MAJOR_VERSION, 0); } /* Checked/free HAL requires checked/free kernel */ if (Prcb->BuildType != HalpBuildType) { /* No match, bugcheck */ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, HalpBuildType, 0); } /* Initialize ACPI */ HalpSetupAcpiPhase0(LoaderBlock); /* Initialize the PICs */ HalpInitializePICs(TRUE); // 这个函数会调用函数进行时钟中断,APC,DPC的注册 /* Initialize CMOS lock */ KeInitializeSpinLock(&HalpSystemHardwareLock); /* Initialize CMOS */ HalpInitializeCmos(); /* Fill out the dispatch tables */ HalQuerySystemInformation = HaliQuerySystemInformation; HalSetSystemInformation = HaliSetSystemInformation; HalInitPnpDriver = HaliInitPnpDriver; HalGetDmaAdapter = HalpGetDmaAdapter; HalGetInterruptTranslator = NULL; // FIXME: TODO HalResetDisplay = HalpBiosDisplayReset; HalHaltSystem = HaliHaltSystem; /* Setup I/O space */ HalpDefaultIoSpace.Next = HalpAddressUsageList; HalpAddressUsageList = &HalpDefaultIoSpace; /* Setup busy waiting */ HalpCalibrateStallExecution(); /* Initialize the clock */ HalpInitializeClock(); /* * We could be rebooting with a pending profile interrupt, * so clear it here before interrupts are enabled */ HalStopProfileInterrupt(ProfileTime); /* Do some HAL-specific initialization */ HalpInitPhase0(LoaderBlock); } else if (BootPhase == 1) { /* Initialize bus handlers */ HalpInitBusHandlers(); /* Do some HAL-specific initialization */ HalpInitPhase1(); } /* All done, return */ return TRUE; }
至于HalInitSystem是什么,这个基本搞过内核的都知道,内核初始化的时候会调用这个函数,看了下Reactos是直接设置了入口点,所以回到WRK,看看HalInitSystem是什么时间调用的
VOID ExpInitializeExecutive(IN ULONG Number,IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
......
if (HalInitSystem(InitializationPhase, LoaderBlock) == FALSE) {
KeBugCheck(HAL_INITIALIZATION_FAILED);
}
......
}
跟到这里就没必要往上跟踪了,在往上就是内核入口函数了,这里附加一个内核原理与实现书上的一张图
所以可以总结下时钟中断/APC/DPC注册的流程了:
KiSystemStartUp->KiInitlizeKernel->ExpInitializeExecutive->HalInitSystem->HalpInitializePICs->注册中断
好了,以上都是理论,现在测试下, 启动windbg,这里要设置系统初始断点,以上其他函数的执行过程省略,直接从ExpInitializeExecutive开始
通过参数可以看到,传递给HalInitSystem的参数是0,代表是内核阶段0初始化,继续跟踪
HalInitSystem会判断是阶段0还是阶段1,这里是阶段0,所以会调用HalpInitializePICs注册时钟中断,但是可能因为硬件的问题,调用的不是APIC.C中的HalpInitializePICs,而是PIC中的HalpInitializePICs,这里先不深究了