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

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
zeroc
Posts: 3
Joined: Tue Dec 07, 2010 11:39 pm

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

Post 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!
Last edited by zeroc on Wed Dec 08, 2010 2:05 am, edited 1 time in total.
User avatar
salil_bhagurkar
Member
Member
Posts: 261
Joined: Mon Feb 19, 2007 10:40 am
Location: India

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

Post 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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

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

Post 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
Last edited by Combuster on Wed Dec 08, 2010 2:01 am, edited 2 times in total.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
zeroc
Posts: 3
Joined: Tue Dec 07, 2010 11:39 pm

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

Post 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.
Last edited by zeroc on Wed Dec 08, 2010 2:03 am, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

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

Post by Combuster »

I see you responded faster than I could edit my previous post :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
zeroc
Posts: 3
Joined: Tue Dec 07, 2010 11:39 pm

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

Post by zeroc »

Haha, yeah. Thanks again you really helped me there.
Post Reply