Errors when setting up interrupts

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator:Moderators

Post Reply
Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:
Errors when setting up interrupts

Post by Andyhhp » Sat Sep 27, 2008 12:21 am

Hi,

I am currently trying to continue my kernel and keep on hitting the same problem.

When I try to install an interrupt descriptor table, I get triple faults when generating any form of interrupt.

Code: Select all

static struct idt_desc idt_table[256];
static struct idtr idt_reg;

void def_handler()
{
	unsigned short * screen = (unsigned short*)0xB8000;
	*screen = (unsigned short)0x0F00|'D';
	for(;;);
}

bool GetIntWorking()
{
	idt_reg.limit = sizeof(idt_desc)*256 -1;
	idt_reg.base = (unsigned char)idt_table;

	unsigned int ptr = (unsigned int)def_handler;

	for(int x=0;x<256>> 16);
		idt_table[x].reserved = 0;
		idt_table[x].sel = 0x08;
		idt_table[x].flags = 0x8E;
	}

	__asm lidt [idt_reg];
	__asm int 0x80;

	return false;
}
Here is the relevant bit of code. From what I have picked up, you should be able to generate an interrupt using the 'int' instruction even if interrupts are currently disabled.

From the tutorials, that would seem to be the minimum needed to actually catch a Pmode interrupt. However, it is triple faulting when executing the interrupt instruction.

Just as background, It is certainly not the bootloader at fault. My bootloader runs the demo of this fine but not this one. I have also copied the project settings from that demo so its nothing to do with the configuration.

Can anyone help?

Andrew

EDIT
it seems your form doesn't like the preincremental operator following a semicolon in the loop - possibly a counter to a possible injection attack: Contents should be:
idt_table[x].baselo = ptr & 0xFFFF;
idt_table[x].basehi = (ptr >> 16);
idt_table[x].reserved = 0;
idt_table[x].sel = 0x08;
idt_table[x].flags = 0x8E;
Image

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Post by Mike » Sat Sep 27, 2008 4:15 am

From what I have picked up, you should be able to generate an interrupt using the 'int' instruction even if interrupts are currently disabled.
Correct.

Code: Select all

idt_reg.base = (unsigned char)idt_table;
This line is error prone. idt_reg.base should be 32 bits (convert to an unsigned int instead of unsigned char). Converting the base to an unsigned char will strip the address of idt_table stored in the idt base down to 8 bits--which will cause problems and will most likely not refer to a invalid idt base address.

After making this change I got your code working fine. :)

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Sat Sep 27, 2008 11:19 am

Wow - Thankyou very much. I sorta feel like an idiot now because I ended up defining idtr as:

Code: Select all

struct idtr
{
	unsigned short	limit;
	unsigned char	base;
};
No wonder it wasn't working. :P

Now I am going to move on to fully enable interrupts.

Am I correct in assuming that to do this, I will need to remap the PIC and write proper handlers that use the 'iret' instruction?

Also, is it necessary to enable the PIT or can I safely ignore that until I have the PIC sorted?

Thanks,

Andrew
Image

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Post by Mike » Sat Sep 27, 2008 4:56 pm

You are correct--the only thing that needs to be setup is the PIC.

Technically, the PIT will still be setup and firing off IRQ 0. As long as IRQ 0 is mapped to a valid interrupt handler in your IDT (By just remapping IRQ 0 through the PIC) everything should work fine.

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Sat Sep 27, 2008 6:03 pm

Ok - thats good. I will just give IRQ 0 a null handler that merely returns.

A few thing that I am not sure about:

Which stack is used for interrupt handlers? I would have thought that it would need its own custom stack so it doesn't corrupt the one currently in use.

Also, is this stack pre-cleared before the interrupt handler is called?

This is because no error code is generated when you use the int instruction. However, if you call 'int 13d', the interrupt handler will be expecting an error but this will be an undefined 32bit value on whichever stack is used.

Is there a way to tell if the interrupt was generated from sofware or from the PIC?

Thanks,

Andrew
Image

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Post by Mike » Sat Sep 27, 2008 7:58 pm

Which stack is used for interrupt handlers? I would have thought that it would need its own custom stack so it doesn't corrupt the one currently in use.
It uses the current stack at esp. You will need to fix the stack inside of the interrupt handler. See Tutorial 15's Demo Conclusion section for an example of how to do this.
Is there a way to tell if the interrupt was generated from sofware or from the PIC?
Not directly, no. The software can determine this itself, though.

Post Reply