Keyboard Handler
Re:Keyboard Handler
Still doesn't compile.. here are the flags I use for gcc:AR wrote: Add "-std=c99" to the commandline for GCC.
-std=c99 -ansi -ffreestanding -Wall -pedantic -Werror -nostdlib -nostartfiles -nodefaultlibs -Iinclude
Re:Keyboard Handler
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:
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__));
Re:Keyboard Handler
Ok, now it looks like:
Now, bochs not only panics when I press a key but also displays the video text in blue (screenshot attached).
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;
Re:Keyboard Handler
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.
Re:Keyboard Handler
Thanks! I've doubled the kernel stack space (32k) and now the screen doesn't get that blue layout.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.
But the panic is still there
Re:Keyboard Handler
So you're still getting:
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).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!
Re:Keyboard Handler
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?
Btw, what should I look for in the debug log?
Re:Keyboard Handler
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".
To trace use "pb 0x100000" to set a breakpoint then "c" then you can step through with "s".
Re:Keyboard Handler
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 ::)
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 ::)
Re:Keyboard Handler
Sorry, should have checked it before: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
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));
}
Code: Select all
struct { word size; dword address; } __attribute__((__packed__)) IDT;
IDT.size = size;
IDT.address = (dword)base;
asm("lidt (%0)" :: "g"(&IDT));
Re:Keyboard Handler
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:
EDIT: Is the code for "acknowledge" (http://www.osdev.org/osfaq2/index.php/SampleInlineFunctions) working well? Shouldn't it be like this?
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);
*/
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);
}
Re:Keyboard Handler
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".
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".
Re:Keyboard Handler
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..
I read that in some document, but now I can't remember where..