Okay, so yesterday, I tried as I said to setup the IDT and I'm having an issue I never had before. For simplicity's sake, I basically reused James Molloy's IDT system and setup the isr's the best I could in GAS syntax. The problem is that when I use the code:
it puts 0xF000FF57 into int_no in the registers struct. I've been pulling my hair out trying to figure it out. I'll put the code here:
isr.h:
Code: Select all
#ifndef _ADAMANTIUM_ISR_H
#define _ADAMANTIUM_ISR_H
#include <stdint.h>
#ifndef INTn
#define INTn(n) asm ( "int $"#n )
#endif
typedef struct
{
uint32_t ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no, err_code;
uint32_t eip, cs, eflags, useresp, ss;
} registers_t;
typedef void(*isr_t)(registers_t);
extern void exception_handler(void);
extern void register_interrupt_handler(uint8_t n, isr_t hndl);
extern void isr0(void);
extern void isr1(void);
extern void isr2(void);
extern void isr3(void);
extern void isr4(void);
extern void isr5(void);
extern void isr6(void);
extern void isr7(void);
extern void isr8(void);
extern void isr9(void);
extern void isr10(void);
extern void isr11(void);
extern void isr12(void);
extern void isr13(void);
extern void isr14(void);
extern void isr15(void);
extern void isr16(void);
extern void isr17(void);
extern void isr18(void);
extern void isr19(void);
extern void isr20(void);
extern void isr21(void);
extern void isr22(void);
extern void isr23(void);
extern void isr24(void);
extern void isr25(void);
extern void isr26(void);
extern void isr27(void);
extern void isr28(void);
extern void isr29(void);
extern void isr30(void);
extern void isr31(void);
#endif
isr.c:
Code: Select all
void isr_handler(registers_t regs)
{
printf("Received Intno: 0x%x\n", regs.int_no); // Here is where the interrupt number is printed...
}
isr_idx.S:
Code: Select all
.code32
.globl isr0
.globl isr1
.globl isr2
.globl isr3
.globl isr4
.globl isr5
.globl isr6
.globl isr7
.globl isr8
.globl isr9
.globl isr10
.globl isr11
.globl isr12
.globl isr13
.globl isr14
.globl isr15
.globl isr16
.globl isr17
.globl isr18
.globl isr19
.globl isr20
.globl isr21
.globl isr22
.globl isr23
.globl isr24
.globl isr25
.globl isr26
.globl isr27
.globl isr28
.globl isr29
.globl isr30
.globl isr31
isr0:
cli
push 0x00
push 0x00
jmp isr_common_stub
isr1:
cli
push 0x00
push 0x01
jmp isr_common_stub
isr2:
cli
push 0x00
push 0x02
jmp isr_common_stub
isr3:
cli
push 0x00
push 0x03
jmp isr_common_stub
isr4:
cli
push 0x00
push 0x04
jmp isr_common_stub
isr5:
cli
push 0x00
push 0x05
jmp isr_common_stub
isr6:
cli
push 0x00
push 0x06
jmp isr_common_stub
isr7:
cli
push 0x00
push 0x07
jmp isr_common_stub
isr8:
cli
push 0x08
jmp isr_common_stub
isr9:
cli
push 0x00
push 0x09
jmp isr_common_stub
isr10:
cli
push 0x0A
jmp isr_common_stub
isr11:
cli
push 0x0B
jmp isr_common_stub
isr12:
cli
push 0x0C
jmp isr_common_stub
isr13:
cli
push 0x0D
jmp isr_common_stub
isr14:
cli
push 0x0E
jmp isr_common_stub
isr15:
cli
push 0x00
push 0x0F
jmp isr_common_stub
isr16:
cli
push 0x00
push 0x10
jmp isr_common_stub
isr17:
cli
push 0x11
jmp isr_common_stub
isr18:
cli
push 0x00
push 0x12
jmp isr_common_stub
isr19:
cli
push 0x00
push 0x13
jmp isr_common_stub
isr20:
cli
push 0x00
push 0x14
jmp isr_common_stub
isr21:
cli
push 0x00
push 0x15
jmp isr_common_stub
isr22:
cli
push 0x00
push 0x16
jmp isr_common_stub
isr23:
cli
push 0x00
push 0x17
jmp isr_common_stub
isr24:
cli
push 0x00
push 0x18
jmp isr_common_stub
isr25:
cli
push 0x00
push 0x19
jmp isr_common_stub
isr26:
cli
push 0x00
push 0x1A
jmp isr_common_stub
isr27:
cli
push 0x00
push 0x1B
jmp isr_common_stub
isr28:
cli
push 0x00
push 0x1C
jmp isr_common_stub
isr29:
cli
push 0x00
push 0x1D
jmp isr_common_stub
isr30:
cli
push 0x1E
jmp isr_common_stub
isr31:
cli
push 0x00
push 0x1F
jmp isr_common_stub
.extern isr_handler
isr_common_stub:
pusha
movw %ds, %ax
push %eax
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
call isr_handler
pop %eax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
popa
add $8, %esp
sti
iret
idt.h:
Code: Select all
#ifndef _ADAMANTIUM_IDT_H
#define _ADAMANTIUM_IDT_H 1
#include <compiler.h> // For the _packed macro definition
#include <stdint.h>
#include "isr.h"
typedef struct idt_entry_struct
{
uint16_t base_low;
uint16_t selector;
uint8_t zero;
uint8_t flags;
uint16_t base_high;
} _packed idt_entry_t;
typedef struct idt_ptr_struct
{
uint16_t limit;
uint32_t base;
} _packed idt_ptr_t;
#endif
descriptors.h:
Code: Select all
#ifndef _ADAMANTIUM_DESCRIPTORS_H
#define _ADAMANTIUM_DESCRIPTORS_H
#define MAX_GDT_ENTRIES 5
#define MAX_IDT_ENTRIES 256
#if !defined(__ASSEMBLER__)
#include <kernel/tty.h>
#include <vga.h>
#include <stdint.h>
#include <stdio.h>
#include "interrupt.h"
extern void descriptors_init(void);
#endif
// For use with both C and Asembly sources:
#define GDT_KERNEL_CODE_SEGMENT 0x08
#define GDT_KERNEL_DATA_SEGMENT 0x10
#endif
descriptors.c:
Code: Select all
#include <kernel/i386/descriptors.h>
#include <kernel/i386/idt.h>
#include <string.h>
// Install the GDT. Located in file boot/desc.S
extern void gdt_install(void);
static void idt_install(void);
static void gdt_init(void);
static void idt_init(void);
static void idt_set_gate(uint8_t, uint32_t, uint16_t, uint8_t);
idt_entry_t idt_entries[MAX_IDT_ENTRIES];
idt_ptr_t idt_ptr;
void descriptors_init(void)
{
gdt_init();
idt_init();
}
static void gdt_init(void)
{
gdt_install();
}
static void idt_init(void)
{
idt_ptr.limit = (sizeof(idt_entry_t) * (MAX_IDT_ENTRIES - 1));
idt_ptr.base = (uint32_t)&idt_entries;
memset(&idt_entries, 0, sizeof(idt_entry_t) * MAX_IDT_ENTRIES);
idt_set_gate(0x00, (uint32_t)isr0, GDT_KERNEL_CODE_SEGMENT, 0x8E); // GDT_KERNEL_CODE_SEGMENT=0x08 (duh!)
idt_set_gate(0x01, (uint32_t)isr1, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x02, (uint32_t)isr2, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x03, (uint32_t)isr3, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x04, (uint32_t)isr4, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x05, (uint32_t)isr5, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x06, (uint32_t)isr6, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x07, (uint32_t)isr7, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x08, (uint32_t)isr8, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x09, (uint32_t)isr9, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x0A, (uint32_t)isr10, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x0B, (uint32_t)isr11, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x0C, (uint32_t)isr12, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x0D, (uint32_t)isr13, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x0E, (uint32_t)isr14, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x0F, (uint32_t)isr15, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x10, (uint32_t)isr16, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x11, (uint32_t)isr17, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x12, (uint32_t)isr18, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x13, (uint32_t)isr19, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x14, (uint32_t)isr20, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x15, (uint32_t)isr21, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x16, (uint32_t)isr22, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x17, (uint32_t)isr23, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x18, (uint32_t)isr24, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x19, (uint32_t)isr25, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x1A, (uint32_t)isr26, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x1B, (uint32_t)isr27, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x1C, (uint32_t)isr28, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x1D, (uint32_t)isr29, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x1E, (uint32_t)isr30, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_set_gate(0x1F, (uint32_t)isr31, GDT_KERNEL_CODE_SEGMENT, 0x8E);
idt_install();
asm volatile ( "sti" );
}
static void idt_set_gate(uint8_t index, uint32_t base, uint16_t selector, uint8_t flags)
{
idt_entries[index].base_low = base & 0xFFFF;
idt_entries[index].base_high = (base >> 16) & 0xFFFF;
idt_entries[index].selector = selector;
idt_entries[index].zero = 0x00;
idt_entries[index].flags = flags;
}
static void idt_install(void)
{
asm volatile ( "lidt %0" : : "m"( idt_ptr ));
}
I have tried everything and nothing seems to work. It's expected to say "Received intno: 0x0", but it says "Received Intno: 0xf000ff57". That doesn't seem right at all... Any and all help is appreciated. Thanks.