Page 1 of 3

IDT problems

Posted: Mon Feb 06, 2012 11:27 am
by bellezzasolo
Please post any IDT problems you have here. WHen they're solved they will be placed on the the wiki here: IDT problems

Re: IDT problems

Posted: Mon Feb 06, 2012 11:54 am
by turdus
bellezzasolo wrote:Please post any IDT problems you have here. WHen they're solved they will be placed on the the wiki here: IDT problems
I'm not sure we should have a wiki page for every struggle, specially when error message is so informative like this one:

Code: Select all

interrupt(): not accessible or not code segment cs = 0x0008
interrupt(): gate descriptor not valid sys seg (vector = 0x0d)
It's more than obvious.

I think this kind of topic belongs to forum, not wiki documentation, it cloud mislead people searching for "IDT" by irrelevant results.

Re: IDT problems

Posted: Mon Feb 06, 2012 12:59 pm
by bluemoon
It's funny to see #ifdef WIN32 in your OS code...

And for your IDT problem article, you are solving alignment / padding issue...

Re: IDT problems

Posted: Wed Feb 08, 2012 7:13 am
by bellezzasolo
I am demoting the code to the forum.
Solved problems will be paced on the wiki

so here it is:
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 [http://www.brokenthorn.com/Resources/OSDevIndex.html 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

Code: Select all

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

Code: Select all

//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

Code: Select all

#include "IDT.h"
#include "..\Asm\Asmlayer.h"
#include <cstddef.h>
#include <stdout.h>
#include "panic.h"
//structures
#pragma pack(push,1)
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
};
#pragma pack(pop)
#pragma pack(push,1)
class IDT_reg {
public:
	unsigned short limit;
	IDT_entry* base;
};
#pragma pack(pop)

//data

static IDT_reg IDT_register;
static IDT_entry IDT [256] = {0};

//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");
		halt();
	}
#ifdef WIN32
	if(sizeof(IDT_entry) != 8)
	{
		Puts("Bad IDT struct\n");
		halt();
	}
#else
	if(sizeof(IDT_entry) != 16)
	{
		Puts("Bad IDT struct\n");
		halt();
	}
#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

Code: Select all

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
Where Halt is "hlt" so that you can actually see the message being put. Interrupts should be disabled before lidt, so if I don't see the message problem could be that.
I agree it's funny to see #ifdef WIN32, but thats VC++ for you. :lol:

Re: IDT problems

Posted: Wed Feb 08, 2012 7:14 am
by bellezzasolo
By upolling the PIC I can now get a command line. But I still want interrupts! Please help! [-o<

Re: IDT problems

Posted: Wed Feb 08, 2012 12:24 pm
by neon
Hello,

May I ask why you still arent packing the structure to 1 byte? That would greatly simplify your code. Also, dont ever use WIN32 in your system software. If you must utilize MSVC specific code, use _MSC_VER.

Re: IDT problems

Posted: Wed Feb 08, 2012 1:36 pm
by bellezzasolo
Sorry for the lack of clarification.
I am compiling for 64 bit as well. That is why I use the #ifdef WIN32 ... #else
also, I define myself, and as it is simplest to do it this way I do it.

P.S I am a great fan of your series

Re: IDT problems

Posted: Wed Feb 08, 2012 3:00 pm
by AJ
Hi,

I don't understand the logic behind an "IDT Problem" article. Surely the IDT is one of the most documented, well defined features of the x86/x86_64 processor? If there's a problem with the IDT, you're not doing it right and the information will be in the Intel manuals.

@OP: Is this just a round-about way of you asking for help setting up your IDT?

Cheers,
Adam

Re: IDT problems

Posted: Thu Feb 09, 2012 1:48 am
by bellezzasolo
I feel people can benefit from this article as the documentation will tell you a large amount of information about the structure, but not implementation in an compiled environment. We all can find out the basic structures from the IDT page, but the implementation could be a lot more difficult.
Please help me, as I can't see what's wrong with it! :?

Re: IDT problems

Posted: Thu Feb 09, 2012 5:52 am
by bluemoon
In fact the implementation is not that difficult once you understand the manual. It's just few lines of code.
I discourage skipping the manual simply because you feel it contain too much information and try to avoid it.

EDIT: If you need an implementation, there are plenty of barebone tutorials.

Re: IDT problems

Posted: Thu Feb 09, 2012 6:13 am
by gerryg400
According to

Code: Select all

interrupt(): not accessible or not code segment cs = 0x0008
your GDT may be wrong. Have you tested your GDT by doing a far jmp ?

Re: IDT problems

Posted: Thu Feb 09, 2012 7:06 am
by bellezzasolo
actually no. I will try it.

Re: IDT problems

Posted: Thu Feb 09, 2012 7:14 am
by bellezzasolo
yeah, and don't point out the >>16 error on the 64 bit version, I will correct that. I tried &(*function) but still wouldn't work. Thankyou for the GDT lead. I should know if this is the problem within a few hours.

Re: IDT problems

Posted: Thu Feb 09, 2012 8:14 am
by gravaera
bellezzasolo wrote:Please note before you give me GCC specific adivce I have a slightly unusual setup
We speak in terms of a set of conventionally accepted tools on this forum: if you use a different toolchain/language, it's your job to ensure that you can translate information given here into your "nonstandard" working environment -- that's your issue, nobody here has to take your setup into consideration, or else we'd never get anything done.

Some things I noticed in passing that aren't very palatable:

Code: Select all

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:
Bochs is telling you that there is a problem with the Code selector you loaded. You need to check it over, that's all. The bad selector is causing a fault.
IDT.cpp

Code: Select all

#pragma pack(push,1)
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
};
#pragma pack(pop)
The preprocessing above is probably meant to ensure portabiilty across compilers, but you padded the structure for the non-MSVC case, so naturally the non-msvc case won't work; you might also want to look into using stdint.h for your integer types from now so you can save yourself trouble later on.

--Peace out
gravaera

Re: IDT problems

Posted: Thu Feb 09, 2012 11:12 am
by bellezzasolo
Thankyou. IRQ's now work (although a panic screen)
Here is normal operation:
Normal operation (no IRQ)
Normal operation (no IRQ)
Here is panic:
Panic
Panic