我想处理NMI并在NMI发生时做一些事情。首先,我编写一个幼稚的nmi处理程序:
static irqreturn_t nmi_handler(int irq, void* dev_id) {
printk("-#_#- I'm TT, I am handling NMI.\n");
return IRQ_HANDLED;
}
并编写一个模块注册我的nmi处理程序,然后使用APIC触发NMI 5次:
static void __init ipi_init(void) {
printk("-#_#- I'm coming again, hahaha!\n");
int result = request_irq(NMI_VECTOR,
nmi_handler, IRQF_DISABLED, "NMI Watchdog", NULL);
printk("--- the result of request_irq is: %d\n", result);
int i;
for (i = 0; i < 5; ++i) {
apic->send_IPI_allbutself(NMI_VECTOR);
ssleep(1);
}
}
现在,我输入“insmod xxx.ko”来安装此模块,然后,检查/var/log/syslog:
kernel: [ 1166.231005] -#_#- I'm coming again, hahaha!
kernel: [ 1166.231028] --- the result of request_irq is: 0
kernel: [ 1166.231050] Uhhuh. NMI received for unknown reason 00 on CPU 1.
kernel: [ 1166.231055] Do you have a strange power saving mode enabled?
kernel: [ 1166.231058] Dazed and confused, but trying to continue
kernel: [ 1167.196293] Uhhuh. NMI received for unknown reason 00 on CPU 1.
kernel: [ 1167.196293] Do you have a strange power saving mode enabled?
kernel: [ 1167.196293] Dazed and confused, but trying to continue
kernel: [ 1168.201288] Uhhuh. NMI received for unknown reason 00 on CPU 1.
kernel: [ 1168.201288] Do you have a strange power saving mode enabled?
kernel: [ 1168.201288] Dazed and confused, but trying to continue
kernel: [ 1169.235553] Uhhuh. NMI received for unknown reason 00 on CPU 1.
kernel: [ 1169.235553] Do you have a strange power saving mode enabled?
kernel: [ 1169.235553] Dazed and confused, but trying to continue
kernel: [ 1170.236343] Uhhuh. NMI received for unknown reason 00 on CPU 1.
kernel: [ 1170.236343] Do you have a strange power saving mode enabled?
kernel: [ 1170.236343] Dazed and confused, but trying to continue
它显示我已成功注册nmi_handler(结果= 0),并且NMI被触发了5次,但是我没有发现应在nmi_handler中输出的字符串。
我使用Ubuntu 10.04 LTS,Intel Pentium 4 Dual-core。
最佳答案
没有人?
我的伴侣又给了我3天的时间,因此我阅读了源代码和ULK3,现在我可以回答问题1:
实际上, IRQ号和 INT vector 号是与不同!函数request_irq()调用setup_irq():
/**
* setup_irq - setup an interrupt
* @irq: Interrupt line to setup
* @act: irqaction for the interrupt
*
* Used to statically setup interrupts in the early boot process.
*/
int setup_irq(unsigned int irq, struct irqaction *act)
{
struct irq_desc *desc = irq_to_desc(irq);
return __setup_irq(irq, desc, act);
}
看这个:
@irq: Interrupt line to setup
。参数irq是中断行号,而不是中断 vector 号。查找ULK3 PDF,P203,定时器中断具有IRQ 0,但其INT nr为32!所以我触发了INT2(NMI),但是我的处理程序实际上处理了INT34!我想在源代码中找到更多证据(例如,如何将IRQ转换为INT?我修改了处理程序和init,我请求irq = 2,而Linux分配INT = 50),但是什么也没得到,期望linux-xxx/arch/x86/include/asm/irq_vectors.h
/*
* IDT vectors usable for external interrupt sources start
* at 0x20:
*/
#define FIRST_EXTERNAL_VECTOR 0x20
请稍等...让我阅读更多代码来回答问题2。