My descriptor at entry 4 in the GDT is 0x4A800068 (00000000000000000000000000000000 1001010100000000000000001101000b).
The error from bochs is:
LTR: doesn't point to an available TSS descriptor!
There may be two's of stuff, but this code is just experimenting.
Code: Select all
int InitializeMemManager() {
SetupGDTDescriptor(0, 0x0, 0x0, 0x0, 0x0, 0x0);
SetupGDTDescriptor(1, 0x0, 0xFFFFF, GDT_DPL0|GDT_READABLE|GDT_SEG_CODE|GDT_PRESENT, GDT_286_CALL_GATE, 1);
SetupGDTDescriptor(2, 0x0, 0xFFFFF, GDT_DPL0|GDT_READABLE|GDT_SEG_DATA|GDT_PRESENT, GDT_286_CALL_GATE, 1);
InitTask(0, task1);
SetGDTDesc(4, getTasks(), sizeof(tss_seg), 0x9, SEG_DESC_ATTR_PRESENT|SEG_DESC_ATTR_SYSTEM, SEG_DESC_ATTR2_32BIT);
LoadGDTDescriptor(20);
LoadTaskRegister(getSelector(4, 0, 0));
return 0;
}
Code: Select all
#define SEG_DESC_ATTR_SYSTEM 0x1 // 0001b
#define SEG_DESC_ATTR_DPL0 0x0 // 0000b
#define SEG_DESC_ATTR_DPL1 0x2 // 0010b
#define SEG_DESC_ATTR_DPL2 0x4 // 0100b
#define SEG_DESC_ATTR_DPL3 0x6 // 0110b
#define SEG_DESC_ATTR_PRESENT 0x8 // 1000b
#define SEG_DESC_ATTR2_AVAIL 0x1 // 0001b
#define SEG_DESC_ATTR2_32BIT 0x4 // 0100b
#define SEG_DESC_ATTR2_GRAN 0x8 // 1000b
typedef struct {
uint16 low_limit;
uint16 low_base;
uint8 middle_base;
uint8 settings;
uint8 high_limit:4;
uint8 attributes:3;
uint8 granularity:1;
uint8 high_base;
} ATTR_PACKED x86_gdt;
typedef struct {
uint16 limit;
x86_gdt* base;
} ATTR_PACKED gdtr;
typedef struct {
uint8 rpl:2;
uint8 ti:1;
uint16 index:13;
} ATTR_PACKED seg_selector;
typedef struct {
uint16 limit_0_15;
uint16 base_0_15;
uint8 base_16_23;
uint8 type:4;
uint8 attr:4;
uint8 limit_16_19:4;
uint8 atrr2:4;
uint8 base_24_31;
} ATTR_PACKED seg_descriptor;
x86_gdt g_GDT[256] = {0};
void SetGDTDesc(uint16 _num, uint32 _base, uint32 _limit, uint8 _type, uint8 _attr, uint8 _attr2) {
seg_descriptor *pDesc = &g_GDT[_num];
pDesc->base_0_15 = (uint16)_base;
pDesc->base_16_23 = (uint8)(_base >> 16);
pDesc->base_24_31 = (uint8)(_base >> 24);
pDesc->limit_0_15 = (uint16)_limit;
pDesc->limit_16_19 = (uint8)(_limit >> 16);
pDesc->type = _type;
pDesc->attr = _attr;
pDesc->atrr2 = _attr2;
}
void SetupGDTDescriptor(uint32 _selector, uint32 _base, uint32 _limit, uint32 _settings, uint32 _attributes, uint8 _granul$
_settings |= 0x10;
g_GDT[_selector].attributes = _attributes;
g_GDT[_selector].settings = _settings;
g_GDT[_selector].granularity = _granularity;
g_GDT[_selector].low_base = (uint16)_base;
g_GDT[_selector].middle_base = (uint8)(_base >> 16);
g_GDT[_selector].high_base = (uint8)(_base >> 24);
g_GDT[_selector].low_limit = (uint16)_limit;
g_GDT[_selector].high_limit = (uint8)(_limit >> 16);
}
Code: Select all
#define TSS_DPL0 0x00
#define TSS_DPL1 0x20
#define TSS_DPL2 0x40
#define TSS_DPL3 0x60
#define TSS_PRESENT 0x80
#define EFLAGS_V86 0x40000
typedef struct {
uint8 reserved1;
uint8 type:4;
uint8 reserved2:1;
uint8 dpl:2;
uint8 p:1;
} ATTR_PACKED task_gate;
typedef struct {
uint16 seg_limit_0_15;
uint16 addr_0_15;
uint8 addr_16_23;
uint8 type;
uint8 seg_limit_16_19;
uint8 addr_24_31;
} ATTR_PACKED tss_desc;
typedef struct {
uint16 backlink, _blh;
uint32 esp0;
uint16 ss0, _ss0h;
uint32 esp1;
uint16 ss1, _ss1h;
uint32 esp2;
uint16 ss2, _ss2h;
uint32 cr3;
uint32 eip;
uint32 eflags;
uint32 eax;
uint32 ecx;
uint32 edx;
uint32 ebx;
uint32 esp;
uint32 ebp;
uint32 esi;
uint32 edi;
uint16 es, _esh;
uint16 cs, _csh;
uint16 ss, _ssh;
uint16 ds, _dsh;
uint16 fs, _fsh;
uint16 gs, _gsh;
uint16 ldt, _ldth;
uint16 trace, iomapbase;
} ATTR_PACKED tss_seg;
tss_seg g_Tasks[10];
void InitTask(uint8 _num, void *_task) {
g_Tasks[_num].esp = 0xFFFF;
g_Tasks[_num].es = 0x8;
g_Tasks[_num].cs = 0x10;
g_Tasks[_num].ss = 0x18;
g_Tasks[_num].ds = 0x8;
g_Tasks[_num].fs = 0x0;
g_Tasks[_num].gs = 0x0;
g_Tasks[_num].eip = _task;
g_Tasks[_num].eflags = 0x0002;
g_Tasks[_num].iomapbase = sizeof(tss_seg);
}