TSS ltr Instruction Failure
Posted: Sat Mar 03, 2012 12:01 pm
Hello,
I am trying to install a TSS into the GDT. The processor triple faults on the _asm ltr eax; instruction though. Here is the code (it handles both my GDT and TSS).
I am trying to install a TSS into the GDT. The processor triple faults on the _asm ltr eax; instruction though. Here is the code (it handles both my GDT and TSS).
Code: Select all
void GDT::InstallGDT()
{
GDT::Private::GDTList = (GDT::Private::GDTStr*)Heap::Malloc(8 * 256, 0);
memset(GDT::Private::GDTList, 0, 8 * 256);
GDT::InitializeKernelGDT();
GDT::Private::GDTItr itr;
itr.Size = (8 * 256) - 1;
itr.Offset = (dword)GDT::Private::GDTList;
_asm lgdt [itr];
_asm cli;
_asm mov eax, 0x2B;
_asm ltr eax;
_asm sti;
}
void GDT::InitializeKernelGDT()
{
GDT::InstallGDTEntry(0xFFFFF, 0, 1, 1, 0, 1, 1, 1);
GDT::InstallGDTEntry(0xFFFFF, 0, 1, 0, 0, 1, 1, 2);
GDT::InstallGDTEntry(0xFFFFF, 0, 1, 1, 3, 1, 1, 3);
GDT::InstallGDTEntry(0xFFFFF, 0, 1, 0, 3, 1, 1, 4);
GDT::InstallGDTEntry((dword)&GDT::Private::KTSS + sizeof(GDT::Private::TSS), (dword)&GDT::Private::KTSS, false, true, 3, true, false, 5);
memset((void*)&GDT::Private::KTSS, 0, sizeof(GDT::Private::TSS));
GDT::Private::KTSS.ss0 = 0x10;
GDT::Private::KTSS.esp0 = 0;
GDT::Private::KTSS.cs = 0xB;
GDT::Private::KTSS.ss = 0x13;
GDT::Private::KTSS.es = 0x13;
GDT::Private::KTSS.ds = 0x13;
GDT::Private::KTSS.fs = 0x13;
GDT::Private::KTSS.gs = 0x13;
}
void GDT::InstallGDTEntry(dword Limit, dword Base, bool ReadandWrite, bool Code, byte Privl, bool i32Bit, bool i4kbGran, byte Index)
{
GDT::Private::GDTStr newGdt;
newGdt.Limit = (Limit & 0xFFFF);
newGdt.Base = (Base & 0xFFFF);
newGdt.Base2 = ((Base >> 16) & 0xFF);
newGdt.Accessed = 1;
newGdt.ReadWrite = ReadandWrite;
newGdt.Direction = 0;
newGdt.Executable = Code;
newGdt.Reserved1 = 1;
newGdt.Privl = Privl;
newGdt.Present = 1;
newGdt.Limit2 = ((Limit >> 16) & 0xF);
newGdt.Reserved2 = 0;
newGdt.Reserved3 = 0;
newGdt.Size = i32Bit;
newGdt.Gran = i4kbGran;
newGdt.Base3 = ((Base >> 24) & 0xF);
memcpy(&GDT::Private::GDTList[Index], &newGdt, sizeof(GDT::Private::GDTStr));
}