The code -
Code: Select all
#ifdef x86
#include <Segmentation.hpp>
#include <Interrupt.hpp>
#include <Registration.hpp>
extern "C" void FlushTSS();
/* Don't compile Native.asm on non-x86 */
extern "C" {
struct NativeDescTablePointer GDTPtr;
struct SegmentDescriptor GDTable[6];
struct TSS systemTSS;
}
extern "C" void setGate(uint32_t gateNo, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity) {
GDTable[gateNo].lowerBase = base & 0xffff;
GDTable[gateNo].middleBase = (base >> 16) & 0xff;
GDTable[gateNo].higherBase = (base >> 24) & 0xff;
GDTable[gateNo].lowerLimit = limit & 0xffff;
GDTable[gateNo].granularity = (limit >> 16) & 0xf;
GDTable[gateNo].granularity |= granularity & 0xf0;
GDTable[gateNo].access = access;
}
extern "C" void setupTSS(uint32_t offset, uint16_t ss0, uint16_t esp0) {
uint32_t base = (uint32_t) &systemTSS;
uint32_t size = base + sizeof(TSS);
setGate(offset, base, size, 0xe9, 1);
unsigned char *tssLocation = (unsigned char*) &systemTSS;
for(int offset = 0; offset < sizeof(systemTSS); offset++) {
tssLocation[offset] = 0;
}
// systemTSS.eflags = 0x1202;
systemTSS.ss0 = ss0;
systemTSS.esp0 = esp0;
systemTSS.cs = 0x0B;
systemTSS.ss = // These specify what segments
systemTSS.ds = // should be loaded when the
systemTSS.es = // processor switches to
systemTSS.fs = // kernel mode.
systemTSS.gs =
0x13;
systemTSS.iomap = sizeof(TSS);
}
extern "C" void setupSegmentation() {
#ifdef segmentationEnabled
GDTPtr.limit = (sizeof(struct SegmentDescriptor) * 3) - 1;
GDTPtr.base = (uint32_t) GDTable;
setGate(0, 0, 0, 0, 0); // NULL Descriptor
setGate(1, 0, 0xffffffff, 0x9a, 0xcf);
setGate(2, 0, 0xffffffff, 0x92, 0xcf);
setGate(3, 0, 0xffffffff, 0xfa, 0xcf);
setGate(4, 0, 0xffffffff, 0xf2, 0xcf);
setupTSS(5, 0x10, 0x0); // fine without FlushTSS
FlushGDT();
FlushTSS(); // This is a problem - { mov ax, 0x2b; ltr ax; ret }
#endif
}
Code: Select all
extern GDTPtr
FlushGDT:
lgdt [GDTPtr]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:SegmentReturn
SegmentReturn:
ret
FlushTSS:
mov ax, 0x2B
ltr ax
ret