summaryrefslogtreecommitdiff
path: root/src/gdt.c
diff options
context:
space:
mode:
authorSimponic <loganthebean222@gmail.com>2021-02-20 23:24:25 -0700
committerSimponic <loganthebean222@gmail.com>2021-02-20 23:24:25 -0700
commita2a4a155c259d24101435771607b81f167b62cf3 (patch)
tree8e5dc73b21d02abbfe0f5185050c48908b3249ab /src/gdt.c
downloadsimponicos-a2a4a155c259d24101435771607b81f167b62cf3.tar.gz
simponicos-a2a4a155c259d24101435771607b81f167b62cf3.zip
Changed to nasm
Diffstat (limited to 'src/gdt.c')
-rw-r--r--src/gdt.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/gdt.c b/src/gdt.c
new file mode 100644
index 0000000..a9808aa
--- /dev/null
+++ b/src/gdt.c
@@ -0,0 +1,36 @@
+#include "gdt.h"
+
+void encodeGDT(uint8_t* gdtEntry, struct GDT source) {
+ if ((source.limit > 65536) && ((source.limit & 0xFFF) == 0xFFF)) {
+ // Set the GDT to use paging
+ // To do this we need to make sure the limit is aligned to 4KiB
+ source.limit = source.limit >> 12;
+ // Granularity: 1 (use paging with 4KiB segments)
+ // Size: 1 (32 bit protected mode)
+ gdtEntry[6] = 0xC0;
+ }
+ else {
+ // Granularity: 0 (1 byte segments)
+ // Size: 1
+ gdtEntry[6] = 0x40;
+ }
+
+ // Here we are encoding the limit
+
+ // Bits 0-15 encode the bottom 16 bits of the limit
+ gdtEntry[0] = source.limit & 0xFF;
+ gdtEntry[1] = (source.limit >> 8) & 0xFF;
+ // Bits 48-51 encode the last 4 bits of the limit
+ gdtEntry[6] |= (source.limit >> 16) & 0xF;
+
+ // Bits 16-39 encode the bottom 24 bits of the base
+ gdtEntry[2] = source.base & 0xFF;
+ gdtEntry[3] = (source.base >> 8) & 0xFF;
+ gdtEntry[4] = (source.base >> 16) & 0xFF;
+ // Bits 56-64 encode the last byte of the base
+ gdtEntry[7] = (source.base >> 24) & 0xFF;
+
+ // Bits 40-47 set the access byte, which is documented at https://wiki.osdev.org/GDT,
+ // where most of the ideas for this function are taken from shamelessly
+ gdtEntry[5] = source.type;
+}