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.
My kernel has currently the following components :
Correct GDT
Correct IDT
PIC programming
Correct tty driver (almost print functions )
I am trying to write a keyboard handler but I have a problem. I wrote an asm IRQ function which call my C handling function.
I wrote a keyboard init funtion just with some simple instructions to initialize my keyboard buffer :
[pre]current = 0;
last = 0;[/pre]
where 'current' and 'last' are unsigned char I will use to remember the position in the keyboard buffer.
This code works perfectly on two machines (P166 & 386) but reboots two others (P90 & PIII667). I found out that it was the second instruction ('last = 0;') that causes this.
I also tried to call a dummy function within my keyboard init function instead of the two instructions above, and it reboots too.
My kernel reboots when I call my C keyboard handler in my irq1 asm function.
So instead of calling it, I wrote on the screen the address of the handler. I got 12892.
Then I added a instructions in my C kernel body function to wrote the address of my keyboard handler, and I got 12896.
Shouldn't I have the same two addresses ?
Is this my problem ?
Here's my irq1 (n)asm functions :
[pre]EXTERN keyboard
irq1:
cli
push eax
call keyboard
mov al,0x20
out 0x20,al
pop eax
sti
iret[/pre]
and here's my C keyboard handler function :
[pre]extern void putchar(unsigned char);
void keyboard(void)
{
unsigned char inv;
inv=inb(0x60);
putchar('.');
return;
}
[/pre]
Here's a part of my C kernel body function
[pre]// Init PIC
outb(0x20,0x11);
outb(0x21,0x20);
outb(0x21,0x4);
outb(0x21,0x1);
outb(0x21,0xFD);
outb(0xA0,0x11);
outb(0xA1,0x70);
outb(0xA1,0x2);
outb(0xA1,0x1);
outb(0xA1,0xFF);
[/pre]
'inb' and 'outb' are simple asm functions to get (set) a byte from (to) a port.
This sequence causes the computer to reboot when I press a key
What have I made wrong ?
I put a 'cli' in my irq1 function because I think that it may be more careful to unable other interruptions when you are just processing one. (imagine a timer interruption while you are processing a key press...)
%macro SAVE 0
; save some registers
pushad
push ds
push es
push fs
push gs
mov eax, DS_SELECTOR
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
%endmacro
%macro RESTORE 0
; restore saved registers
pop gs
pop fs
pop es
pop ds
popad
%endmacro
irq1:
cli
SAVE
call keyboard
mov al, 0x20
out 0x20, al
RESTORE
sti
iretd
when I make a dummy keyboard handler like this :
[pre]void keyboard(void)
{
}
[/pre]
it works, but when I insert this instruction :
[pre]void keyboard(void)
{
unsigned char value;
I don't think it comes from my IDT, because I made a printing test with the timer interrupt and ... well, my keyboard handler works on other machines and with bochs 2.0.