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.