-
-
[求助]系统在什么时候会注册时钟中断函数
-
发表于: 2016-5-13 20:30 3127
-
由于这几天一直在看线程调度这块,想要系统的学习一下,看看系统是什么时间注册的时钟中断函数,然后就在WRK中搜索HalpClockInterrupt这个函数,可是搜索不到,说明WRK并没有公布,于是就在Reactos中搜索,发现了这个函数在HalpInitializePICs中被注册,具体的代码是:
然后我就继续搜索HalpInitializePICs,发现是在内核阶段0初始化的时候,HalInitSystem调用的它,具体的过程是:KiSystemStartUp->KiInitlizeKernel->ExpInitializeExecutive->HalInitSystem->HalpInitializePICs->注册中断
本来我以为一切都完美了,没想到系统调用的居然是hal\halx86\up\pic.c文件中的同名函数HalpInitializePICs,这个函数的原型是
很明显这里面并没有任何注册时钟中断的操作,请问有没有朋友知道这是怎么回事呢,或者时钟中断是在哪里注册的呢
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); KeRegisterInterruptHandler(DISPATCH_VECTOR, HalpDispatchInterrupt); #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); }
然后我就继续搜索HalpInitializePICs,发现是在内核阶段0初始化的时候,HalInitSystem调用的它,具体的过程是:KiSystemStartUp->KiInitlizeKernel->ExpInitializeExecutive->HalInitSystem->HalpInitializePICs->注册中断
本来我以为一切都完美了,没想到系统调用的居然是hal\halx86\up\pic.c文件中的同名函数HalpInitializePICs,这个函数的原型是
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts) { ULONG EFlags; I8259_ICW1 Icw1; I8259_ICW2 Icw2; I8259_ICW3 Icw3; I8259_ICW4 Icw4; EISA_ELCR Elcr; ULONG i, j; /* Save EFlags and disable interrupts */ EFlags = __readeflags(); _disable(); /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */ Icw1.NeedIcw4 = TRUE; Icw1.InterruptMode = EdgeTriggered; Icw1.OperatingMode = Cascade; Icw1.Interval = Interval8; Icw1.Init = TRUE; Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */ __outbyte(PIC1_CONTROL_PORT, Icw1.Bits); /* Set interrupt vector base */ Icw2.Bits = PRIMARY_VECTOR_BASE; __outbyte(PIC1_DATA_PORT, Icw2.Bits); /* Connect slave to IRQ 2 */ Icw3.Bits = 0; Icw3.SlaveIrq2 = TRUE; __outbyte(PIC1_DATA_PORT, Icw3.Bits); /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */ Icw4.Reserved = 0; Icw4.SystemMode = New8086Mode; Icw4.EoiMode = NormalEoi; Icw4.BufferedMode = NonBuffered; Icw4.SpecialFullyNestedMode = FALSE; __outbyte(PIC1_DATA_PORT, Icw4.Bits); /* Mask all interrupts */ __outbyte(PIC1_DATA_PORT, 0xFF); /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */ Icw1.NeedIcw4 = TRUE; Icw1.InterruptMode = EdgeTriggered; Icw1.OperatingMode = Cascade; Icw1.Interval = Interval8; Icw1.Init = TRUE; Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */ __outbyte(PIC2_CONTROL_PORT, Icw1.Bits); /* Set interrupt vector base */ Icw2.Bits = PRIMARY_VECTOR_BASE + 8; __outbyte(PIC2_DATA_PORT, Icw2.Bits); /* Slave ID */ Icw3.Bits = 0; Icw3.SlaveId = 2; __outbyte(PIC2_DATA_PORT, Icw3.Bits); /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */ Icw4.Reserved = 0; Icw4.SystemMode = New8086Mode; Icw4.EoiMode = NormalEoi; Icw4.BufferedMode = NonBuffered; Icw4.SpecialFullyNestedMode = FALSE; __outbyte(PIC2_DATA_PORT, Icw4.Bits); /* Mask all interrupts */ __outbyte(PIC2_DATA_PORT, 0xFF); /* Read EISA Edge/Level Register for master and slave */ Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER); /* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */ if (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) && !(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level)) { /* ELCR is as it's supposed to be, save it */ HalpEisaELCR = Elcr.Bits; /* Scan for level interrupts */ for (i = 1, j = 0; j < 16; i <<= 1, j++) { if (HalpEisaELCR & i) { /* Switch handler to level */ SWInterruptHandlerTable[j + 4] = HalpHardwareInterruptLevel; /* Switch dismiss to level */ HalpSpecialDismissTable[j] = HalpSpecialDismissLevelTable[j]; } } } /* Register IRQ 2 */ HalpRegisterVector(IDT_INTERNAL, PRIMARY_VECTOR_BASE + 2, PRIMARY_VECTOR_BASE + 2, HIGH_LEVEL); /* Restore interrupt state */ if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK; __writeeflags(EFlags); }
很明显这里面并没有任何注册时钟中断的操作,请问有没有朋友知道这是怎么回事呢,或者时钟中断是在哪里注册的呢
赞赏
他的文章
赞赏
雪币:
留言: