Keyboard Handler

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.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Solar wrote: You checked the FAQ? (Too lazy to c&p the link, just click on the mega-tokyo.com banner...)
Yes, I read it and the papers/documents at BonaFide too.
Kim

Re:Keyboard Handler

Post by Kim »

You could add paging support with a higherhalf kernel.
And maybe try out multitasking.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Kim wrote: You could add paging support with a higherhalf kernel.
And maybe try out multitasking.
Thanks Kim, but when I wrote "(...) where to continue (...)" I meant that relating to the keyboard issue ;)
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:Keyboard Handler

Post by bubach »

Can you post your PIC and IRQ code?
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
marcio.f

Re:Keyboard Handler

Post by marcio.f »

The main file is attached.
Here's the ISR wrapper for IRQ1 (does nothing - just to test):

Code: Select all

.globl _irq1_wrapper
.align 4

_irq1_wrapper:   NOP
                 IRET
tom1000000

Re:Keyboard Handler

Post by tom1000000 »

Hi,

Its easy to test if an IRQ is being picked up by the CPU.

Just write some code in the actual irq handler to directly update the VGA display.

Initialise word at any location on the display (eg 0xB8000 + 400) to an outrageous value so it stands out.

Then everytime an interrupt fires change the ascii char or even invert it.

This will prove your PIC is setup properly.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

I thought of doing that too, thanks. But now I just want to be able to press a key and Bochs to not panic. Later I'll add that.
AR

Re:Keyboard Handler

Post by AR »

I cannot make sense of your IDT code, by casting the various fields to "word" you are truncating the high 16 bits. Also 1 != 0x21.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

AR wrote: I cannot make sense of your IDT code, by casting the various fields to "word" you are truncating the high 16 bits. Also 1 != 0x21.
That's the reason why I asked here for help ;)
I'm not casting to word, instead to dword, which has 32 bits (IIRC):

Code: Select all

void lidt(void *base, dword size)
{
   dword i[2];
   
   i[0] = size;
   i[1] = (dword) base;   
   asm ("lidt (%0)" :: "p" (((char *)i)+2));
}
I know 1 != 0x21 but:
- first, the code is commented, so it will do nothing /*asm volatile ("int $0x21");*/
- second, if I remapped the PIC's so that IRQ0 starts at 0x20 and IRQ8 starts at 0x28, I think IRQ1 is 0x21, right? But, then again, I might be confusing notations..
AR

Re:Keyboard Handler

Post by AR »

Code: Select all

/* target segment selector (31-16) + offset in target segment low (15-0) */
   idt[IRQ1*2] = (word)(0x08<<16) + (word)((*_irq1_wrapper) & 0x0000FFFF);
   
   /* offset in target segment high (31-16) + present (15) + DPL (14-13) +
      0 (12) + type (interrupt gate) (11-8) + 000 (7-5) + dword-count (4-0) */
   idt[IRQ1*2+1] = (word)((*_irq1_wrapper) & 0xFFFF0000) + (1<<15) + (0<<13) + \
      (0<<12) + (0xE<<8) + (0<<5) + 0;
All the "word"s are truncating the numbers. (eg. (word)(0x08<<16) == 0)

IRQ1 is defined as 1, but you've remapped the PIC at 0x20, therefore the interrupt for IRQ1 = 0x21 but you're trying to use 0x01.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

How stupid I am :)
Sorry and thanks for pointing out. I've changed it to this (Bochs still panics):

Code: Select all

#define IRQ1 0x21

idt[IRQ1*2] = (0x08<<16) + ((*_irq1_wrapper) & 0x0000FFFF);
idt[IRQ1*2+1] = ((*_irq1_wrapper) & 0xFFFF0000) + (1<<15) + (0<<13) + (0<<12) + (0xE<<8) + (0<<5) + 0;
AR

Re:Keyboard Handler

Post by AR »

My logic is not working properly at the moment but I think you're dereferencing the IRQ handler (instead of the address you're actually using the first opcode), I suggest you use an array of IDT structs instead of that as it is just confusing.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

AR wrote: (...) I think you're dereferencing the IRQ handler (instead of the address you're actually using the first opcode)
If I remove the '*' like this:

Code: Select all

idt[IRQ1*2] = (0x08<<16) + ((_irq1_wrapper) & 0x0000FFFF);
idt[IRQ1*2+1] = ((_irq1_wrapper) & 0xFFFF0000) + (1<<15) + (0<<13) + (0<<12) + (0xE<<8) + (0<<5) + 0;
gcc won't compile:

Code: Select all

kernel.c: In function `_main':
kernel.c:133: error: invalid operands to binary &
kernel.c:137: error: invalid operands to binary &
[hr]
I suggest you use an array of IDT structs instead of that as it is just confusing.
Creating this struct:

Code: Select all

struct _idt_entry
{
   word offset_low;
   word selector;
   byte dword_count:5;
   byte unused:3;
   byte type:5;
   byte dpl:2;
   byte present:1;
   word offset_high;
} __attribute__((__packed__));

typedef struct _idt_entry idt_entry;
will make gcc give these errors:

Code: Select all

kernel.c:104: warning: type of bit-field `dword_count' is a GCC extension
kernel.c:105: warning: type of bit-field `unused' is a GCC extension
kernel.c:106: warning: type of bit-field `type' is a GCC extension
kernel.c:107: warning: type of bit-field `dpl' is a GCC extension
kernel.c:108: warning: type of bit-field `present' is a GCC extension
make: *** [kernel.o] Error 1
AR

Re:Keyboard Handler

Post by AR »

For the first one you can make it less fiddily with:

Code: Select all

extern void _irq1_wrapper();
... ((dword)&_irq1_wrapper) ...
For the second it looks like the size specifier isn't part of the standard, are you using C99? If you already are then you'll need to just use 2 bytes and #defines.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Thanks, now I have it like this:

Code: Select all

extern void _irq1_wrapper();
(...)
idt[IRQ1*2] = (0x08<<16) + (((dword)&_irq1_wrapper) & 0x0000FFFF);
idt[IRQ1*2+1] = (((dword)&_irq1_wrapper) & 0xFFFF0000) + (1<<15) + (0<<13) + (0<<12) + (0xE<<8) + (0<<5) + 0;
For the struct, I don't know how to see if I'm using C99 ???
I only know I'm compiling it as ANSI C.
Post Reply