Receiving GPF after almost any PIC Interrupt :(
- HerrGanchev
- Posts: 6
- Joined: Sat Feb 03, 2007 7:33 am
- Location: Sofia, Bulgaria
Receiving GPF after almost any PIC Interrupt :(
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.
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.
- HerrGanchev
- Posts: 6
- Joined: Sat Feb 03, 2007 7:33 am
- Location: Sofia, Bulgaria
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
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);
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
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
- HerrGanchev
- Posts: 6
- Joined: Sat Feb 03, 2007 7:33 am
- Location: Sofia, Bulgaria
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?):
here are the two macros for the start and end of each interrupt handler
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
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" \
)
you don't have a c function like the following code snippit do you ?
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:
hopes this helps a bit.
http://www.osdev.org/osfaq2/index.php/I ... ceRoutines provides more details.
regards
Code: Select all
void interrupt(void) {
START_INTERRUPT();
.....
END_INTERRUPT()
}
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);
http://www.osdev.org/osfaq2/index.php/I ... ceRoutines provides more details.
regards
Author of COBOS
- HerrGanchev
- Posts: 6
- Joined: Sat Feb 03, 2007 7:33 am
- Location: Sofia, Bulgaria
- HerrGanchev
- Posts: 6
- Joined: Sat Feb 03, 2007 7:33 am
- Location: Sofia, Bulgaria
Code: Select all
_irqEmpty:
pusha
call _EmptyInterrupt
mov al, 0x20
out 0x20, al
popa
iret
Could it be a problem that I remap the PIC in real mode?
No, that should be no problem.Could it be a problem that I remap the PIC in real mode?
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 ) ?
- HerrGanchev
- Posts: 6
- Joined: Sat Feb 03, 2007 7:33 am
- Location: Sofia, Bulgaria
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
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