aboutsummaryrefslogtreecommitdiff
path: root/arch/i386/lgdt.c
diff options
context:
space:
mode:
authoraqua <aqua@iserlohn-fortress.net>2024-03-08 17:24:49 +0200
committeraqua <aqua@iserlohn-fortress.net>2024-03-08 22:00:07 +0200
commit20b97ea7c0dbbdc13800e12ff5c86c00c4a342ec (patch)
tree473281e5fc8b256827ce1a678573444e1aa5f669 /arch/i386/lgdt.c
parentGenerate src/conf.h (diff)
downloadkernel-20b97ea7c0dbbdc13800e12ff5c86c00c4a342ec.tar.xz
Bazel build
Diffstat (limited to 'arch/i386/lgdt.c')
-rw-r--r--arch/i386/lgdt.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/i386/lgdt.c b/arch/i386/lgdt.c
new file mode 100644
index 0000000..473a91d
--- /dev/null
+++ b/arch/i386/lgdt.c
@@ -0,0 +1,25 @@
+#include "gdt.h"
+
+struct __attribute__((packed)) Pointer {
+ uint16_t limit;
+ uint32_t base;
+};
+
+static struct SegmentDescriptor_t segments[8] __attribute__((aligned(32)));
+
+void
+gdt_install()
+{
+ const struct Pointer ptr = {sizeof(segments) - 1, (unsigned)&segments};
+ SegmentDescriptor(&segments[0], 0, 0, 0); /* null segment */
+ SegmentDescriptor(&segments[2], 0, 0xffffffff, 0x9a); /* ktext segment */
+ SegmentDescriptor(&segments[3], 0, 0xffffffff, 0x92); /* kdata segment */
+
+ __asm__("lgdt (%0)" : : "a"(&ptr));
+
+ /* load the kernel data segment */
+ __asm__("mov %0, %%ds; mov %0, %%es; mov %0, %%fs; mov %0, %%gs; mov %0, %%ss" : : "ax"(kdataDescriptor));
+
+ /* load the kernel code segment */
+ __asm__("ljmp %0, $1f\n1:" : : "i"(ktextDescriptor));
+}