diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2025-01-02 09:49:33 -0500 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2025-01-02 09:49:33 -0500 |
commit | 0dde3ff57bbbf90eb7d9ce1b7aff0dd706875653 (patch) | |
tree | f6bbec7df77b14a14dda18a2d44e435cbb9dcd31 | |
parent | 49fa3246c0e19a089ffcebe85b65acdcbb478411 (diff) |
kernel: Properly initialize GDT
-rw-r--r-- | kernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | kernel/boot/gdt.c | 21 | ||||
-rw-r--r-- | kernel/boot/gdt.s | 26 | ||||
-rw-r--r-- | kernel/boot/init/boot.s | 2 | ||||
-rw-r--r-- | kernel/include/boot/gdt.h | 20 | ||||
-rw-r--r-- | kernel/kernel/kernel.c | 7 |
6 files changed, 65 insertions, 12 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index d2a019b..94d0e15 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -4,6 +4,7 @@ project(kernel C ASM) set(KERNEL_SRC boot/init/boot.s boot/gdt.c + boot/gdt.s kernel/kernel.c kernel/halt.c diff --git a/kernel/boot/gdt.c b/kernel/boot/gdt.c index 34bbfe3..4644b3d 100644 --- a/kernel/boot/gdt.c +++ b/kernel/boot/gdt.c @@ -18,6 +18,8 @@ #include <stdint.h> +#include <kernel/io.h> + #include <boot/gdt.h> GDT_entry GDT[] = { @@ -28,7 +30,22 @@ GDT_entry GDT[] = { GDT_ENTRY(0, 0xfffff, KERNEL_CODE_SEGMENT_ACCESS_FLAGS, FLAGS), /* Kernel Mode Data Segment */ - GDT_ENTRY(0, 0xfffff, KERNEL_DATA_SEGMENT_ACCESS_FLAGS, FLAGS) + GDT_ENTRY(0, 0xfffff, KERNEL_DATA_SEGMENT_ACCESS_FLAGS, FLAGS), + + /* User Mode Code Segment */ + GDT_ENTRY(0, 0xfffff, USER_CODE_SEGMENT_ACCESS_FLAGS, FLAGS), + + /* User Mode Data Segment */ + GDT_ENTRY(0, 0xfffff, USER_DATA_SEGMENT_ACCESS_FLAGS, FLAGS) + + /* TODO: TSS? */ + /* TODO: LDT? */ }; -GDT_descriptor g_GDT_descriptor = { sizeof(GDT) - 1, GDT }; +GDT_descriptor g_GDT_descriptor = { sizeof(GDT_entry) * 5 - 1, &GDT[0] }; + +void +GDT_load(void) +{ + _GDT_flush(&g_GDT_descriptor); +} diff --git a/kernel/boot/gdt.s b/kernel/boot/gdt.s new file mode 100644 index 0000000..ee50e4e --- /dev/null +++ b/kernel/boot/gdt.s @@ -0,0 +1,26 @@ +.intel_syntax noprefix + +.global _GDT_flush +.type _GDT_flush, @function +_GDT_flush: + /* First Argument (Pointer to the GDT) */ + mov eax, [esp + 4] + + /* Load GDT */ + lgdt [eax] + + /* Offset For Kernel Data Segment (16 bits) */ + mov eax, 0x10 + + /* Set the Data Segment Selectors */ + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + /* Set the Code Segment Selector */ + jmp 0x08:.flush + +.flush: + ret diff --git a/kernel/boot/init/boot.s b/kernel/boot/init/boot.s index 32ebe8f..35a89a2 100644 --- a/kernel/boot/init/boot.s +++ b/kernel/boot/init/boot.s @@ -96,8 +96,6 @@ _start: runtime support to work as well. */ - /* TODO: Initialize global descriptor table */ - /* Call the global constructors. */ call _init diff --git a/kernel/include/boot/gdt.h b/kernel/include/boot/gdt.h index b07d64d..7cf7d35 100644 --- a/kernel/include/boot/gdt.h +++ b/kernel/include/boot/gdt.h @@ -19,6 +19,8 @@ #ifndef __boot_gdt_h #define __boot_gdt_h +#include <stdint.h> + /* Access Flags: * 7 PRESENT * 6 PRIVILEGE @@ -38,14 +40,20 @@ #define READABLE_WRITABLE(x) (x << 1) #define ACCESSED(x) x -#define KERNEL_CODE_SEGMENT_ACCESS_FLAGS \ - PRESENT(1) | PRIVILEGE(0) | TYPE(1) | EXECUTABLE(1) \ +#define CODE_SEGMENT_ACCESS_FLAGS(privilege) \ + PRESENT(1) | PRIVILEGE(privilege) | TYPE(1) | EXECUTABLE(1) \ | DIRECTION_CONFORMING(0) | READABLE_WRITABLE(1) | ACCESSED(0) -#define KERNEL_DATA_SEGMENT_ACCESS_FLAGS \ - PRESENT(1) | PRIVILEGE(0) | TYPE(1) | EXECUTABLE(0) \ +#define DATA_SEGMENT_ACCESS_FLAGS(privilege) \ + PRESENT(1) | PRIVILEGE(privilege) | TYPE(1) | EXECUTABLE(0) \ | DIRECTION_CONFORMING(0) | READABLE_WRITABLE(1) | ACCESSED(0) +#define KERNEL_CODE_SEGMENT_ACCESS_FLAGS CODE_SEGMENT_ACCESS_FLAGS(0) +#define KERNEL_DATA_SEGMENT_ACCESS_FLAGS DATA_SEGMENT_ACCESS_FLAGS(0) + +#define USER_CODE_SEGMENT_ACCESS_FLAGS CODE_SEGMENT_ACCESS_FLAGS(3) +#define USER_DATA_SEGMENT_ACCESS_FLAGS DATA_SEGMENT_ACCESS_FLAGS(3) + /* Other Flags: * 3 GRANULARITY * 2 SIZE @@ -92,7 +100,7 @@ typedef struct { GDT_entry *ptr; /* Address of GDT */ } __attribute__((packed)) GDT_descriptor; -/* TODO: Implement GDT_load() */ -void __attribute((cdecl)) GDT_load(void); +extern void _GDT_flush(GDT_descriptor *); +void GDT_load(void); #endif diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index 20e5bb4..7deb6ec 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <boot/gdt.h> #include <kernel/halt.h> #include <libk/io.h> @@ -26,11 +27,13 @@ void kernel_main(void) { - vga_text_buffer_initialize(); - serial_initialize(); + GDT_load(); printk("Kernel", "Started."); + vga_text_buffer_initialize(); + serial_initialize(); + // exit(); halt(); /* If exit() fails (on real hardware) */ } |