From c4fcc92183c55db868d0d6ae53e6009fb2e53ee5 Mon Sep 17 00:00:00 2001 From: aqua Date: Sat, 29 Oct 2022 11:26:44 +0300 Subject: makefile: add i686/arch.a target --- i686/gdt.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i686/gdt.h (limited to 'i686/gdt.h') diff --git a/i686/gdt.h b/i686/gdt.h new file mode 100644 index 0000000..9148c3d --- /dev/null +++ b/i686/gdt.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +enum Ring { Ring0 = 0x0, Ring1 = 0x1, Ring2 = 0x2, Ring3 = 0x3 }; + +struct __attribute__((packed)) Access { + bool accessed : 1; // if 0, is set by processor when accessed + bool readwrite : 1; // code seg: read toggle; data seg: write toggle + bool direction : 1; // code seg: conforming bit; data seg: direction bit + bool executable : 1; // executable bit + bool segment : 1; // true for code/data; false for gates/tss + enum Ring privilege : 2; // descriptor privilege level + bool present : 1; // true for every active segment +}; +_Static_assert(sizeof(struct Access) == 1); + +static const struct Access null_access = {}; +static const struct Access ktext_access = {.readwrite = true, .executable = true, .segment = true, .present = true}; +static const struct Access kdata_access = {.readwrite = true, .segment = true, .present = true}; + +// Segment Descriptor +// A memory structure (part of a table) that tells the CPU the attributes of a given segment +// |31| | | | | | |24|23|22|21|20|19| | |16|15| | | | | | | 8| 7| | | | | | | 0| +// | base_31_24 | G|DB| | A| lim_19_16 | access | base_23_16 | +// | base_15_0 | limit_15_0 | +// |31| | | | | | | | | | | | | | |16|15| | | | | | | | | | | | | | | 0| +// limit size of segment - 1, either in bytes or in 4KiB chunks (check flags) +// base address of segment +// access +// flags defines the segment chunks and 16/32 bit +struct __attribute__((packed)) SegmentDescriptor_t { + uint16_t limit_15_0; // low bits of segment limit + uint16_t base_15_0; // low bits of segment base address + uint8_t base_23_16; // middle bits of segment base address + uint8_t access; // access byte + uint8_t limit_19_16 : 4; // high bits of segment limit + // flags + bool a : 1; // unused, available for software use + bool rsv : 1; // reserved + bool db : 1; // false => 16-bit seg; true => 32-bit seg + bool granularity : 1; // limit scaled by 4k when set + uint8_t base_31_24; // high bits of segment address +}; +_Static_assert(sizeof(struct SegmentDescriptor_t) == 8); + +void SegmentDescriptor(struct SegmentDescriptor_t *self, unsigned base, unsigned limit, uint8_t access); + +void gdt_install(); + +enum SegmentIndex { + ktextDescriptor = 2 * sizeof(struct SegmentDescriptor_t), + kdataDescriptor = 3 * sizeof(struct SegmentDescriptor_t), +}; -- cgit v1.2.1