You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.4 KiB
C++
82 lines
2.4 KiB
C++
4 weeks ago
|
#include <array>
|
||
|
#include <cstdint>
|
||
|
|
||
|
struct gdt_entry_bits {
|
||
|
std::uint32_t limit_low : 16;
|
||
|
std::uint32_t base_low : 24;
|
||
|
std::uint32_t accessed : 1;
|
||
|
std::uint32_t read_write : 1; // readable for code, writable for data
|
||
|
std::uint32_t conforming_expand_down : 1; // conforming for code, expand down for data
|
||
|
std::uint32_t code : 1; // 1 for code, 0 for data
|
||
|
std::uint32_t code_data_segment : 1; // should be 1 for everything but TSS and LDT
|
||
|
std::uint32_t DPL : 2; // privilege level
|
||
|
std::uint32_t present : 1;
|
||
|
std::uint32_t limit_high : 4;
|
||
|
std::uint32_t available : 1; // only used in software; has no effect on hardware
|
||
|
std::uint32_t long_mode : 1;
|
||
|
std::uint32_t big : 1; // 32-bit opcodes for code, uint32_t stack for data
|
||
|
std::uint32_t gran : 1; // 1 to use 4k page addressing, 0 for byte addressing
|
||
|
std::uint32_t base_high : 8;
|
||
|
} __attribute__((packed));
|
||
|
|
||
|
constinit static const std::array<gdt_entry_bits, 3> gdt {{
|
||
|
{},
|
||
|
/* kernel_code = */ {
|
||
|
.limit_low = 0xFFFF,
|
||
|
.base_low = 0x0000,
|
||
|
.accessed = 0,
|
||
|
.read_write = 1,
|
||
|
.conforming_expand_down = 0,
|
||
|
.code = 1,
|
||
|
.code_data_segment = 1,
|
||
|
.DPL = 0,
|
||
|
.present = 1,
|
||
|
.limit_high = 0xF,
|
||
|
.available = 0,
|
||
|
.long_mode = 0,
|
||
|
.big = 1,
|
||
|
.gran = 1,
|
||
|
.base_high = 0x00
|
||
|
},
|
||
|
/* kernel_data = */ {
|
||
|
.limit_low = 0xFFFF,
|
||
|
.base_low = 0x0000,
|
||
|
.accessed = 0,
|
||
|
.read_write = 1,
|
||
|
.conforming_expand_down = 0,
|
||
|
.code = 0,
|
||
|
.code_data_segment = 1,
|
||
|
.DPL = 0,
|
||
|
.present = 1,
|
||
|
.limit_high = 0xF,
|
||
|
.available = 0,
|
||
|
.long_mode = 0,
|
||
|
.big = 1,
|
||
|
.gran = 1,
|
||
|
.base_high = 0x00
|
||
|
}
|
||
|
}};
|
||
|
|
||
|
void gdt_initialize()
|
||
|
{
|
||
|
auto gdtr = reinterpret_cast<std::uint64_t>(gdt.data());
|
||
|
gdtr <<= 16;
|
||
|
gdtr |= gdt.size() * sizeof(gdt[0]);
|
||
|
|
||
|
asm volatile(R"(
|
||
|
lgdt %0
|
||
|
pushl $0x8
|
||
|
push $.setcs
|
||
|
ljmp *(%%esp)
|
||
|
.setcs:
|
||
|
add $8, %%esp
|
||
|
mov $0x10, %%eax
|
||
|
mov %%eax, %%ds
|
||
|
mov %%eax, %%es
|
||
|
mov %%eax, %%fs
|
||
|
mov %%eax, %%gs
|
||
|
mov %%eax, %%ss
|
||
|
)" :: "m"(gdtr));
|
||
|
}
|
||
|
|