Page 1 of 1

No interrupts get called

Posted: Fri May 05, 2017 2:02 pm
by DeezRamChips
Hi :) I'm trying to make my own interrupt handler (first time I ever do that) but I'm struggling to get it working :(

To test if the problem was the C part, I added a 'call panic' command right at the beggining of every isr, but I still don't get anything :(

The code I got if made of some parts from the wiki and from a french website about osdeving.

Here is the code (please don't kill me if it's sh*t xD):

idt.c

Code: Select all

#include <idt.h>
#include <stddef.h>
#include <stdint.h>

void idt_entry(int num, uint32_t offset, uint16_t selector, uint8_t type_attr){
	IDT[num].offset_1 = (offset & 0xffff);;
	IDT[num].selector = selector;
	IDT[num].zero = 0;
	IDT[num].type_attr = type_attr;
	IDT[num].offset_2 = (offset & 0xffff0000) >> 16;
}

void loadIDT(){
	IDT_Pointer.limit = (sizeof(struct idt_entry) * IDT_SIZE) - 1;
	IDT_Pointer.base = &IDT;
	for (int i = 0; i < IDT_SIZE; i++){
		idt_entry(i, (uint32_t)&_asm_int_default_hdlr, 0x08,0x0E);
	}
	idt_entry(33, (uint32_t)&_asm_int_2_hdlr, 0x08, 0x0E);
	_loadIDT();
}

void _int_0_hdlr(){

}

void _int_1_hdlr(){

}

void _int_2_hdlr(){

}
idt.h

Code: Select all

#include <stddef.h>
#include <stdint.h>

#define IDT_BASE  0x800
#define IDT_SIZE  0xFF

#define INTGATE  0x8E00

struct idt_entry {
	uint16_t offset_1; // offset bits 0..15
	uint16_t selector; // a code segment selector in GDT or LDT
	uint8_t zero;      // unused, set to 0
	uint8_t type_attr; // type and attributes, see below
	uint16_t offset_2; // offset bits 16..31
} __attribute__((packed));

struct idt_ptr {
   unsigned short limit;
   unsigned int base;
} __attribute__((packed));

struct idt_entry IDT[IDT_SIZE];
struct idt_ptr IDT_Pointer;

extern void _loadIDT();
extern void _asm_int_default_hdlr();
extern void _asm_int_0_hdlr();
extern void _asm_int_1_hdlr();
extern void _asm_int_2_hdlr();

void idt_entry(int num, uint32_t offset, uint16_t selector, uint8_t type_attr);
void loadIDT();
idt_loader.asm

Code: Select all

.file "idt.c"
.global _loadIDT
.type _loadIDT, @function

.extern IDT_Pointer

_loadIDT:
	lidt IDT_Pointer
	mov 0x10, %eax
	mov %ds, %eax
	mov %es, %eax
	mov %fs, %eax
	mov %gs, %eax
	mov %ss, %eax
	jmp flush

flush:
   ret
interrupt_handler.asm

Code: Select all

.file "idt.c"
.global _asm_int_default_hdlr
.global _asm_int_0_hdlr
.global _asm_int_1_hdlr
.global _asm_int_2_hdlr
.extern _int_0_hdlr
.extern _int_1_hdlr
.extern _int_2_hdlr

_asm_int_default_hdlr:
	call panic
	iret

_asm_int_0_hdlr:
	call panic
	#pushad
    cld
    call _int_0_hdlr
    #popad
    iret

_asm_int_1_hdlr:
	call panic
	#pushad
    cld
    call _int_1_hdlr
    #popad
    iret

_asm_int_2_hdlr:
	call panic
	#pushad
    cld
    call _int_2_hdlr
    #popad
    iret
Hope someone cal help me :)

Re: No interrupts get called

Posted: Fri May 05, 2017 3:01 pm
by eryjus
Mask interrupts? http://wiki.osdev.org/8259_PIC#Masking

Enable interrupts (sti)?

Re: No interrupts get called

Posted: Fri May 05, 2017 3:08 pm
by DeezRamChips
Thanks for answering :)

What a stupid mistake xD

I called sti after loading idt, and, It seems to work ! BUT when any interrupt is called, the vm reboots :(

Re: No interrupts get called

Posted: Fri May 05, 2017 3:22 pm
by eryjus
DeezRamChips wrote:BUT when any interrupt is called, the vm reboots
probably something like...

IRQ0 (or similar) -- no handler
Double Fault -- no handler
Triple fault -- reboot

Fill in all the exceptions and faults in the IDT so you have something to work with.

Re: No interrupts get called

Posted: Fri May 05, 2017 3:35 pm
by DeezRamChips
I already assign an isr to every interrupt :/ It's done in the loadIDT() function:

Code: Select all

for (int i = 0; i < IDT_SIZE; i++){
	idt_entry(i, (uint32_t)&_asm_int_default_hdlr, 0x08,0x0E);
}

Re: No interrupts get called

Posted: Fri May 05, 2017 3:53 pm
by Octacone
DeezRamChips wrote:I already assign an isr to every interrupt :/ It's done in the loadIDT() function:

Code: Select all

for (int i = 0; i < IDT_SIZE; i++){
	idt_entry(i, (uint32_t)&_asm_int_default_hdlr, 0x08,0x0E);
}
You don't need an ISR for every interrupt. You need 32 ISRs for 32 different exceptions and other 224 entries for 244 interrupt request handlers. You should also remap your Programmable Interrupt Controller (PIC) so your exceptions don't interfere with your interrupt request handlers. When an exception occurs you should probably display something similar to a BSOD, halting the CPU if the kernel couldn't be recovered. I would suggest you taking a look at assembly macros for easier code management, you don't need to prototype all those entries by hand. Also don't forget about call gates if you are planning on using and IDT and interrupts for system calls. Those will probably have different flags and selectors. Every interrupt request should/could have a different handler (common assembly handler + different C handler scheme).

Re: No interrupts get called

Posted: Fri May 05, 2017 4:49 pm
by DeezRamChips
Before doing all of this, I think it would be better to have working interrupts :)

One thing I know, is that it's not related to the loading of the IDT, it only happens when I run 'sti' :/

Re: No interrupts get called

Posted: Fri May 05, 2017 6:54 pm
by eryjus
DeezRamChips wrote:it only happens when I run 'sti'
Ok, let's walk through this a bit more... Maybe we can get there.

When you execute the 'sti' opcode, you are enabling interrupts. If you are experiencing a reboot right after that statement (I'm sure you have a debug statement in your code so you know this rather than presume), then you are getting an interrupt immediately. 'sti' alone will not cause a reboot.

Now. We know we are having a problem related to an interrupt. The causes are that the IDT is not set up (which it is as you indicate) or the IDT is set up incorrectly (a possibility, and generating a GPF) or it might be an alignment problem (but I cannot confirm it will manifest itself right after sti). Continuing down this line, if the interrupt or GPF is not handled properly, then you will get a Double Fault and if that is still unhanded a Triple Fault which leads to a reboot.

Now, if you have a common handler set up for all interrupts and that common handler is never called (a panic function call first thing as you mentioned), then you have to assume that the interrupt is never getting to the interrupt handler code. I would look into idt_entry() in particular and bit-map all the values you are setting -- like Present...?

Re: No interrupts get called

Posted: Sat May 06, 2017 1:35 pm
by DeezRamChips
Ok, thank you for answering :) I'll definitly check the structures tomorow !

I was wondering if the problem could be related to the GDT since I also created the functions to load it myself :/