GitHub

@@ -1,6 +1,7 @@

11

#include "gdt.h"

22

#include "gdt_structures.h"

33

#include <std/memory.h>

4+

#include <stdbool.h>

4556

// TSS definition modified from http://www.jamesmolloy.co.uk/tutorial_html/10.-User%20Mode.html

67

typedef struct tss_entry {

@@ -46,6 +47,25 @@ typedef struct gdt_def2 {

4647

uint8_t base_high; // The last 8 bits of the base.

4748

} __attribute__((packed)) gdt_def2_t;

484950+

typedef struct gdt_def3 {

51+

uint16_t limit_low;

52+

uint16_t base_low;

53+

uint8_t base_middle;

54+

bool accessed:1;

55+

bool readable:1;

56+

bool conforming:1;

57+

bool is_code:1;

58+

bool belongs_to_os:1;

59+

uint8_t dpl:2;

60+

bool present:1;

61+

uint8_t limit_high:4;

62+

bool available:1;

63+

bool long_mode:1;

64+

bool default_operand_size:1;

65+

bool granularity:1;

66+

uint8_t base_high;

67+

} __attribute__((packed)) gdt_def3_t;

68+4969

static void gdt_set_gate(void* gdt_entries_ptr, int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) {

5070

gdt_def2_t* gdt_entries = gdt_entries_ptr;

5171

gdt_entries[num].base_low = (base & 0xFFFF);

@@ -84,11 +104,17 @@ static void tss_init(void* gdt_base, uint16_t gdt_offset, uint16_t ss0, uint32_t

84104

}

8510586106

static void gdt_write_descriptor(gdt_entry_t* entry, uint32_t base, uint32_t limit, uint16_t flag) {

107+

uint32_t tmp = limit & 0x000F0000;

108+

tmp |= (flag);

109+

printf("tmp 0x%08x\n", tmp);

110+87111

//write the high 32 bit word

88112

//set limit bits 19:16

89113

entry->high_word = limit & 0x000F0000;

90114

//set type, p, dpl, s, g, d/b, l and avl fields

91-

entry->high_word |= (flag << 8) & 0x00F0FF00;

115+

//entry->high_word |= (flag << 8) & 0x00F0FF00;

116+

entry->high_word |= flag;

117+

printf("tm2 0x%08x\n", entry->high_word);

92118

//set base bits 23:16

93119

entry->high_word |= (base >> 16) & 0x000000FF;

94120

//set base bits 31:24

@@ -101,22 +127,158 @@ static void gdt_write_descriptor(gdt_entry_t* entry, uint32_t base, uint32_t lim

101127

entry->low_word |= limit & 0x0000FFFF;

102128

}

103129130+

typedef struct __attribute__((packed)) {

131+

uint16_t limit_low; /*!< The low word of the limit */

132+

uint16_t base_low; /*!< The low word of the base */

133+134+

uint8_t base_middle; /*!< The low byte of the upper word of the base */

135+

uint8_t access; /*!< The access flags for the entry */

136+

uint8_t limit_high; /*!< The high byte of the limit. Also contains the flags */

137+

uint8_t base_high; /*!< The high byte of the upper word of the base */

138+

} gdt_entry2_t;

139+140+

void gdt_set_entry(gdt_entry2_t* entry, uint32_t limit, uint32_t base, uint8_t access, uint8_t flags) {

141+

// Set up the limit stuff

142+

entry->limit_low = (uint16_t)(limit & 0xFFFF);

143+

entry->limit_high = (uint8_t)((limit & 0xF0000) >> 16);

144+145+

// Set up the base

146+

entry->base_low = (uint16_t)(base & 0xFFFF);

147+

entry->base_middle = (uint8_t)((base & 0xFF0000) >> 16);

148+

entry->base_high = (uint8_t)((base & 0xFF000000) >> 24);

149+150+

// Set up any flags

151+

entry->limit_high |= (uint8_t)(flags);

152+

entry->access = access;

153+

}

154+155+

void gdt_set_flat_entry(gdt_entry2_t* entry, uint8_t access, uint8_t flags) {

156+

gdt_set_entry(entry, 0xFFFFF, 0, access, flags);

157+

}

158+159+

void gdt_activate(gdt_pointer_t* table);

160+104161

void gdt_init() {

105-

static gdt_entry_t gdt_entries[16] = {0};

106-

static gdt_descriptor_t gdt_descriptor = {0};

162+

//assert(sizeof(gdt_def3_t) == 8, "Must be exactly 8 bytes!");

163+

printf("sizeof(gdt_def3_t) = %d\n", sizeof(gdt_def3_t));

164+

static gdt_entry_t gdt_entries[16] = {0};

165+

static gdt_pointer_t table = {0};

107166108-

gdt_descriptor.table_base = (uint32_t)&gdt_entries;

109-

gdt_descriptor.table_size = sizeof(gdt_entries) - 1;

167+

table.table_base = (uint32_t)&gdt_entries;

168+

table.table_size = sizeof(gdt_entries) - 1;

110169111170

gdt_write_descriptor(&gdt_entries[0], 0, 0, 0);

171+

gdt_def3_t cs_kernel_long = {

172+

.limit_low = 0xFFFF,

173+

.base_low = 0x0,

174+

.base_middle = 0x0,

175+

.accessed = 0,

176+

.readable = 1,

177+

.conforming = 0, // todo 0

178+

.is_code = 1,

179+

.belongs_to_os = 1,

180+

.dpl = 0,

181+

.present = 1,

182+

.limit_high = 0xF,

183+

.available = 0, // todo 0

184+

.long_mode = 1,

185+

.default_operand_size = 0, // must be 0

186+

.granularity = 1,

187+

.base_high = 0

188+

};

189+

memcpy(&gdt_entries[1], &cs_kernel_long, sizeof(cs_kernel_long));

190+191+

gdt_def3_t ds_kernel_long = {

192+

.limit_low = 0xFFFF,

193+

.base_low = 0x0,

194+

.base_middle = 0x0,

195+

.accessed = 0,

196+

.readable = 1,

197+

.conforming = 0, // todo 0 // For data segment this means expand down

198+

.is_code = 0,

199+

.belongs_to_os = 1,

200+

.dpl = 0,

201+

.present = 1,

202+

.limit_high = 0xF,

203+

.available = 0, // todo 0

204+

.long_mode = 1,

205+

.default_operand_size = 0, // must be 0

206+

.granularity = 1,

207+

.base_high = 0

208+

};

209+

memcpy(&gdt_entries[2], &ds_kernel_long, sizeof(ds_kernel_long));

210+211+

/*

212+

Orig

213+

ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]

214+

CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]

215+

SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]

216+

DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]

217+

FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]

218+

GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]

219+

LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT

220+

TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy

221+

GDT= 000000000104a960 0000007f

222+223+

ES =0010 0000000000000000 ffffffff 00bf9700 DPL=0 DS [EWA]

224+

CS =0008 0000000000000000 ffffffff 00bf9e00 DPL=0 CS64 [CR-]

225+

SS =0010 0000000000000000 ffffffff 00bf9700 DPL=0 DS [EWA]

226+

DS =0010 0000000000000000 ffffffff 00bf9700 DPL=0 DS [EWA]

227+

FS =0010 0000000000000000 ffffffff 00bf9700 DPL=0 DS [EWA]

228+

GS =0010 0000000000000000 ffffffff 00bf9700 DPL=0 DS [EWA]

229+

LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT

230+

TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy

231+

GDT= 000000000104a960 0000007f

232+233+

ES =0010 0000000000000000 ffffffff 00af9300 DPL=0 DS [-WA]

234+

CS =0008 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]

235+

SS =0010 0000000000000000 ffffffff 00af9300 DPL=0 DS [-WA]

236+

DS =0010 0000000000000000 ffffffff 00af9300 DPL=0 DS [-WA]

237+

FS =0010 0000000000000000 ffffffff 00af9300 DPL=0 DS [-WA]

238+

GS =0010 0000000000000000 ffffffff 00af9300 DPL=0 DS [-WA]

239+

LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT

240+

TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy

241+

GDT= 000000000104a960 0000007f

242+

*/

243+

/*

112244

gdt_write_descriptor(&gdt_entries[1], 0x00000000, 0x000FFFFF, (GDT_CODE_PL0));

113245

gdt_write_descriptor(&gdt_entries[2], 0x00000000, 0x000FFFFF, (GDT_DATA_PL0));

114246

gdt_write_descriptor(&gdt_entries[3], 0x00000000, 0x000FFFFF, (GDT_CODE_PL3));

115247

gdt_write_descriptor(&gdt_entries[4], 0x00000000, 0x000FFFFF, (GDT_DATA_PL3));

248+

*/

249+250+

//gdt_write_descriptor(&gdt_entries[1], 0x0, 0x000FFFFF, (GDT_CODE_R0_x64));

251+

/*

252+

uint32_t flags = 0;

253+

flags |= (1 << 9); // Readable

254+

flags |= (1 << 11); // Always 1

255+

flags |= (1 << 12); // 0 = system, 1 = user. Select 1 for code/data segments

256+

flags |= (0 << 13); // Ring level (DPL)

257+

flags |= (1 << 15); // Present

258+

flags |= (1 << 21); // Long mode

259+

flags |= (0 << 22); // Default operand size; must be cleared in long mode

260+

flags |= (1 << 23); // Granularity: 4KB

261+

gdt_write_descriptor(&gdt_entries[1], 0x0, 0x000FFFFF, flags);

262+263+

flags &= ~(1 << 11); // Always 0

264+

flags &= ~(1 << 10); // Always 0

265+

flags |= (1 << 9); // Always 0

266+

gdt_write_descriptor(&gdt_entries[2], 0x0, 0x000FFFFF, flags);

267+

*/

116268117-

tss_init(gdt_entries, 5, 0x10, 0x00);

269+

//gdt_write_descriptor(&gdt_entries[2], 0x0, 0x0FFFFFFF, (GDT_DATA_R0_x64));

270+

//tss_init(gdt_entries, 5, 0x10, 0x00);

118271119-

gdt_activate((uint32_t)&gdt_descriptor);

272+

printf("Set GDT to %d 0x%x\n", &table, &table);

273+

gdt_activate(&table);

274+

//printf("Done load, do jmp\n");

275+

//gdt_load_cs(SEGMENT_INDEX(1) | SEGMENT_RPL_KERNEL);

276+

gdt_load_cs(0x08);

277+

//gdt_load_ds(SEGMENT_INDEX(2) | SEGMENT_RPL_KERNEL);

278+

gdt_load_ds(0x10);

279+

asm("cli");

280+

asm("hlt");

281+

printf("Done!\n");

120282

tss_activate();

121283

}

122284

Read the original on github.com ↗