首页
社区
课程
招聘
[求助]系统在什么时候会注册时钟中断函数
发表于: 2016-5-13 20:30 3127

[求助]系统在什么时候会注册时钟中断函数

2016-5-13 20:30
3127
由于这几天一直在看线程调度这块,想要系统的学习一下,看看系统是什么时间注册的时钟中断函数,然后就在WRK中搜索HalpClockInterrupt这个函数,可是搜索不到,说明WRK并没有公布,于是就在Reactos中搜索,发现了这个函数在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);
}


很明显这里面并没有任何注册时钟中断的操作,请问有没有朋友知道这是怎么回事呢,或者时钟中断是在哪里注册的呢

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回