我目前正在用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中断上调用一个特定的函数
所以请任何人帮我解决这个问题。
谢谢。
答案 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条目。