Problems with interrupt handling

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Jerkko

Problems with interrupt handling

Post 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.
JoeKayzA

Re:Problems with interrupt handling

Post 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
Jerkko

Re:Problems with interrupt handling

Post 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.
Jerkko

Re:Problems with interrupt handling

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problems with interrupt handling

Post 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).
Jerkko

Re:Problems with interrupt handling

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problems with interrupt handling

Post 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.
Jerkko

Re:Problems with interrupt handling

Post 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.
oswizard

Re:Problems with interrupt handling

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problems with interrupt handling

Post 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.
Post Reply