keyboard problem(interrupts are working, keyboard is not)
keyboard problem(interrupts are working, keyboard is not)
Hello, I am new to the osdev forums but have been using the site for help in writing an os in c and a bit of assembly. I know a good deal of C++ and am picking up the differences in c and have decided to write an os for fun and experience. Right now I just got interrupts working but cant get the keyboard to.
I think it is a problem with what interrupt the irq for the keyboard is mapped to. I re-mapped the pic with a function call like this
init_pics(0x20, 0x28);
and I added a keyboard isr to my idt like this:
AddInt(21, _int21, 0);
also, I unmasked irq's after that. I think that the keyboard would be mapped at 0x21 but I am not completely sure ( it is irq 1 I know but that is mapped to 0x21 because of the re-mapped pic right?). help is appreciated, I can post more code if you like, it is very similar to many tutorials, but I hope once I get input working that I can have a relatively unique os after that. when a key is pressed my keyboard isr just prints "key press" but when i press a key nothing happens, i can successfully call the interrupt from asm though. thanks for any help!
I think it is a problem with what interrupt the irq for the keyboard is mapped to. I re-mapped the pic with a function call like this
init_pics(0x20, 0x28);
and I added a keyboard isr to my idt like this:
AddInt(21, _int21, 0);
also, I unmasked irq's after that. I think that the keyboard would be mapped at 0x21 but I am not completely sure ( it is irq 1 I know but that is mapped to 0x21 because of the re-mapped pic right?). help is appreciated, I can post more code if you like, it is very similar to many tutorials, but I hope once I get input working that I can have a relatively unique os after that. when a key is pressed my keyboard isr just prints "key press" but when i press a key nothing happens, i can successfully call the interrupt from asm though. thanks for any help!
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: keyboard problem(interrupts are working, keyboard is not
It would be very helpful to see the following:
- Some code for the functions init_pics and AddInt.
- Your keyboard IRQ handler.
- The commands you send to the keyboard.
- How do you know that interrupts are working? Do you receive any other interrupts?
-
- Posts: 4
- Joined: Sat Jan 24, 2009 10:54 am
Re: keyboard problem(interrupts are working, keyboard is not
Hello, I just recently built in my IDT handler with keyboard. If you want I could send you my kernel. It's really basic and the keyboard handler is the only significance, but that way you could maybe be able to find your bug. Ill be able to send it to you in 3 hours or so, so let me know!
Re: keyboard problem(interrupts are working, keyboard is not
thanks for the help. here is my init_pics code:
//definitions
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
then this function:
void init_pics(int pic1, int pic2)
{
/* send ICW1 */
outportb(PIC1, ICW1);
outportb(PIC2, ICW1);
/* send ICW2 */
outportb(PIC1 + 1, pic1); /* remap */
outportb(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
outportb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
outportb(PIC2 + 1, 2);
/* send ICW4 */
outportb(PIC1 + 1, ICW4);
outportb(PIC2 + 1, ICW4);
/* disable all IRQs */
outportb(PIC1 + 1, 0xFF);
}
here is my AddInt code:
void AddInt(int number, void (*handler)(), dword dpl)
{
word selector = 0x08;
word settings;
dword offset = (dword)handler;
/* get CS selector */
asm volatile("movw %%cs,%0" :"=g"(selector));
/* set settings options depending on dpl */
switch(dpl)
{
case 0: settings = INT_0; break;
case 1:
case 2:
case 3: settings = INT_3; break;
}
/* set actual values of int */
IDT[number].low_offset = (offset & 0xFFFF);
IDT[number].selector = selector;
IDT[number].settings = settings;
IDT[number].high_offset = (offset >> 16);
}
where IDT is a struct containing the variables low_offset, selector, settings, and high offset. my keyboard isr just prints to the screen taht a key has been pressed:
void keyboardISR()
{
byte new_scan_code = inportb(0x60);
print("key press", 3);
outportb(0x20,0x20);
}
I dont really need the new_scan_code yet but it is there so i can add on later. that is in an assembly wrapper:
[extern keyboardISR]
[global _int21]
_int21:
pusha
push ds
push es
push fs
push gs
mov eax,0x10
mov ds,eax
mov es,eax
cld
call keyboardISR
pop gs
pop fs
pop es
pop ds
popa
iret
i dont't know much assembly so this could be optimized but it seems to work, i can call the interrupt in assembly and it works but like I said, i think i have the keyboard mapped to the wrong thing or something. Also, i probably don't need to see anyones kernel yet, im sure i could learn from it so i might ask if i can't figure this out from your responses. thanks for the help!
//definitions
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
then this function:
void init_pics(int pic1, int pic2)
{
/* send ICW1 */
outportb(PIC1, ICW1);
outportb(PIC2, ICW1);
/* send ICW2 */
outportb(PIC1 + 1, pic1); /* remap */
outportb(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
outportb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
outportb(PIC2 + 1, 2);
/* send ICW4 */
outportb(PIC1 + 1, ICW4);
outportb(PIC2 + 1, ICW4);
/* disable all IRQs */
outportb(PIC1 + 1, 0xFF);
}
here is my AddInt code:
void AddInt(int number, void (*handler)(), dword dpl)
{
word selector = 0x08;
word settings;
dword offset = (dword)handler;
/* get CS selector */
asm volatile("movw %%cs,%0" :"=g"(selector));
/* set settings options depending on dpl */
switch(dpl)
{
case 0: settings = INT_0; break;
case 1:
case 2:
case 3: settings = INT_3; break;
}
/* set actual values of int */
IDT[number].low_offset = (offset & 0xFFFF);
IDT[number].selector = selector;
IDT[number].settings = settings;
IDT[number].high_offset = (offset >> 16);
}
where IDT is a struct containing the variables low_offset, selector, settings, and high offset. my keyboard isr just prints to the screen taht a key has been pressed:
void keyboardISR()
{
byte new_scan_code = inportb(0x60);
print("key press", 3);
outportb(0x20,0x20);
}
I dont really need the new_scan_code yet but it is there so i can add on later. that is in an assembly wrapper:
[extern keyboardISR]
[global _int21]
_int21:
pusha
push ds
push es
push fs
push gs
mov eax,0x10
mov ds,eax
mov es,eax
cld
call keyboardISR
pop gs
pop fs
pop es
pop ds
popa
iret
i dont't know much assembly so this could be optimized but it seems to work, i can call the interrupt in assembly and it works but like I said, i think i have the keyboard mapped to the wrong thing or something. Also, i probably don't need to see anyones kernel yet, im sure i could learn from it so i might ask if i can't figure this out from your responses. thanks for the help!
Re: keyboard problem(interrupts are working, keyboard is not
ok, i found out that 0x21 hex is actually 33 decimal so i mapped my keyboard isr to interrupt 33 and then i just get an exception. i can post my exception handler too if need be. thanks for any help!
-
- Posts: 4
- Joined: Sat Jan 24, 2009 10:54 am
Re: keyboard problem(interrupts are working, keyboard is not
Here, I've added my OS source code to this post. Please keep in mind I am simply a rookie programming interested in expanding my knowledge by creating an OS. I have no intentions in using a perfect syntax/technique concerning the code. I hope you will find it helpful! The most interesting for you is probably the interrupts.* files. Feel free to ask questions!
Good luck!
Good luck!
- Attachments
-
- TukOS.zip
- TukOS Source + binaries
- (37.45 KiB) Downloaded 286 times
Re: keyboard problem(interrupts are working, keyboard is not
thanks for posting your kernel! I'm sure I can learn from it, I am just writing an os to learn also. I fixed the exception thing, I unmasked irqs after I loaded the idt this time instead of before, but the keyboard still isn't working even though i have it mapped at 33 (0x21). I will have to take a while looking trough your code, it styled alot differently than mine actually but it appears to do the same basic thing. thanks for your help, maybe I can fix my code soon!(If you have any suggestions for my code or want more posted feel free to tell me)
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: keyboard problem(interrupts are working, keyboard is not
Which exception do you get? At which instruction does it happen? Have you used a debugger (as in Bochs or QEMU)?
Just a few comments on your code:
You should probably disable all IRQs on PIC2, too. Otherwise you might get unexpected results once you enable IRQ 2. (This is not related to the keyboard, just a general advice.)
I would use "=r" instead of "=g" here, but maybe I'm just confused by the fact that GCC allows an "immediate integer" for "g", which does not make sense for an output operand.
Just a few comments on your code:
Code: Select all
outportb(PIC1 + 1, 0xFF);
Code: Select all
asm volatile("movw %%cs,%0" :"=g"(selector));
Re: keyboard problem(interrupts are working, keyboard is not
Well, I fixed the exception thing, I was getting the exception when I loaded the exception handlers because I unmasked irqs too early I think. i fixed that now by unmasking irqs later. The exception was a non-fatal one but it continuously came and didn't allow the computer to do anything. My handler doesn't display any more than that (probably a bad idea I know, but I had hoped to rarely get exceptions, I will fix it though). I do not know much assembly so i don't really know what =r or =g does, that part was from a tutorial, because I don't know assembly( I probably should learn). Still, I cant fix the keyboard, i guess i could post my whole kernel, its kind of messy because I have all my function definitions at the top of kernel.c(it helps me understand what I'm doing better) and do not have my functions split up into separate files, the whole kernel is literally in kernel.c(except for asm parts). I like it better that way but i could definitely clean things up. Right now i just really want to get the keyboard working. thanks alot for your help!
Re: keyboard problem(interrupts are working, keyboard is not
i wonder if it has anything to do with the fact that there is a 'cli' asm command right after my loader.s ( the same as in the c bare bones) calls kmain. that would disable interrupts right? maybe kmain gets through with what it is doing and then interrupts are disabled before i can press a key. just a thought, but i wouldn't exactly know given my lack of experience with assembler.
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: keyboard problem(interrupts are working, keyboard is not
Yes, "cli" clears the "interrupt flag" in the EFLAGS register, which disables all (maskable) hardware interrupts. (There is also a non-maskable interrupt, but that's a different topic.) So unless you enable interrupts again by setting the interrupt flag to 1 (i.e., "sti"), you won't get any interrupts.
Re: keyboard problem(interrupts are working, keyboard is not
what should i do to deal with that? is the barebones tutorial not supposed to allow keyboard input( unlikely)? when i remove the cli or add an sti i just get a fatal exception. maybe there would be a way to have kmain wait until a key is pressed to move on? thanks for your help!
Re: keyboard problem(interrupts are working, keyboard is not
hi, check my post about keyboard initialization. codes included.
Re: keyboard problem(interrupts are working, keyboard is not
where is it? i checked your profile and went to 'posts' but i cant find it. When i did a search i couldn't find it either...thanks
Re: keyboard problem(interrupts are working, keyboard is not
ok, I added support so that my kernel now tells me what exception has occured. if i remove the cli or add an sti i get a general protection fault. I also tried adding an empty for loop at the end of my kmain so it would just loop until the keyboard interrupt comes, that aslos results in a general protection fault. I think many of them must be coming consecutively becuase the screen is always flashing, eventually it stops flashing and ends in a double fault. I am not sure why this is happening. thanks for any help!