Page 1 of 1

x86 os - called interrupt's index is half of given [SOLVED]

Posted: Wed Dec 08, 2010 1:38 am
by zeroc
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!

Re: x86 os qemu - called interrupt's index is half of given

Posted: Wed Dec 08, 2010 1:43 am
by salil_bhagurkar
It's likely that there is a problem with your IDT structure. But the N/2 thing is weird.
You should post some code; specifically the IDT initialization and your interrupt handlers in question.

Re: x86 os qemu - called interrupt's index is half of given

Posted: Wed Dec 08, 2010 1:53 am
by Combuster
ASSERT( sizeof(Descriptor) == 8 ) ?

And other than that, you can never put C functions directly in the IDT, let alone C++ ones. If you want weird breakages, this is certainly the way to go.

EDIT: your real problem:

Code: Select all

Descriptor* idt = GetDescriptor(index); // returns idt+index
idt[index].* = ... // acessing idt+index+index

Re: x86 os qemu - called interrupt's index is half of given

Posted: Wed Dec 08, 2010 1:57 am
by zeroc
salil_bhagurkar wrote:It's likely that there is a problem with your IDT structure. But the N/2 thing is weird.
You should post some code; specifically the IDT initialization and your interrupt handlers in question.
This source file is the base of all my IDT code. The Initialize() function is called once to initialize the IDT.
Combuster wrote:ASSERT( sizeof(Descriptor) == 8 ) ?
I have already made sure that this is true. The structure is packed with an alignment of 1 using #pragma pack, in the IDT source file

Combuster wrote:And other than that, you can never put C functions directly in the IDT, let alone C++ ones. If you want weird breakages, this is certainly the way to go.
Well, I realize the interrupts have different calling conventions from C/C++, but I figured that for simple testing right now if any interrupt called does not return out of itself it would be safe.


EDIT: Wow Combuster that was definitely the problem. I really can't believe I missed that. Thank you so very much.

Re: x86 os qemu - called interrupt's index is half of given

Posted: Wed Dec 08, 2010 2:03 am
by Combuster
I see you responded faster than I could edit my previous post :wink:

Re: x86 os - called interrupt's index is half of given [SOLV

Posted: Wed Dec 08, 2010 2:05 am
by zeroc
Haha, yeah. Thanks again you really helped me there.