Page 1 of 1

Respond to interrupts.

Posted: Sun Nov 04, 2007 1:37 pm
by Nox
Hello,

I have a little problem :)
My kernel works in protected mode.
Here is kernel's main function:

Code: Select all

#include <ktty.h>
#include <colors.h>
#include <ints.h>
#include <handler.h>

int kmain()
{
   unsigned char *pmode   = "Entered protected mode. [OK]\n\0";
   unsigned char *ints    = "Setting up interrupts.  [OK]\n\0";
   unsigned char *welcome = "Welcome to mOS.\n\0";

   kclear(BgFgColors(COLOR_BLACK, COLOR_LIGHT_GREEN));
   kputs(pmode, BgFgColors(COLOR_BLACK, COLOR_LIGHT_GREEN));

   init_interrupts();
   kputs(ints, BgFgColors(COLOR_BLACK, COLOR_LIGHT_GREEN));
   kputs(welcome, BgFgColors(COLOR_BLACK, COLOR_LIGHT_GREEN));

for(;;);
asm("hlt");
   return 0;
}
init_interrupts(); - initialize all 255 interrupts with function that do nothing.
then it installs timer irq with type TRAP_GATE, and keyboard irq with same type.

With current code I can do nothing, i mean when i type something nothing happens. It just cycleing (for(;;);) and thats all. It's not responding to interrupts.
My question is: how can I put processor in state of doing nothing, just to wait for interrupts.

P.S: without multitasking, I don't need it now.
P.S2: sorry for my bad english :)

Posted: Sun Nov 04, 2007 1:54 pm
by 01000101
have you enabled your keyboard and timer with your IRQ and ISRs?
once you have the IRQ setup properly, you should be able to for(;;) and still recieve interrupts. did you happen to accidentally put a asm(sti) somewhere??

maybe if you post your IRQ hander or your keyboard/timer code we could help more.

Posted: Sun Nov 04, 2007 2:37 pm
by Nox

Code: Select all

void inst_interrupt(unsigned char vector, void (*func)(), unsigned short type)
{
     struct idt_gate *_idt_gate = (struct idt_gate *)IDT_ADDRESS;

     _idt_gate[vector].offset15_0 = ((unsigned int)func & 0xFFFF);
     _idt_gate[vector].seg_selector = 0x8;
     _idt_gate[vector].flags = (PRESENT | RING0 | GATE_SIZE32 | type);
     _idt_gate[vector].offset31_16 = (((unsigned int)func >> 16));
}

//loading value in to IDT register 
void load_idt_register()
{
     unsigned short *table_limit = (unsigned short *) IDT_REG;
     unsigned int *table_address = (unsigned int *) (IDT_REG+2);

     *table_limit = 256 * 8 - 1;
     *table_address = IDT_ADDRESS;
     asm("lidt 0(,%0,)"::"a"(IDT_REG));
}
void init_interrupts(void)
{
     disable_interrupts(); //asm("cli")
     remap_pics(); // 0x20 - IRQ0
                                                                                                                                                              
     inst_auto_handlers();

     inst_interrupt(0x20, &irq_timer, TRAP_GATE);
     inst_interrupt(0x21, &irq_keyboard, TRAP_GATE);

     load_idt_register();
     enable_interrupts();
}

//timer handler 
asm(".globl irq_timer");
asm("irq_timer:");
asm("cli");
asm("pusha");
asm("call irq0");
asm("movb $0x20, %al");
asm("outb %al, $0x20"); 
asm("sti");
asm("iretl");

void irq0(void)
{
    //timer
}

//keyboard handler  
asm(".globl irq_keyboard");
asm("irq_keyboard:");
asm("cli");
asm("pusha");
asm("call irq1");
asm("movb $0x20, %al");
asm("outb %al, $0x20");
asm("popa");
asm("sti");
asm("iretl");

void irq1(void)
{
   unsigned char new_scan_code = inportb(0x60);
   kputs("#", BgFgColors(COLOR_BLACK,COLOR_LIGHT_GREY));
}
void handler(void);
//defineing auto handler for all ints and exceptions                                                                                                          
asm(".globl handler");
asm("handler:");
asm("cli");
asm("pusha");
asm("movb $0x20, %al");
asm("outb %al, $0x20");
asm("popa");
asm("sti");
asm("iret");

//installing auto handlers                                                                                                                                    
void inst_auto_handlers()
{
   int i = 0;
   while(i != 255)
   {
      inst_interrupt(i, &handler, TRAP_GATE);
      i++;
   }
}
Forgot to mention that I run my OS in qemu and when kernel starts to for(;;) I can not close qemu window (only to kill process).
If I disable interrupts everything seems to be fine, qemu responses to my reqests, I can debug, dump virtual memory ...

Posted: Mon Nov 05, 2007 12:19 am
by os64dev
Forgot to mention that I run my OS in qemu and when kernel starts to for(;Wink I can not close qemu window (only to kill process).
If I disable interrupts everything seems to be fine, qemu responses to my reqests, I can debug, dump virtual memory ...
Seems an error has occurred in your OS. You should use bochs which at least provides details about the faulty code.

Posted: Mon Nov 05, 2007 1:47 am
by LordMage
you also have to find out how to, in your compiler, turnoff the extra pushing and poping that takes place when a funciton is called. this will mess up the stack that the INT needs. When I wrote mine I found that no matter what I did it wasn't working. So, I had to make an external ASM file that held the prototypes for my isrs and irqs and then called from asm my c++ function to run my INT. I was basically following brans tutorial for that but had to change several things because I am using VC++. hope some of that helps. You should definitely use bochs to help with the trouble shooting. I would have never gotten as far as I am without it, and I'm not much further than you are now.

Posted: Mon Nov 05, 2007 6:26 am
by AndrewAPrice
Forgot to mention that I run my OS in qemu and when kernel starts to for(;Wink I can not close qemu window (only to kill process).
If I disable interrupts everything seems to be fine, qemu responses to my reqests, I can debug, dump virtual memory ...
That's because for ( ; ; ) is causing a constant loop. QEMU is trying to run that loop over and over again which is why it appears to be unresponsive. A much easier version would be (using inline assembly):

Code: Select all

#define KERNEL_HALT() asm("cli"); \
   for( ; ; )
      asm("hlt");
then place KERNEL_HALT() anywhere in your code where you want it to freeze and QEMU will still be as responsive as ever!

Posted: Mon Nov 05, 2007 3:25 pm
by Nox
Thanks to all.
I found, dumping generated code, that my compiler does not include irq_timer function in output file. I do not know why this happens. I deleted irq_timer code, made a copy of irq_keyboard code and necessary changes, it works.

Thanks again.