我自己的OS内核中的周期性RTC中断

时间:2011-08-29 11:07:35

标签: c++ operating-system kernel

我目前正在用c ++编写内核。因此,作为内核的基本部分,我在内核中实现了一个中断处理模块,并且运行良好。但它不适用于RTC IRQ8中断。

这是启用irq:

的代码
void IDT::enable_irq(unsigned short x, void (*handler)(), unsigned char control){
    current_mask &= ~(1<<x) ;   //Zero off the IRQ mask to enable
if (x>=8)
{
    current_mask &= ~(1<<2);
    set_int((x + SLAVE_VEC - 7),(unsigned long) handler, control);
}
else            //Sets the appropriate interrupt at the same time
{
    set_int((x + MASTER_VEC),(unsigned long) handler, control);
}
outb(PICMI, current_mask & 0xff);
outb(PICSI, (current_mask >> 8) & 0xff);
}

set_int是在IDT中添加中断条目的功能。

如果我将其称为:

,它对键盘中断很有用
enable_irq(1,kbInt,INT_GATE|BITS_32|PRESENT|RING_2);

但如果我为irq8调用它,即RTC,那么它就无法正常工作。

enable_irq(8,rtcInt,INT_GATE|BITS_32|PRESENT|RING_2);

它给我一个错误:An unhandled interrupt has occurred...

然后我按照本教程中的说明操作: http://wiki.osdev.org/RTC

但我想做的是,我想在每次中断时生成周期性的RTC中断并在屏幕上显示时间。或者我想在每个rtc中断上调用一个特定的函数

所以请任何人帮我解决这个问题。

谢谢。

1 个答案:

答案 0 :(得分:1)

你的代码中的数学是错误的。

if (x>=8) 
{ 
    current_mask &= ~(1<<2); 
    set_int((x + SLAVE_VEC - 7),(unsigned long) handler, control); 
} 
如果SLAVE_VEC是0x40(正如你的意思所暗示),

将在IDT中的位置0x41安装一个处理程序,当你确定要将它安装在位置0x40时,因为0x40是PIC为IRQ8触发的中断(同样,假设PIC配置为具有0x40的基数。

您的代码应为: -

if (x>=8) 
{ 
    current_mask &= ~(1<<2); 
    set_int((x + SLAVE_VEC - 8),(unsigned long) handler, control); 
} 

将正确配置IRQ8的0x40th IDT条目。