Bona Fide OS Developer
View unanswered posts | View active topics It is currently Thu Mar 28, 2024 1:57 pm



Post new topic Reply to topic  [ 3 posts ] 
 Keyboard IRQ Help 
Author Message

Joined: Thu Dec 23, 2010 1:12 pm
Posts: 9
Post Keyboard IRQ Help
EDIT: I completely recoded my interrupt code and it works now.

I am currently developing a 32 bit C++ and assembly OS booted by grub 2. I have got as far as implementing the IDT, remapping the PIC and implementing test keyboard code. However, when I press a key I get IRQ 4(interrupt 36) instead of IRQ 1 and the cpu resets. I have debugged it in bochs and it seems to do a far jump to 246:000a during the iret instruction then resets. This is very strange because my code segment is 8 and my data segment is 16. Including the null segment, they are the only gdt selectors in the kernel.
My Keyboard code is here:
Code:
void kbd_isr()
{
  unsigned char scancode = inb(0x60);
  char tmp[5];
  itoa(scancode,tmp,10);
  puts(tmp);
}

and my irq/isr handler is here:
Code:
#include <screen.h>
#include <string.h>
#include <system.h>
#include <keyboard.h>

//extern "C" void pit_isr();

struct registers
{
    unsigned int ds;                  // Data segment selector
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
    unsigned int int_no, err_code;    // Interrupt number and error code (if applicable)
    unsigned int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
}__attribute__((__packed__));

extern "C"
{
void isr_handler(struct registers regs)
{
  switch(regs.int_no)
  {
    case 33:
      kbd_isr();
      break;
    default:
      char tmp[3];
      itoa(regs.int_no,tmp,16);
      error((char *) "interrupt: 0x");
      error(tmp);   
  }
  if(regs.int_no > 31)
  {
  /*  if(regs.int_no == 39 || regs.int_no == 47)
  {
    puts("spurious7\n");
    outb(0x20,0x0B);
    if(inb(0x20) & 0x80)
    {
      if(regs.int_no == 47)
      {
   puts("spurious15\n");
   outb(0x20,0x20);
      }
      return;
    }
  }
  */
 
  if(regs.int_no >= 40)
    outb(0xA0,0x20);
  outb(0x20,0x20);
  }
}
}

My code is partly based on JamesM's tutorials, but modified a large amount.


Sat Jul 16, 2011 12:44 pm
Profile
Site Admin

Joined: Fri Jul 24, 2009 10:02 pm
Posts: 247
Location: Las Vegas, NV, US
Post Re: Keyboard IRQ Help
Glad you fixed it!

So, for the benefit of others in the future, what was the problem?


Tue Aug 23, 2011 1:10 am
Profile

Joined: Thu Dec 23, 2010 1:12 pm
Posts: 9
Post Re: Keyboard IRQ Help
Most of the idt code was In assembly and was almost incomprihensible so I rewrote it and did more of it in c++. It was much easier to understand and I wouldn't have been able to find the problem in the asm. I don't know what the problem was. The idt code must have not set up the isrs correctly and caused a #GP when called. I'm guessing the asm code didn't split the isr addresses properly.


Wed Aug 31, 2011 4:01 pm
Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 


Who is online

Users browsing this forum: No registered users and 25 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin and tweaked by the BF Team.