Page 1 of 1
Receiving GPF after almost any PIC Interrupt :(
Posted: Sat Feb 03, 2007 7:40 am
by HerrGanchev
Hello guys!
Sorry if such topic already exists.
I am trying to write a simple kernel, and I am trying to set up some sort of a floppy driver. Unfortunatelly I have a problem with the interrupts, managed by the PIC - when almost all of them are called (except the keyboard and timer interrupt), a general protection fault is raised. I think I have done everything needed to set up the interrupt system:
* create the IDT
* load it with LIDT
* remap the PIC - 0x20+, 0x28+ interrupt vectors
* STI
Also, at the end of every hardware interrupt, I send an EOI as necessary.
I am using Bochs 2.3 for testing.
Thanks.
Posted: Sat Feb 03, 2007 8:54 am
by Otter
Did you register handlers for all irqs ( 0x20 to 0x2F ) ? If not, have you masked the others ? I dunno if it's important for you but in your list you did mention that you set the pic masks.
Maybe you could give some code ...
Posted: Sat Feb 03, 2007 9:46 am
by HerrGanchev
No, I did not mask the interrupts - actually I did once but this didn't change anything, except that the masked ones don't trigger
I remapped the PIC so that IRQ0 becomes INT 32, etc.
I have the following code on init to make sure for every interrupt i have a handler
Code: Select all
for (i = 0; i <= 48; i++)
InterruptSet((BYTE)i, EmptyInterrupt, 8, 0x8E00);
InterruptSet(13, GeneralProtectionInterrupt, 8, 0x8E00);
InterruptSet(14, PageFaultInterrupt, 8, 0x8E00);
InterruptSet(32, TimerInterrupt, 8, 0x8E00);
InterruptSet(33, KeyboardInterrupt, 8, 0x8E00);
Posted: Sat Feb 03, 2007 12:48 pm
by Otter
What happens if you call one of these interrupts manually ? Do you get a gpf too ? Then, your EmptyInterrupt seems to produce it.
Have you isolated the instruction which is responsible for the exception ? Dunno how complex your exception handler is but it should tell you the CS/EIP of the instruction which raised the gpf. If you have the EIP you should be able to locate the responsible position. If it is in your handler for EmptyInterrupt, maybe you could give the code of it
Posted: Sat Feb 03, 2007 2:56 pm
by HerrGanchev
If called manually as a software interrupt, again a GPF occurs, the EIP pointer is exactly the "int 38" instruction
When I tested the floppy controller, the eip pointed at the outputb() function that allows the floppy controller interrupt.
Between the manual and the normal interrupt invoke the only difference in the stack is the EXT bit of the error code
here is the source in the boot sector that remaps the pic (I think I do it in real mode, is this a problem?):
Code: Select all
mov al, 0x11
out 0x20, al
call simpleLoop
mov al, 0x11
out 0xA0, al
call simpleLoop
mov al, 0x20
out 0x21, al
call simpleLoop
mov al, 0x28
out 0xA1, al
call simpleLoop
mov al, 0x04
out 0x21, al
call simpleLoop
mov al, 0x02
out 0xA1, al
call simpleLoop
mov al, 0x01
out 0x21, al
call simpleLoop
mov al, 0x01
out 0xA1, al
call simpleLoop
sti
here are the two macros for the start and end of each interrupt handler
Code: Select all
#define START_INTERRUPT() \
__asm__ __volatile__( \
"cli\n" \
"pusha\n" \
"push %gs\n" \
"push %fs\n" \
"push %es\n" \
"push %ds\n"); \
BYTE byEmptyInterruptVariable
#define END_INTERRUPT() \
__asm__ __volatile__( \
"movb $0x20, %al\n" \
"outb %al, $0x20\n" \
"pop %ds\n" \
"pop %es\n" \
"pop %fs\n" \
"pop %gs\n" \
"popa\n" \
"sti\n" \
"leave\n" \
"iret\n" \
)
Posted: Sat Feb 03, 2007 3:21 pm
by os64dev
you don't have a c function like the following code snippit do you ?
Code: Select all
void interrupt(void) {
START_INTERRUPT();
.....
END_INTERRUPT()
}
because that would be bad... see the FAQ. You should make the interrupt handlers in assembler, either nasm or as what ever you prefer, and call the c function from there like so:
Code: Select all
// file: isr.s
.extern isr_c_part
isr_asm_part:
pusha
call isr_c_part
popa
iret
//- file: isr.c
void isr_c_part(void) {
....
}
//- register interrupt.
InterruptSet(14, isr_asm_part, 8, 0x8E00);
hopes this helps a bit.
http://www.osdev.org/osfaq2/index.php/I ... ceRoutines provides more details.
regards
Posted: Sun Feb 04, 2007 12:42 am
by HerrGanchev
I know, I read the article, yet I used the "BLACK MAGIC" technique
But I don't believe this is the problem since the execution doesn't reach the interrupt handler at all
Anyway, I'll try using asm routines ...
Posted: Sun Feb 04, 2007 6:05 am
by HerrGanchev
Code: Select all
_irqEmpty:
pusha
call _EmptyInterrupt
mov al, 0x20
out 0x20, al
popa
iret
ok, so this is the new handler writen in assembler. Again, everything beyond IRQ1 crashes with GPF
Could it be a problem that I remap the PIC in real mode?
Posted: Sun Feb 04, 2007 7:52 am
by Otter
Could it be a problem that I remap the PIC in real mode?
No, that should be no problem.
I think the PIC is not the problem because you say that the gpf occurs even when you call the int manually, so I think the problem is in your idt.
Could you give the code for your idt ( all of it, including the LIDT ) ?
Posted: Sun Feb 04, 2007 8:41 am
by HerrGanchev
I was able to fix the problem, since you remind me to open the idt source
so the problem was that I uploaded a premade IDT directly from the second sector and the size of the IDT was up to the keyboard interrupt selector
, now I set it to 1023 words und alles arbeitet problemloss
Thanks, Otter! Thanks os64dev! Sorry for taking your time