110 lines
2.2 KiB
C++
110 lines
2.2 KiB
C++
#include "gdt.h"
|
|
|
|
tss_struct tss = (tss_struct) {
|
|
.link = 0,
|
|
._reserved0 = 0,
|
|
.esp0 = 0xc1006000,
|
|
.ss0 = 0x10,
|
|
._reserved1 = 0,
|
|
.esp1 = 0,
|
|
.ss1 = 0,
|
|
._reserved2 = 0,
|
|
.esp2 = 0,
|
|
.ss2 = 0,
|
|
._reserved3 = 0,
|
|
.cr3 = 0,
|
|
.eip = 0,
|
|
.eflags = 0,
|
|
.eax = 0,
|
|
.ebx = 0,
|
|
.ecx = 0,
|
|
.edx = 0,
|
|
.esp = 0,
|
|
.ebp = 0,
|
|
.esi = 0,
|
|
.edi = 0,
|
|
.es = 0,
|
|
._reserved4 = 0,
|
|
.cs = 0,
|
|
._reserved5 = 0,
|
|
.ss = 0,
|
|
._reserved6 = 0,
|
|
.ds = 0,
|
|
._reserved7 = 0,
|
|
.fs = 0,
|
|
._reserved8 = 0,
|
|
.gs = 0,
|
|
._reserved9 = 0,
|
|
.ldtr = 0,
|
|
._reserved10 = 0,
|
|
._reserved11 = 0,
|
|
.iopb = sizeof(tss_struct)
|
|
};
|
|
|
|
constexpr gdt_entry::gdt_entry(uint32_t limit, uint32_t base, bool rw, bool exec, bool system, uint8_t ring) :
|
|
limit_lo(limit & 0xffff),
|
|
limit_hi((limit & 0xf0000) >> 16),
|
|
base_lo(base & 0xffff),
|
|
base_mid((base & 0xff0000) >> 16),
|
|
base_hi((base & 0xff000000) >> 24),
|
|
__ignored__(0),
|
|
accessed(0),
|
|
granularity(1),
|
|
size(1),
|
|
present(1),
|
|
read_write(rw),
|
|
executable(exec),
|
|
system_segment(system),
|
|
privilege(ring),
|
|
direction(0)
|
|
{}
|
|
|
|
constexpr gdt_entry::gdt_entry() :
|
|
limit_lo(0),
|
|
base_lo(0),
|
|
base_mid(0),
|
|
accessed(0),
|
|
read_write(0),
|
|
direction(0),
|
|
executable(0),
|
|
system_segment(0),
|
|
privilege(0),
|
|
present(0),
|
|
limit_hi(0),
|
|
__ignored__(0),
|
|
size(0),
|
|
granularity(0),
|
|
base_hi(0)
|
|
{}
|
|
|
|
gdt_and_iopb gai = {
|
|
.gdt = {
|
|
gdt_entry(), // Null Segment
|
|
gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Kernel Code Segment
|
|
gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Kernel Data Segment
|
|
|
|
gdt_entry(0xfffff, 0, 1, 1, 1, 3), // User Code Segment
|
|
gdt_entry(0xfffff, 0, 1, 0, 1, 3), // User Data Segment
|
|
|
|
gdt_entry() // Empty Task State Segment
|
|
}
|
|
};
|
|
|
|
gdt_descr descr = (gdt_descr){
|
|
.size = sizeof(gai.gdt) - 1,
|
|
.offset = gai.gdt,
|
|
};
|
|
|
|
void init_gdt() {
|
|
gai.gdt[5] = gdt_entry(sizeof(tss) + 8193, &tss, 0, 1, 0, 0); // Initialise the TSS.
|
|
gai.gdt[5].accessed = 1;
|
|
for (int i=0; i<8192; i++)
|
|
gai.iopb[i] = 0;
|
|
asm volatile("lgdt %0;"
|
|
"mov $0x10, %%eax;"
|
|
"mov %%eax, %%ss;"
|
|
"mov %%eax, %%ds;"
|
|
"mov $0x28, %%ax;"
|
|
"ltr %%ax" : : "m" (descr));
|
|
Global::tss = &tss;
|
|
} |