Respond to interrupts.

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
Nox
Posts: 3
Joined: Sun Nov 04, 2007 5:48 am

Respond to interrupts.

Post 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 :)
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Post 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.
Nox
Posts: 3
Joined: Sun Nov 04, 2007 5:48 am

Post 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 ...
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post 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.
Author of COBOS
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post 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.
Getting back in the game.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post 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!
My OS is Perception.
Nox
Posts: 3
Joined: Sun Nov 04, 2007 5:48 am

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