Page 1 of 1
Problems with interrupt handling
Posted: Sat Aug 20, 2005 11:24 am
by Jerkko
I have problem with handling interrupts. Those work fine as good as come the 'iret' instruction. Then it just stops there. I have read and done as in some tutorials, but it isn't working fine.
In Bochs log file there is this lines repeatly:
Code: Select all
00004739770i[CPU ] selector->index*8 + 7 = 135
00004739770i[CPU ] gdtr.limit = 23
00004739770i[CPU ] fetch_raw_descriptor: GDT: index > limit
00004739770i[CPU ] | EAX=00000005 EBX=00026260 ECX=00100092 EDX=00000f64
00004739770i[CPU ] | ESP=00102fcc EBP=00102ff8 ESI=00026373 EDI=00026383
00004739770i[CPU ] | IOPL=0 NV UP DI PL NZ NA PE NC
00004739770i[CPU ] | SEG selector base limit G D
00004739770i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00004739770i[CPU ] | DS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00004739770i[CPU ] | ES:0008( 0001| 0| 0) 00000000 000fffff 1 1
00004739770i[CPU ] | FS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00004739770i[CPU ] | GS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00004739770i[CPU ] | SS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00004739770i[CPU ] | CS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00004739770i[CPU ] | EIP=00100770 (0010076f)
00004739770i[CPU ] | CR0=0x60000011 CR1=0x00000000 CR2=0x00000000
00004739770i[CPU ] | CR3=0x00000000 CR4=0x00000000
I have tried almost everything, but I just can't get it work correctly. I can paste code if necessary.
Re:Problems with interrupt handling
Posted: Sat Aug 20, 2005 1:04 pm
by JoeKayzA
Hi!
The relevant line is here:
Code: Select all
00004739770i[CPU ] fetch_raw_descriptor: GDT: index > limit
This says exactly what happened: Somehow, a (bad) segment selector got loaded into a segment register, that is outside the gdt. And this is probably due to a messed up stack, because the code segment gets reloaded during IRET with a value from the stack that is pushed on interrupt. Which interrupt is this exactly? Remember that faults also push a fault code on the stack, that has to be popped manually before you can do IRET.
Have a look at this:
http://www.osdev.org/osfaq2/index.php/Help%21%3F%20I%20can%27t%20get%20interrupts%20working
cheers Joe
Re:Problems with interrupt handling
Posted: Sat Aug 20, 2005 1:21 pm
by Jerkko
Thanks Joe.
I got that working. The problem was in my function that I used to test interrupts.
I had this kind of code in one file written in asm
Code: Select all
global _Do_int_call
_Do_int_call:
int 0x00
ret
And then I called that from C code
Code: Select all
extern void Do_int_call();
//code here
Do_int_call();
I had done something to registers that I should not. I forgot that it's not maybe good to touch some registers before saving them when we are calling an assembly function from C code. I think thats the reason why it didn't worked.
Re:Problems with interrupt handling
Posted: Sun Aug 21, 2005 1:47 am
by Jerkko
Okay. I have a new problem. Interrupts are working quite good expect numbers 8,10,11,12,13 and 14 which should put some kind of error code to the stack. For some reason those don't seem to do so.
Code: Select all
_int8:
push 0x08
jmp interrupt_handler
That code doesn't work correctly because the error code isn't put to the stack automaticly. I that interrupt code working by adding another push instruction there. What's wrong? Everything should be okay. I use 'asm("int $0x08")' in my code to test that interrupt code.
Re:Problems with interrupt handling
Posted: Sun Aug 21, 2005 1:57 am
by Pype.Clicker
beware: when generated from the CPU, some exceptions do have an error code on the stack (and that's the case for e.g. exception #13). When you instead use "int 0xD", no such error code is pushed, so you're not in the right conditions to test your handler.
You should find more info about this in the 'interrupts' chapter of the intel manual which i advice you to print out and review with glowpen and pencil at hand (oh, a cup of tea and some cookies could be welcome too, of course).
Re:Problems with interrupt handling
Posted: Sun Aug 21, 2005 2:24 am
by Jerkko
OK. So if use 'int' instruction to call to ints #8, #10, #11, #12 , #13 and #14 the processor doesn't push error code. So I should somehow mess the things in my code to cause those interrupts. Then it would work properly.
Maybe I should read more those Intel manuals like Pype.Clicker suggested.
Re:Problems with interrupt handling
Posted: Sun Aug 21, 2005 3:36 am
by Pype.Clicker
well, the double fault will be hard to simulate ... but you could quite easily write something like
Code: Select all
mov ds, 0xcafe ;; yeah, that don't exist plain like this.
mov dword [ds:12345678],0xdeadbeef ;; should raise a GPF (errcode == 0xcafe)
if you have some unmapped page somewhere, you can also have a paging execption raised with
Code: Select all
;; use a valid, flat enough segment
mov dword [ds:0xdeadbeef],0 ;; will raise PF with CR2 == 0xdeadbeef
Testing stack fault is much more complicated since you need the stack to recover it. I usually suggest you use a task gate and a failure-recovery TSS for stack fault, double fault and invalid TSS errors.
Re:Problems with interrupt handling
Posted: Mon Aug 22, 2005 1:55 pm
by Jerkko
OK. I thinks my interrups are working fine, but I have little problem with IRQ1. The timer interrupt works fine, but IRQ1 doesn't. I can get only one keyboard interrupt. The interrupt routine puts just things to stack, calls IRQ handler which only prints IRQ number. Then the handler pops things form stack and sends 0x20 to port 0x20 (PIC 1). I just doesn't seem to work with IRQ1. Should I read something from keyboard ports before the 'iret' instruction or do something else like send something to some ports?
Thanks.
Re:Problems with interrupt handling
Posted: Mon Aug 22, 2005 2:15 pm
by oswizard
Yes. Read a byte from port 0x60 - the keyboard data port. It can only hold one byte, and the interrupt is triggered when there is a byte to read.
That should do it.
Good luck,
Mike
Re:Problems with interrupt handling
Posted: Mon Aug 22, 2005 11:28 pm
by Pype.Clicker
Mike wrote:
Yes. Read a byte from port 0x60 - the keyboard data port. It can only hold one byte, and the interrupt is triggered when there is a byte to read.
actually, this is the case for most IRQs: they're here to notify the CPU of something to be done, and unless that thing is done, the device remains "stalled", unable to deliver more interrupts. Same will occur with the mouse, the network card, the disks, etc.