Interrupt handling, GDT, IDT PIC problem [SOLVED]
Posted: Wed May 27, 2009 2:10 pm
Hello all, i am new here and ive been trying to get a lil simple os running. I ty in advance for any help.
I ve been trying to get things to work step by step, right now i am stuck at interrupts.
For some reason i cant get them to work, the cpu seems to triple fault and reset(i really dont know where or how or why)
i got a simple GDT with just code and data sectores taking all the memory for now.
i made 256 IDT's all poining to the same asm proc. I tried pointing to a c proc but it gave me the same errors.
I think i initialized the PIC correctly, but when i press '1' i call an int 48(to be on the upside) with cli enabled and
if i enable sti (using '2') and some ints are not mapped to be ignored in the pic, the cpu also resets.
I use nasm for the assembly, and mingw for the c code.
the irq asm i scompiled using "..\nasm-2.05.01\nasm" -f win32 irq.asm -o irq.o and the rest is all linked using
"..\Dev-Cpp\bin\ld" -e _kernel -Ttext 0x1000 -o kernel.o main.o video.c.o ports.c.o keyboard.c.o std.c.o login.c.o shell.c.o memory.c.o scheduler.c.o irq.o
here is the bootloader important section.
here is the irq.asm section on another asm
and finally the part i think the problem is in:
Am i mapping the irs correctly?, how about the GDT? is it correct? waht aout hte rings, i still dont have those very clear?
Are the IDT's correctly used? Is theproblem in the resulting adress of th efunciont to call?
TY
I ve been trying to get things to work step by step, right now i am stuck at interrupts.
For some reason i cant get them to work, the cpu seems to triple fault and reset(i really dont know where or how or why)
i got a simple GDT with just code and data sectores taking all the memory for now.
i made 256 IDT's all poining to the same asm proc. I tried pointing to a c proc but it gave me the same errors.
I think i initialized the PIC correctly, but when i press '1' i call an int 48(to be on the upside) with cli enabled and
if i enable sti (using '2') and some ints are not mapped to be ignored in the pic, the cpu also resets.
I use nasm for the assembly, and mingw for the c code.
the irq asm i scompiled using "..\nasm-2.05.01\nasm" -f win32 irq.asm -o irq.o and the rest is all linked using
"..\Dev-Cpp\bin\ld" -e _kernel -Ttext 0x1000 -o kernel.o main.o video.c.o ports.c.o keyboard.c.o std.c.o login.c.o shell.c.o memory.c.o scheduler.c.o irq.o
here is the bootloader important section.
Code: Select all
[BITS 32] ; We now need 32-bit instructions so we go into protected mode
clear_pipe:
mov ax, 10h ; Save data segment identifyer
mov ds, ax ; Move a valid data segment into the data segment register
mov ss, ax ; Move a valid data segment into the stack segment register
mov es, ax
xor eax, eax
mov fs, ax
mov gs, ax
mov esp, 090000h ; Move the stack pointer to 090000h
jmp 08h:01000h ; Jump to section 08h (code), offset 01000h
;http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0
dd 0
gdt_code: ; Code segment, read/execute, nonconforming
dw 0FFFFh ; The lower 16 bits of the limit.
dw 0 ; The lower 16 bits of the base.
db 0 ; The next 8 bits of the base.
db 10011010b ; Access flags, determine what ring this segment can be used in.
db 11001111b ;constant
db 0 ; The last 8 bits of the base.
gdt_data: ; Data segment, read/write, expand down
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end: ; Used to calculate the size of the GDT
gdt_desc: ; The GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT
Code: Select all
[extern _irq_handler]
global _irq0
section .code
_irq0:
loop:
jmp loop
pusha
push ds
push es
push fs
push gs
mov eax,0x10 ; Data segment
mov ds,eax
mov es,eax
cld
call _irq_handler
pop gs
pop fs
pop es
pop ds
popa
iret
Code: Select all
struct idt {
//! bits 0-16 of interrupt routine (ir) address
unsigned short baseLo;
//! code selector in gdt
unsigned short sel;
//! reserved, shold be 0
unsigned char reserved;
//! bit flags. Set with flags above
unsigned char flags;
//! bits 16-32 of ir address
unsigned short baseHi;
};
struct idtr {
//! size of the interrupt descriptor table (idt)
unsigned short limit;
//! base address of idt
unsigned int base;
};
struct idtr test;
struct idt int_[256];
void irq_handler()
{
for( ; ;)
}
#define MASTER 0x20
#define MASTERDATA 0x21
#define SLAVE 0xA0
#define SLAVEDATA 0xA1
#define EOI 0x20
#define ICW1_INIT 0x10 // required for PIC initialisation
#define ICW1_EDGE 0x08 // edge triggered IRQs
#define ICW1_SINGLE 0x02 // only MASTER (not cascaded)
#define ICW1_ICW4 0x01 // there IS an ICW4 control word
#define ICW4_SFNM 0x10 // Special Fully Nested Mode
#define ICW4_BUFFER 0x08 // Buffered Mode
#define ICW4_MASTER 0x04 // this is the Master PIC
#define ICW4_AEOI 0x02 // Auto EOI
#define ICW4_8086 0x01 // 80/86 Mode
void remapPIC(int pic1, int pic2)
{
unsigned char md,sd;
md=in(MASTERDATA); // save state of MASTER DATA
sd=in(SLAVEDATA); // save state of SLAVE DATA
out(MASTER, EOI); // Send EOI | resets the chip
out(MASTER, ICW1_INIT+ICW1_ICW4); // ICW1 control word setup | just basic PIC stuff
out(SLAVE, ICW1_INIT+ICW1_ICW4); // see pic.h for more details about the values
out(MASTERDATA, pic1); // ICW2 maps IRQs 0-7 to whatever kernel passes
out(SLAVEDATA, pic2); // and same here except with IRQs 8-15
out(MASTERDATA, 0x04); // ICW3
out(SLAVEDATA, 0x02);
out(MASTERDATA, ICW4_8086); // ICW4 control word setup
out(SLAVEDATA, ICW4_8086);
out(MASTERDATA,md); // restore both MASTER DATA
out(SLAVEDATA,sd); // restore SLAVE DATA
}
extern void irq0();
void initiateTimer()
{
remapPIC(0x20, 0x28);
out(0x21, 0xFE);
out(0xA1, 0xFE);
test.limit = sizeof (struct idt)*256 -1;
test.base = (unsigned int) int_;
unsigned int base = (unsigned int) &irq0;
int e;
for( e= 0; e < 256; e++)
{
int_[e].baseLo = base & 0xffff;
int_[e].baseHi = (base >> 16) & 0xffff;
int_[e].reserved = 0;
int_[e].flags = 0x8E ;
int_[e].sel = 0x08;
}
__asm__("lidt [ bx ]" : : "b" (&test));
}
Am i mapping the irs correctly?, how about the GDT? is it correct? waht aout hte rings, i still dont have those very clear?
Are the IDT's correctly used? Is theproblem in the resulting adress of th efunciont to call?
TY