Another IRQ Question... WITH CODE!
Posted: Wed Jan 08, 2003 2:55 pm
I've been lurking here for the past week reading this and that, and i have my own IRQ question now.. I've read lots of different material, and am getting to understand what I'm doing (I think). I followed and implemented many thigns that have been discussed on the five page thread a while ago about setting up the IDT. Here's my code, and it doesn't work. I get a "3rd (13) exception with no resolution" error in bochs (v 2.0).
I also boot from Grub, and have had no problems with it really. Everything is complied in gcc, and i can post the linker script/makefile if requested.
There is probably some really dumb mistake in here that someone will be able to tell me right away, but alas... my code:
void create_idt( unsigned long num, void (*handler)(void) );
void init_idt( void );
void keyboard_handler( void );
void default_func( void );
typedef struct {
unsigned short offset_low;
unsigned short selector;
unsigned char param_count;
unsigned char access;
unsigned short offset_high;
} __attribute__ ((packed)) idt_entry;
typedef struct {
unsigned short size;
unsigned long base;
} __attribute__ ((packed)) gate;
gate idtr;
idt_entry IDT[256];
void KernelMain( void ) {
char *prompt;
__clear_screen();
printf( "Adam's OS\n" );
printf( "version 0.01b\t\t\tBuild 1100\n" );
printf( "Jan 03 Development\n" );
printf( "Initlizing \"kernel\" services...\n" );
printf( "Disabling interrupts...\n" );
cli();
init_idt();
while(1) {
/*printf( "] " );
prompt = getline();
printf( "\n" );
if( strcmp( prompt, "exit" ) == 0 ) {
printf( "We cannot reboot right now, sorry!\n" );
*/
}
}
void create_idt( unsigned long num, void (*handler)(void) ) {
idt_entry *idt_temp;
idt_temp = (idt_entry *)(idtr.base + (num *8));
idt_temp->offset_low = (unsigned short) (((unsigned long)handler & 0xFFFF));
idt_temp->selector = (unsigned short)0x10;
idt_temp->access = (unsigned char) 0x8E;
idt_temp->param_count = (unsigned char)0;
idt_temp->offset_high = (unsigned short)(((unsigned long)handler >> 16));
}
void init_idt( void ) {
int n;
idtr.size = 256*8-1;
idtr.base = 0x00001000;
printf( "Creating IDT's...\n" );
for( n = 0; n < 256; n++ ) {
create_idt(n, &default_func);
}
printf( "Creating keyboard IDT...\n" );
create_idt(32, &keyboard_handler);
printf( "LIDT idtr\n" );
asm volatile ( "LIDT idtr");
printf( "STI" );
asm( "STI" );
printf( "init_idt() complete.\n" );
}
void default_func( void ) {
//_printc( "x" );
asm( "popl %eax" );
asm( "popl %eax" );
asm( "cli" );
asm( "hlt" );
}
void keyboard_handler( void ) {
printf( "key\n" );
outportb( 0x20, 0x20 );
asm( "MOV %ebp, %esp" );
asm( "POP %ebp" );
asm( "IRET" );
}
------------
There's a lot more in the kernel of course, printf and getline, etc... but none of that should matter.
Oh, and the tripple fault happens when I "STI". The message "init_idt complete." never appears.
Thanks for your help!
- Simrook
I also boot from Grub, and have had no problems with it really. Everything is complied in gcc, and i can post the linker script/makefile if requested.
There is probably some really dumb mistake in here that someone will be able to tell me right away, but alas... my code:
void create_idt( unsigned long num, void (*handler)(void) );
void init_idt( void );
void keyboard_handler( void );
void default_func( void );
typedef struct {
unsigned short offset_low;
unsigned short selector;
unsigned char param_count;
unsigned char access;
unsigned short offset_high;
} __attribute__ ((packed)) idt_entry;
typedef struct {
unsigned short size;
unsigned long base;
} __attribute__ ((packed)) gate;
gate idtr;
idt_entry IDT[256];
void KernelMain( void ) {
char *prompt;
__clear_screen();
printf( "Adam's OS\n" );
printf( "version 0.01b\t\t\tBuild 1100\n" );
printf( "Jan 03 Development\n" );
printf( "Initlizing \"kernel\" services...\n" );
printf( "Disabling interrupts...\n" );
cli();
init_idt();
while(1) {
/*printf( "] " );
prompt = getline();
printf( "\n" );
if( strcmp( prompt, "exit" ) == 0 ) {
printf( "We cannot reboot right now, sorry!\n" );
*/
}
}
void create_idt( unsigned long num, void (*handler)(void) ) {
idt_entry *idt_temp;
idt_temp = (idt_entry *)(idtr.base + (num *8));
idt_temp->offset_low = (unsigned short) (((unsigned long)handler & 0xFFFF));
idt_temp->selector = (unsigned short)0x10;
idt_temp->access = (unsigned char) 0x8E;
idt_temp->param_count = (unsigned char)0;
idt_temp->offset_high = (unsigned short)(((unsigned long)handler >> 16));
}
void init_idt( void ) {
int n;
idtr.size = 256*8-1;
idtr.base = 0x00001000;
printf( "Creating IDT's...\n" );
for( n = 0; n < 256; n++ ) {
create_idt(n, &default_func);
}
printf( "Creating keyboard IDT...\n" );
create_idt(32, &keyboard_handler);
printf( "LIDT idtr\n" );
asm volatile ( "LIDT idtr");
printf( "STI" );
asm( "STI" );
printf( "init_idt() complete.\n" );
}
void default_func( void ) {
//_printc( "x" );
asm( "popl %eax" );
asm( "popl %eax" );
asm( "cli" );
asm( "hlt" );
}
void keyboard_handler( void ) {
printf( "key\n" );
outportb( 0x20, 0x20 );
asm( "MOV %ebp, %esp" );
asm( "POP %ebp" );
asm( "IRET" );
}
------------
There's a lot more in the kernel of course, printf and getline, etc... but none of that should matter.
Oh, and the tripple fault happens when I "STI". The message "init_idt complete." never appears.
Thanks for your help!
- Simrook