User:Bellezzasolo/IDT problems: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
Content added Content deleted
(Catorgorized)
m (Put into troubleshooting and links to similar article)
Line 161: Line 161:


*[[Visual Studio]]
*[[Visual Studio]]

*[[I_Cant_Get_Interrupts_Working|Interrupt problems]]


[[Category:X86 CPU]]
[[Category:X86 CPU]]
[[Category:Interrupts]]
[[Category:Interrupts]]
[[Category:Troubleshooting]]

Revision as of 08:48, 5 February 2012

Problems with IDTs

Many of us while OS dev'ing will encounter a problem with IDT's. I won't pretend to be an IDT agony aunt - in fact I'm in trouble myself. That is why I created this page - a wiki page you can easily access that's in a nice format. Introduction aside, I'll outline the first IDT problem this page has seen.


Feel free to add content, this is forum style

My problem

Please note before you give me GCC specific adivce I have a slightly unusual setup. My setup is MS VC++ 2010 Express SP1 with the [Updated] Windows SDK, enabling 64 bit development. I use a separate assembly layer. I am currently writing my bootloader, but as I will use a custom file system I am currently testing the 32 bit version with the bootloader available at BrokenThorn, which is a tutorial on a PE kernel. My kernel is higher half at 0xC0000000, and has no memory magager (it relies on the bootloader's). I intend to change this in the near future. It does however, manage it's GDT. My kernel works perfectly without interrupts, and even presents a command line. This is one of the reasons I want IRQ's however, I can only get 1 character. This might be changed very soon!. When I enable interrupts, the machine reboots. And again.... ad infanatum.

Now you understand the environment, this is the bochs output

interrupt(): not accessible or not code segment cs = 0x0008
interrupt(): gate descriptor not valid sys seg (vector = 0x0d)

interrupt(): not accessible or not code segment cs = 0x0008
Machine is in protected mode (active)
CS.mode = 32 bit
SS.mode = 32 bit

I don't know where I'm going wrong. I am using the linear address, as told to. If you need the code, here it is:

IDT.h

//definitions
#define PRESENT 0x80
#define USRPRIV 0x60
#define KRNLPRV 0x0
#define TASK32  0x5
#define INTR16  0x6
#define TRAP16  0x7
#define INTR32  0xE
#define TRAP32  0xF
void setvect(char vect, void(*function)(void), unsigned char priv = (PRESENT|KRNLPRV|INTR32));
void installIDT();

IDT.cpp

#include "IDT.h"
#include "..\Asm\Asmlayer.h"
#include <cstddef.h>
#include <stdout.h>
#include "panic.h"
//structures
class IDT_entry {
public:
#ifdef WIN32
	unsigned short baseLow;
	unsigned short segment;
	unsigned char reserved;
	unsigned char flags;
	unsigned short baseHigh;
#else
	unsigned short baseLow;
	unsigned short segment;
	unsigned char reserved;
	unsigned char flags;
	unsigned short baseMed;
	unsigned int baseHigh;
	unsigned int reserved2;
#endif
};
class IDT_reg {
public:
	unsigned short limit;
	IDT_entry* base;
};

//data
#pragma pack(push,1)
static IDT_reg IDT_register;
#pragma pack(pop)
#pragma pack(push,1)
static IDT_entry IDT [256] = {0};
#pragma pack(pop)

//functions
void setvect(char vect, void(*function)(void), unsigned char priv)
{
#ifdef WIN32
	IDT[vect].flags = priv;
	IDT[vect].segment = (0x8);	//Kernel mode
	IDT[vect].reserved = 0;
	IDT[vect].baseLow = (unsigned short)(unsigned int)function&0xFFFF;
	IDT[vect].baseHigh = (unsigned short)(unsigned int)function>>16;
#else
	IDT[vect].flags = priv;
	IDT[vect].segment = (0x8);	//Kernel mode
	IDT[vect].reserved = 0;
	IDT[vect].reserved2 = 0;
	IDT[vect].baseLow = (unsigned short)(unsigned long long)function&0xFFFF;
	IDT[vect].baseMed = (unsigned short)((unsigned long long)function>>16)&0xFFFF;
	IDT[vect].baseHigh = (unsigned int)(unsigned long long)function>>16;
#endif
}
void installIDT()
{
	if(sizeof(IDT_reg) != 6)
	{
		Puts("Bad IDT reg\n");
	}
#ifdef WIN32
	if(sizeof(IDT_entry) != 8)
	{
		Puts("Bad IDT struct\n");
	}
#else
	if(sizeof(IDT_entry) != 16)
	{
		Puts("Bad IDT struct\n");
	}
#endif
	IDT_register.base = &IDT[0];
#ifdef WIN32
	IDT_register.limit = 256*8-1;
#else
	IDT_register.limit = 256*16-1;
#endif
	lidt(&IDT_register);
}

//ISR's
//These are called from assembly wrappers which handle the brunt
extern "C" {
void defaultHandler()
{
	disable();
	setColor(0x4,0xF);
	Cls();
	Puts(panicScreen);
	halt();
}

}

Finally, my assembly routine

BITS 32 ;my 32 bit version
extern @defaultHandler@0
@handlerDefault@0:
pushad
call @defaultHandler@0
popad
iret

BITS 64 ;and my 64 bit version
extern defaultHandler
handlerDefault:
call pusha
call defaultHandler
call popa
iretq

This links fine, what's going wrong?

Related links