DavidCooper wrote:casnix wrote:I mean the computer hangs when installing the IDT.
So the problem could well be there.
Should I post my IDT code?
I think so, but I doubt I'll understand it. I've got to go, but I'm sure someone will look at it.
Okay.
idt.h
Code: Select all
// idt.h -- From James Molloys kernel tutorial
// -- http://www.jamesmolloy.co.uk
// A struct describing an interrupt gate.
#ifndef __IDT_H
#define __IDT_H
struct idt_entry_struct
{
unsigned short base_lo; // The lower 16 bits of the address to jump to when this interrupt fires.
unsigned short sel; // Kernel segment selector.
unsigned char always0; // This must always be zero.
unsigned char flags; // More flags. See documentation.
unsigned short base_hi; // The upper 16 bits of the address to jump to.
} __attribute__((packed));
typedef struct idt_entry_struct idt_entry_t;
// A struct describing a pointer to an array of interrupt handlers.
// This is in a format suitable for giving to 'lidt'.
struct idt_ptr_struct
{
unsigned short limit;
unsigned int base; // The address of the first element in our idt_entry_t array.
} __attribute__((packed));
typedef struct idt_ptr_struct idt_ptr_t;
// These extern directives let us access the addresses of our ASM ISR handlers.
extern void isr0 ();
extern void isr1 ();
extern void isr2 ();
extern void isr3 ();
extern void isr4 ();
extern void isr5 ();
extern void isr6 ();
extern void isr7 ();
extern void isr8 ();
extern void isr9 ();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
#endif
That's from JamesM's tutorial. I wanna get something working before I change it too much.
idt.c
Code: Select all
// idt.c -- From James Molloys kernel tutorial
// -- http://www.jamesmolloy.co.uk
#include <idt.h>
#include <link.h>
extern void idt_flush(unsigned int);
idt_entry_t idt_entries[256];
idt_ptr_t idt_ptr;
void __install_idt();
static void idt_set_gate(unsigned char, unsigned int, unsigned short, unsigned char);
void __install_idt()
{
idt_ptr.limit = sizeof(idt_entry_t) * 256 -1;
idt_ptr.base = (unsigned int)&idt_entries;
memset(&idt_entries, 0, (unsigned int)sizeof(idt_entry_t)*256);
idt_set_gate( 0, (unsigned int)isr0 , 0x08, 0x8E);
idt_set_gate( 1, (unsigned int)isr1 , 0x08, 0x8E);
idt_set_gate( 2, (unsigned int)isr2 , 0x08, 0x8E);
idt_set_gate( 3, (unsigned int)isr3 , 0x08, 0x8E);
idt_set_gate( 4, (unsigned int)isr4 , 0x08, 0x8E);
idt_set_gate( 5, (unsigned int)isr5 , 0x08, 0x8E);
idt_set_gate( 6, (unsigned int)isr6 , 0x08, 0x8E);
idt_set_gate( 7, (unsigned int)isr7 , 0x08, 0x8E);
idt_set_gate( 8, (unsigned int)isr8 , 0x08, 0x8E);
idt_set_gate( 9, (unsigned int)isr9 , 0x08, 0x8E);
idt_set_gate(10, (unsigned int)isr10, 0x08, 0x8E);
idt_set_gate(11, (unsigned int)isr11, 0x08, 0x8E);
idt_set_gate(12, (unsigned int)isr12, 0x08, 0x8E);
idt_set_gate(13, (unsigned int)isr13, 0x08, 0x8E);
idt_set_gate(14, (unsigned int)isr14, 0x08, 0x8E);
idt_set_gate(15, (unsigned int)isr15, 0x08, 0x8E);
idt_set_gate(16, (unsigned int)isr16, 0x08, 0x8E);
idt_set_gate(17, (unsigned int)isr17, 0x08, 0x8E);
idt_set_gate(18, (unsigned int)isr18, 0x08, 0x8E);
idt_set_gate(19, (unsigned int)isr19, 0x08, 0x8E);
idt_set_gate(20, (unsigned int)isr20, 0x08, 0x8E);
idt_set_gate(21, (unsigned int)isr21, 0x08, 0x8E);
idt_set_gate(22, (unsigned int)isr22, 0x08, 0x8E);
idt_set_gate(23, (unsigned int)isr23, 0x08, 0x8E);
idt_set_gate(24, (unsigned int)isr24, 0x08, 0x8E);
idt_set_gate(25, (unsigned int)isr25, 0x08, 0x8E);
idt_set_gate(26, (unsigned int)isr26, 0x08, 0x8E);
idt_set_gate(27, (unsigned int)isr27, 0x08, 0x8E);
idt_set_gate(28, (unsigned int)isr28, 0x08, 0x8E);
idt_set_gate(29, (unsigned int)isr29, 0x08, 0x8E);
idt_set_gate(30, (unsigned int)isr30, 0x08, 0x8E);
idt_set_gate(31, (unsigned int)isr31, 0x08, 0x8E);
idt_flush((unsigned int)&idt_ptr);
}
static void idt_set_gate(unsigned char num, unsigned int base, unsigned short sel, unsigned char flags)
{
idt_entries[num].base_lo = base & 0xFFFF;
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
idt_entries[num].sel = sel;
idt_entries[num].always0 = 0;
// We must uncomment the OR below when we get to using user-mode.
// It sets the interrupt gate's privilege level to 3.
idt_entries[num].flags = flags /* | 0x60 */;
}
idt.asm
Code: Select all
; idt.asm -- From James Molloys kernel tutorials
; -- http://www.jamesmolloy.co.uk
[GLOBAL idt_flush] ; Allows the C code to call idt_flush().
idt_flush:
mov eax, [esp+4] ; Get the pointer to the IDT, passed as a parameter.
lidt [eax] ; Load the IDT pointer.
ret
%macro ISR_NOERRCODE 1 ; define a macro, taking one parameter
[GLOBAL isr%1] ; %1 accesses the first parameter.
isr%1:
cli
push byte 0
push byte %1
jmp isr_common_stub
%endmacro
%macro ISR_ERRCODE 1
[GLOBAL isr%1]
isr%1:
cli
push byte %1
jmp isr_common_stub
%endmacro
ISR_NOERRCODE 0
ISR_NOERRCODE 1
ISR_NOERRCODE 2
ISR_NOERRCODE 3
ISR_NOERRCODE 4
ISR_NOERRCODE 5
ISR_NOERRCODE 6
ISR_NOERRCODE 7
ISR_ERRCODE 8
ISR_NOERRCODE 9
ISR_ERRCODE 10
ISR_ERRCODE 11
ISR_ERRCODE 12
ISR_ERRCODE 13
ISR_ERRCODE 14
ISR_NOERRCODE 15
ISR_NOERRCODE 16
ISR_NOERRCODE 17
ISR_NOERRCODE 18
ISR_NOERRCODE 19
ISR_NOERRCODE 20
ISR_NOERRCODE 21
ISR_NOERRCODE 22
ISR_NOERRCODE 23
ISR_NOERRCODE 24
ISR_NOERRCODE 25
ISR_NOERRCODE 26
ISR_NOERRCODE 27
ISR_NOERRCODE 28
ISR_NOERRCODE 29
ISR_NOERRCODE 30
ISR_NOERRCODE 31
; In isr.c
[EXTERN isr_handler]
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
pop eax ; reload the original data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
isr.h
Code: Select all
//
// isr.h -- Interface and structures for high level interrupt service routines.
// Part of this code is modified from Bran's kernel development tutorials.
// Rewritten for JamesM's kernel development tutorials.
//
#ifndef __ISR_H
#define __ISR_H
typedef struct registers
{
unsigned int ds; // Data segment selector
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
unsigned int int_no, err_code; // Interrupt number and error code (if applicable)
unsigned int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
} registers_t;
#endif
isr.c
Code: Select all
////
// isr.c -- High level interrupt service routines and interrupt request handlers.
// Part of this code is modified from Bran's kernel development tutorials.
// Rewritten for JamesM's kernel development tutorials.
//
#include <link.h>
#include <isr.h>
// This gets called from our ASM interrupt handler stub.
void isr_handler(registers_t regs)
{
puts("Recieved interrupt: ");
putnum(regs.int_no);
putc('\n');
}
So, yeah. Basically the code from JamesM's tutorial, 'cause (like I said before) I wanna get something working before I meddle with it and completely destroy something...