|
|
|
@ -19,7 +19,21 @@ struct gdt_entry_bits {
|
|
|
|
|
std::uint32_t base_high : 8;
|
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
|
|
constinit static const std::array<gdt_entry_bits, 3> gdt {{
|
|
|
|
|
struct TSSEntry
|
|
|
|
|
{
|
|
|
|
|
std::uint32_t prevTSS;
|
|
|
|
|
std::uint32_t esp0;
|
|
|
|
|
std::uint32_t ss0;
|
|
|
|
|
std::uint32_t unused[23];
|
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
|
|
static TSSEntry tss = {
|
|
|
|
|
.prevTSS = 0,
|
|
|
|
|
.esp0 = 0,
|
|
|
|
|
.ss0 = 0x10
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const std::array<gdt_entry_bits, 6> gdt {{
|
|
|
|
|
{},
|
|
|
|
|
/* kernel_code = */ {
|
|
|
|
|
.limit_low = 0xFFFF,
|
|
|
|
@ -54,6 +68,57 @@ constinit static const std::array<gdt_entry_bits, 3> gdt {{
|
|
|
|
|
.big = 1,
|
|
|
|
|
.gran = 1,
|
|
|
|
|
.base_high = 0x00
|
|
|
|
|
},
|
|
|
|
|
/* user_code = */ {
|
|
|
|
|
.limit_low = 0xFFFF,
|
|
|
|
|
.base_low = 0x0000,
|
|
|
|
|
.accessed = 0,
|
|
|
|
|
.read_write = 1,
|
|
|
|
|
.conforming_expand_down = 0,
|
|
|
|
|
.code = 1,
|
|
|
|
|
.code_data_segment = 1,
|
|
|
|
|
.DPL = 3,
|
|
|
|
|
.present = 1,
|
|
|
|
|
.limit_high = 0xF,
|
|
|
|
|
.available = 0,
|
|
|
|
|
.long_mode = 0,
|
|
|
|
|
.big = 1,
|
|
|
|
|
.gran = 1,
|
|
|
|
|
.base_high = 0x00
|
|
|
|
|
},
|
|
|
|
|
/* user_data = */ {
|
|
|
|
|
.limit_low = 0xFFFF,
|
|
|
|
|
.base_low = 0x0000,
|
|
|
|
|
.accessed = 0,
|
|
|
|
|
.read_write = 1,
|
|
|
|
|
.conforming_expand_down = 0,
|
|
|
|
|
.code = 0,
|
|
|
|
|
.code_data_segment = 1,
|
|
|
|
|
.DPL = 3,
|
|
|
|
|
.present = 1,
|
|
|
|
|
.limit_high = 0xF,
|
|
|
|
|
.available = 0,
|
|
|
|
|
.long_mode = 0,
|
|
|
|
|
.big = 1,
|
|
|
|
|
.gran = 1,
|
|
|
|
|
.base_high = 0x00
|
|
|
|
|
},
|
|
|
|
|
/* tss = */ {
|
|
|
|
|
.limit_low = sizeof(TSSEntry),
|
|
|
|
|
.base_low = (std::uint32_t)&tss & 0xFFFFFF,
|
|
|
|
|
.accessed = 1,
|
|
|
|
|
.read_write = 0,
|
|
|
|
|
.conforming_expand_down = 0,
|
|
|
|
|
.code = 1,
|
|
|
|
|
.code_data_segment = 0,
|
|
|
|
|
.DPL = 0,
|
|
|
|
|
.present = 1,
|
|
|
|
|
.limit_high = 0,
|
|
|
|
|
.available = 0,
|
|
|
|
|
.long_mode = 0,
|
|
|
|
|
.big = 0,
|
|
|
|
|
.gran = 0,
|
|
|
|
|
.base_high = (std::uint32_t)&tss >> 24
|
|
|
|
|
}
|
|
|
|
|
}};
|
|
|
|
|
|
|
|
|
@ -76,6 +141,29 @@ void gdt_initialize()
|
|
|
|
|
mov %%eax, %%fs
|
|
|
|
|
mov %%eax, %%gs
|
|
|
|
|
mov %%eax, %%ss
|
|
|
|
|
|
|
|
|
|
mov $0x28, %%ax
|
|
|
|
|
ltr %%ax
|
|
|
|
|
)" :: "m"(gdtr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void enter_user_mode(void (*func)())
|
|
|
|
|
{
|
|
|
|
|
asm volatile("mov %%esp, %0" : "=r" (tss.esp0));
|
|
|
|
|
|
|
|
|
|
asm volatile(R"(
|
|
|
|
|
mov $0x23, %%ax
|
|
|
|
|
mov %%ax, %%ds
|
|
|
|
|
mov %%ax, %%es
|
|
|
|
|
mov %%ax, %%fs
|
|
|
|
|
mov %%ax, %%gs
|
|
|
|
|
mov %%esp, %%eax
|
|
|
|
|
push $0x23
|
|
|
|
|
push %%esp
|
|
|
|
|
pushf
|
|
|
|
|
push $0x1b
|
|
|
|
|
push %0
|
|
|
|
|
iret
|
|
|
|
|
)" :: "b"(func));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|