x86 os - called interrupt's index is half of given [SOLVED]
Posted: Wed Dec 08, 2010 1:38 am
Hi everyone, I'm building an x86 operating system largely from scratch. My goal has been to get the keyboard IRQ working so I can get input from the user, but I have run into a road block. Right now my OS goes to 32 bit protected mode in its boot code.
The first symptom that I experienced is that the keyboard IRQ was simply not being called when I sent key input. I have written IDT and PIC initialization code, where the IRQs are mapped onto indices 32 and 40 for the master and slave PICs, respectively- so my expected behavior is that IRQ 1 (interrupt 33) would get called. It does not.
With some further examination, I have determined that by calling an interrupt manually myself with __asm__("int $N") (my kernel is written in C++, compiled with gcc), where N is the interrupt number, the interrupt which actually seems to be called has an index of N/2 if N is an even number, or simply 4 (the overflow exception interrupt) if N is any odd number.
For example, in my IDT code, I set a test interrupt at index 40 to call a function which prints "TEST INTERRUPT." This interrupt is not called when I do __asm__("int $40")- the default interrupt handler is called. Instead, if I do __asm__("int $80"), "TEST INTERRUPT" is printed.
I came to the unlikely explanation that if the CPU thought I was still using an interrupt table of the IVT format, with 4-byte entries instead of 8-byte entries, it might exhibit this behavior when calling interrupts. Still though, it doesn't seem possible. I have never touched the IVT before going into 32-bit protected mode.
The behavior of the kernel was the same when I ran it on a real x86 computer.
Relevant kernel source code: Any suggestions would be greatly appreciated. I'm using QEMU to debug the kernel.
Thanks!
The first symptom that I experienced is that the keyboard IRQ was simply not being called when I sent key input. I have written IDT and PIC initialization code, where the IRQs are mapped onto indices 32 and 40 for the master and slave PICs, respectively- so my expected behavior is that IRQ 1 (interrupt 33) would get called. It does not.
With some further examination, I have determined that by calling an interrupt manually myself with __asm__("int $N") (my kernel is written in C++, compiled with gcc), where N is the interrupt number, the interrupt which actually seems to be called has an index of N/2 if N is an even number, or simply 4 (the overflow exception interrupt) if N is any odd number.
For example, in my IDT code, I set a test interrupt at index 40 to call a function which prints "TEST INTERRUPT." This interrupt is not called when I do __asm__("int $40")- the default interrupt handler is called. Instead, if I do __asm__("int $80"), "TEST INTERRUPT" is printed.
I came to the unlikely explanation that if the CPU thought I was still using an interrupt table of the IVT format, with 4-byte entries instead of 8-byte entries, it might exhibit this behavior when calling interrupts. Still though, it doesn't seem possible. I have never touched the IVT before going into 32-bit protected mode.
The behavior of the kernel was the same when I ran it on a real x86 computer.
Relevant kernel source code: Any suggestions would be greatly appreciated. I'm using QEMU to debug the kernel.
Thanks!