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.
AR

Re:Keyboard Handler

Post by AR »

Add "-std=c99" to the commandline for GCC.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

AR wrote: Add "-std=c99" to the commandline for GCC.
Still doesn't compile.. here are the flags I use for gcc:
-std=c99 -ansi -ffreestanding -Wall -pedantic -Werror -nostdlib -nostartfiles -nodefaultlibs -Iinclude
AR

Re:Keyboard Handler

Post by AR »

The only way to get around it then is to remove "-Werror" so that it will ignore the warnings.

I suggest you just create a bunch of defines and use:

Code: Select all

struct _idt_entry
{
   word offset_low;
   word selector;
   byte flags1;
   byte flags2;
   word offset_high;
} __attribute__((__packed__));
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Ok, now it looks like:

Code: Select all

(...)

#define IDT_SIZE 0x800
#define IRQ1 0x21

(...)

struct _idt_entry
{
   /* offset +0 */
   word offset_low; /* offset in target segment low (15-0) */
   word selector; /* target segment selector (31-16) */
   
   /* offset +4 */
   byte flags1; /* 000 (7-5) + dword-count (must be 0 for IDT entries) (4-0) */
   byte flags2; /* present (15) + DPL (14-13) + 0 (12) + type (interrupt gate) (11-8) */
   word offset_high; /* offset in target segment high (31-16) */
} __attribute__((__packed__));

typedef struct _idt_entry idt_entry;

(...)

   idt_entry idt[IDT_SIZE];

(...)

   idt[IRQ1].offset_low = ((dword)&_irq1_wrapper) & 0x0000FFFF;
   idt[IRQ1].selector = 0x08;
   idt[IRQ1].flags1 = (0<<5) + 0;
   idt[IRQ1].flags2 = (1<<7) + (0<<5) + (0<<4) + 0xE;
   idt[IRQ1].offset_high = ((dword)&_irq1_wrapper)>>16;
Now, bochs not only panics when I press a key but also displays the video text in blue (screenshot attached).
AR

Re:Keyboard Handler

Post by AR »

That makes it look like there is an environment problem, you are creating the IDT on the stack, is the stack actually able to hold all that? It would seem that you have overrun your .data/.bss and messed up something.
marcio.f

Re:Keyboard Handler

Post by marcio.f »

AR wrote: That makes it look like there is an environment problem, you are creating the IDT on the stack, is the stack actually able to hold all that? It would seem that you have overrun your .data/.bss and messed up something.
Thanks! I've doubled the kernel stack space (32k) and now the screen doesn't get that blue layout.
But the panic is still there :(
AR

Re:Keyboard Handler

Post by AR »

So you're still getting:
00024535235p[BIOS ] >>PANIC<< floppy recal:f07: ctrl not ready
00024536569p[CPU0 ] >>PANIC<< HALT instruction encountered in the BIOS ROM
00024536569p[CPU0 ] >>PANIC<< WARNING: HLT instruction with IF=0!
This error would seem to indicate that you've ended up in and/or overwritten the BIOS somehow. I can't really see anything else wrong, I can only recommend doing a step by step trace with the debugger (and enabling debug=report on the CPU).
marcio.f

Re:Keyboard Handler

Post by marcio.f »

How can I filter only the CPU reports? I've searched for it in bochs documentation but didn't found anything.
Btw, what should I look for in the debug log?
AR

Re:Keyboard Handler

Post by AR »

If you're using 2.2 then just click "config", change to "log options" tick configure individually, select "CPU0" and set "debug" to "log".

To trace use "pb 0x100000" to set a breakpoint then "c" then you can step through with "s".
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Thanks for the help but this is my first time with the debugger... so I'm using it almost blindly :-[
The debug log for CPU0 (etc) is attached in case you find time to check it, because I simply don't know what to look for ::)
AR

Re:Keyboard Handler

Post by AR »

00100566250d[CPU0 ] interrupt(): vector = 33, INT = 0, EXT = 1
00100566250d[CPU0 ] IDT.limit = 0010
00100566250d[CPU0 ] IDT.base = 106008
00100566250d[CPU0 ] interrupt vector must be within IDT table limits
00100566250d[CPU0 ] interrupt(): vector > idtr.limit[CPU0 ] IDT.base = 106008
Sorry, should have checked it before:

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));
}
This is wrong, try:

Code: Select all

   struct { word size; dword address; } __attribute__((__packed__)) IDT;

   IDT.size = size;
   IDT.address = (dword)base;
   asm("lidt (%0)" :: "g"(&IDT));
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Thanks a lot for your valuable help, AR! It's working now :)
Should I disable the interrupts at the beginning of my ISR and re-enable them at the end?

One more thing, I think some stuff in the wiki should be modified such as the lidt code (http://www.osdev.org/osfaq2/index.php/SampleInlineFunctions) and added some examples about setting up an IDT (and a sample entry).

I'm saying this because I felt some difficulty to find information about setting up an IDT and an entry i.e. for the keyboard.

And we could add code for querying information about the IDT:

Code: Select all

typedef unsigned int uint;
typedef unsigned short ushort;

typedef uint dword;
typedef ushort word;

struct _idt_info
{
   word size;
   dword address;
} __attribute__((__packed__));

typedef struct _idt_info idt_info;

/* Get information about IDT using the SIDT (Store IDT) register */
idt_info sidt()
{
   idt_info idt;
   
   asm ("sidt (%0)" :: "g" (&idt));
   return idt;
}

/* example use:
printf("IDT size: %d (bytes)\n", sidt().size);
printf("IDT address: %x\n", sidt().address);
*/
EDIT: Is the code for "acknowledge" (http://www.osdev.org/osfaq2/index.php/SampleInlineFunctions) working well? Shouldn't it be like this?

Code: Select all

typedef unsigned char uchar;

#define PIC1 0x20
#define PIC2 0xA0
#define PIC_EOI 0x20

#define outb_wait(port, val) (outb(port, val), io_wait())

void irq_end(uchar n)
{
   if (n > 7)
      outb_wait(PIC2, PIC_EOI);
   outb_wait(PIC1, PIC_EOI);
}
AR

Re:Keyboard Handler

Post by AR »

If you use an interrupt gate (0xE IIRC), it automatically disables interrupts for you, any sample code with CLI/STI in the wrapper is incorrect (the author didn't really know what they were doing).

It isn't really necessary to ever query the IDT (I've never needed SIDT and I don't really see any use in the kernel [provided you keep a pointer to the IDT so you can modify it], except perhaps for a crash dump - but if the IDT is broken then it's more likely that you'll triple fault anyway).

I added a note that the parameters are backwards to the Wiki, and the struct method for loading the IDT (Note that it did work, you left out the "<< 16" though). The naming convention used wasn't particularly good (limit is the Intel name for the field, which assumes you already know how LIDT works) so I changed it to "size".
marcio.f

Re:Keyboard Handler

Post by marcio.f »

Hmm, didn't know. Again, thanks a lot for your help :)
marcio.f

Re:Keyboard Handler

Post by marcio.f »

In the keyboard wrapper (the assembly code) is it necessary to remove the error code, or is it only for IRQ's 8 and 10-14 ?
I read that in some document, but now I can't remember where..
Post Reply