From 0787b1a1fc4a7ee003418c4ee56c00b0ded6bd34 Mon Sep 17 00:00:00 2001 From: starnakin Date: Mon, 9 Sep 2024 18:00:17 +0200 Subject: [PATCH] add: gdt (peut etre y'a un gdt on sait pas) --- headers/gdt.h | 18 +++++++++++++ src/gdt/gdt.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/gdt/sgdt.s | 12 +++++++++ src/kernel.c | 3 ++- 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 headers/gdt.h create mode 100644 src/gdt/gdt.c create mode 100644 src/gdt/sgdt.s diff --git a/headers/gdt.h b/headers/gdt.h new file mode 100644 index 0000000..53b61e3 --- /dev/null +++ b/headers/gdt.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +struct gdt_entry { + uint32_t limit; + uint32_t base; + uint8_t access_byte; + uint8_t flags; +}; + +// https://wiki.osdev.org/Global_Descriptor_Table#GDTR +struct gdt_descriptor { + uint16_t size; + uint32_t base; +} __attribute__((packed)); + +void initGdt(); \ No newline at end of file diff --git a/src/gdt/gdt.c b/src/gdt/gdt.c new file mode 100644 index 0000000..d0d0c2c --- /dev/null +++ b/src/gdt/gdt.c @@ -0,0 +1,70 @@ +#include "gdt.h" +#include "kprintf.h" + +extern void setGdt(void *); + +void encodeGdtEntry(uint8_t *target, struct gdt_entry source) +{ + // Check the limit to make sure that it can be encoded + if (source.limit > 0xFFFFF) { + kprintf(KERN_ERR, "GDT cannot encode limits larger than 0xFFFFF"); + } + + // Encode the limit + target[0] = source.limit & 0xFF; + target[1] = (source.limit >> 8) & 0xFF; + target[6] = (source.limit >> 16) & 0x0F; + + // Encode the base + target[2] = source.base & 0xFF; + target[3] = (source.base >> 8) & 0xFF; + target[4] = (source.base >> 16) & 0xFF; + target[7] = (source.base >> 24) & 0xFF; + + // Encode the access byte + target[5] = source.access_byte; + + // Encode the flags + target[6] |= (source.flags << 4); +} +// sizeof(Segment Descriptor) * nb(Segment Descriptor) +uint8_t *gdt_entries = (uint8_t *) 0x00000800; +struct gdt_descriptor gdtr; + +void initGdt() +{ + gdtr.size = 8 * 5 - 1; + gdtr.base = (uint32_t) &gdt_entries; + + struct gdt_entry gdt_entry_null_descriptor = { .base = 0, + .limit = 0x00000000, + .access_byte = 0x00, + .flags = 0x0}; + encodeGdtEntry(gdt_entries + 0x0000, gdt_entry_null_descriptor); + + struct gdt_entry gdt_entry_kernel_mode_code_segment = { .base = 0, + .limit = 0xFFFFF, + .access_byte = 0x9A, + .flags = 0xC }; + encodeGdtEntry(gdt_entries + 0x0008, gdt_entry_kernel_mode_code_segment); + + struct gdt_entry gdt_entry_kernel_mode_data_segment = { .base = 0, + .limit = 0xFFFFF, + .access_byte = 0x92, + .flags = 0xC }; + encodeGdtEntry(gdt_entries + 0x0010, gdt_entry_kernel_mode_data_segment); + + struct gdt_entry gdt_entry_user_mode_code_segment = { .base = 0, + .limit = 0xFFFFF, + .access_byte = 0xFA, + .flags = 0xC }; + encodeGdtEntry(gdt_entries + 0x0018, gdt_entry_user_mode_code_segment); + + struct gdt_entry gdt_entry_user_mode_data_segment = { .base = 0, + .limit = 0xFFFFF, + .access_byte = 0xF2, + .flags = 0xC }; + encodeGdtEntry(gdt_entries + 0x0020, gdt_entry_user_mode_data_segment); + + setGdt(&gdtr); +} \ No newline at end of file diff --git a/src/gdt/sgdt.s b/src/gdt/sgdt.s new file mode 100644 index 0000000..87829d9 --- /dev/null +++ b/src/gdt/sgdt.s @@ -0,0 +1,12 @@ +.globl setGdt + +gdtr: .word 0 # For limit storage + .long 0 # For base storage + +setGdt: + movw 4(%esp), %ax # Move the word at [esp + 4] into AX + movw %ax, gdtr # Move AX into gdtr + movl 8(%esp), %eax # Move the double word at [esp + 8] into EAX + movl %eax, gdtr + 2 # Move EAX into gdtr + 2 + lgdt gdtr # Load the GDT + ret \ No newline at end of file diff --git a/src/kernel.c b/src/kernel.c index 5d5cf31..800cd23 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -22,8 +22,9 @@ void kernel_main(void) terminal_initialize(); /* Newline support is left as an exercise. */ - for (int i = 1001; i; i--) + for (int i = 100; i; i--) kprintf(0, "%d\n", i); + void initGdt(); kprintf(0, "mange ta mere avec ton argument a kprintf fdp\n"); while (true) terminal_getkey();