User:Bellezzasolo/IDT problems: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
(Update ro completed ones) |
No edit summary |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== Problems with IDTs == |
== 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've been in trouble myself. |
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've been 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, |
That is why I created this page - a wiki page you can easily access that's in a nice format. Introduction aside, here are the solved problems. |
||
This is for solved problems. The unsolved ones can be found here on the |
This is for solved problems. The unsolved ones can be found here on the |
||
[http://forum.osdev.org/viewtopic.php?f=1&t=24805 Forum] |
[http://forum.osdev.org/viewtopic.php?f=1&t=24805 Forum] |
||
== |
==Problems== |
||
{{stub|nocat=1}} |
|||
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. |
|||
Please post '''''Completed''''' problems here. |
|||
First of all check your GDT. Then check padding issues. |
|||
Now you understand the environment, this is the bochs output |
|||
<pre> |
|||
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 |
|||
</pre> |
|||
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 |
|||
<source lang="cpp"> |
|||
//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(); |
|||
</source> |
|||
IDT.cpp |
|||
<source lang="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(); |
|||
} |
|||
} |
|||
</source> |
|||
Finally, my assembly routine |
|||
<source lang="asm"> |
|||
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 |
|||
</source> |
|||
Thakyou to [[User talk:Alfaomega08|Alfaomega08]] for helping me. |
|||
Here is the solution: |
|||
<source lang="cpp"> |
|||
#pragma pack(push, 1) |
|||
class IDT_entry |
|||
{ |
|||
// blah blah blah |
|||
}; |
|||
#pragma pack(pop) |
|||
</source> |
|||
and |
|||
<source lang="cpp"> |
|||
if(sizeof(IDT_reg) != 6) |
|||
{ |
|||
Puts("Bad IDT reg\n"); |
|||
Halt(); |
|||
} |
|||
</source> |
|||
Where Halt is an infinite loop or a "cli; hlt" so that you can actually see the message being put. |
|||
== Related links == |
== Related links == |
||
Line 185: | Line 19: | ||
*[[I_Cant_Get_Interrupts_Working|Interrupt problems]] |
*[[I_Cant_Get_Interrupts_Working|Interrupt problems]] |
||
[[Category:X86 CPU]] |
[[:Category:X86 CPU]] |
||
[[Category:Interrupts]] |
[[:Category:Interrupts]] |
||
[[Category:Troubleshooting]] |
[[:Category:Troubleshooting]] |
||
[[Category:User drafts]] |
Latest revision as of 19:57, 16 June 2024
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've been 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, here are the solved problems.
This is for solved problems. The unsolved ones can be found here on the Forum
Problems
This page is a stub.
You can help the wiki by accurately adding more contents to it.
Please post Completed problems here.
First of all check your GDT. Then check padding issues.
Related links
Category:X86 CPU Category:Interrupts Category:Troubleshooting