From 88c519658649edcd647eb30917a57b12e73d7591 Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 16 Nov 2021 21:17:49 +0100 Subject: [PATCH] Rewritten GDT logic --- src/kernel/boot.S | 26 ++++++++++++++ src/kernel/gdt/gdt.s | 74 +++++---------------------------------- src/kernel/gdt/gdtc.cpp | 76 ++++++++++++++++++++++++++++------------- src/kernel/gdt/gdtc.h | 39 ++++++++++++--------- src/kernel/kernel.cpp | 3 +- 5 files changed, 111 insertions(+), 107 deletions(-) diff --git a/src/kernel/boot.S b/src/kernel/boot.S index f9ea085..0c79b10 100644 --- a/src/kernel/boot.S +++ b/src/kernel/boot.S @@ -50,3 +50,29 @@ _start: .include "./src/kernel/gdt/gdt.s" + + loadIDT: + #load idt + call init_idt + sti + + # Try enable A20 + # mov $0x2401, %ax + # int $0x15 + + + # enable protected mode + mov %cr0, %eax + or $1, %eax + mov %eax, %cr0 + + + call kernel_main + + + cli + 1: hlt + jmp 1b + + +.size _start, . - _start \ No newline at end of file diff --git a/src/kernel/gdt/gdt.s b/src/kernel/gdt/gdt.s index 25f7cd5..95859c2 100644 --- a/src/kernel/gdt/gdt.s +++ b/src/kernel/gdt/gdt.s @@ -1,75 +1,19 @@ -/* Tell processor to use our gdt*/ -gdt: - .word (gdt_end - gdt_start -1) # Size of the GDT in bytes minus 1 for math reasons - .int gdt_start # linear address of our GDT +.global LoadGlobalDescriptorTable - -.att_syntax + LoadGlobalDescriptorTable: + lgdt gdtDescriptor -.global load_gdt - load_gdt: - lgdt gdt - - # set the segment selecters - - movw $0x10, %ax + movw $16, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movw %ax, %ss - ljmp $0x08, $flush - flush: - + jmp $8,$flush + + flush: + ret - #load idt - call init_idt - sti - - # Try enable A20 - # mov $0x2401, %ax - # int $0x15 + - - # enable protected mode - mov %cr0, %eax - or $1, %eax - mov %eax, %cr0 - - - call kernel_main - - - cli - 1: hlt - jmp 1b - - -.size _start, . - _start - -/* -* Create the GDT -*/ -.section .data -gdt_start: -gdt_null: -.long 0x0 -.long 0x0 - -gdt_kcode: -.word 0xFFFF # limit -.word 0x0 # base -.byte 0x0 # base -.byte 0b10011010 # 1st flags | type flags -.byte 0b11001111 # 2nd flags | limit -.byte 0x0 # base - -gdt_kdata: -.word 0xFFFF # limit -.word 0x0 # base -.byte 0x0 # base -.byte 0b10010010 # 1st flags | type flags -.byte 0b11001111 # 2nd flags | limit -.byte 0x0 # base -gdt_end: diff --git a/src/kernel/gdt/gdtc.cpp b/src/kernel/gdt/gdtc.cpp index d806112..f2624bf 100644 --- a/src/kernel/gdt/gdtc.cpp +++ b/src/kernel/gdt/gdtc.cpp @@ -1,31 +1,61 @@ #include "gdtc.h" #include "../tty/kterm.h" - -gdtEntry_t gdt[3]; -gdtSegmentPointer gdtPointer{}; + +#define NULL_SEGMENT 0 +#define KERNEL_CODE_SEGMENT 1 +#define KERNEL_DATA_SEGMENT 2 +#define USER_CODE_SEGMENT 3 +#define USER_DATA_SEGMENT 4 + +SegmentDescriptor GlobalDescriptorTable[5]; +GlobalDescriptorTableDescriptor gdtDescriptor; + +void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){ + GlobalDescriptorTable[which].base_low = (base & 0xFFFF ); + GlobalDescriptorTable[which].base_middle = (base >> 6) & 0xFF; + GlobalDescriptorTable[which].base_high = (base >> 24) & 0xFF; + + GlobalDescriptorTable[which].limit_low = (limit & 0xFFFF); + GlobalDescriptorTable[which].granularity = ((limit >> 16) & 0x0F); + + GlobalDescriptorTable[which].granularity |= (granularity & 0xF0); + GlobalDescriptorTable[which].access = access; - -void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access, - uint8_t gran){ - gdt[num].lBase = (base & 0xFFFF); - gdt[num].mBase = (base >> 16) & 0xFF; - gdt[num].hBase = (base >> 24) & 0xFF; - - gdt[num].lLimit = (limit & 0xFFFF); - gdt[num].granularity = ((limit >> 16) & 0x0F); - - gdt[num].granularity |= (gran & 0xF0); - gdt[num].access = access; } -void setupGdt(){ - gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1; - gdtPointer.base = (uint32_t) &gdt; - gdtSetGate(0, 0, 0, 0, 0); - gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); - gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); - printf("call to load gdt\n"); - load_gdt(); + + +void initGDT(){ + + // NULL segment + add_descriptor(NULL_SEGMENT, 0,0,0,0); + + // Kernel Code Segment + add_descriptor(KERNEL_CODE_SEGMENT, 0, 0xFFFFFFFF, 0x9A, 0xCF); + + // Kernel Data Segment + add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF); + + // User Code Segment + // TODO: + + // User Data Segement + // TODO: + + // init Gdt Descriptor + gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1); + gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable; + + + + LoadGlobalDescriptorTable(); + + while (true) + asm volatile("hlt"); + + + + } diff --git a/src/kernel/gdt/gdtc.h b/src/kernel/gdt/gdtc.h index 517a98a..548bc5e 100644 --- a/src/kernel/gdt/gdtc.h +++ b/src/kernel/gdt/gdtc.h @@ -1,22 +1,27 @@ #include -extern "C"{ -typedef struct { - uint16_t lLimit; - uint16_t lBase; - uint8_t mBase; - uint8_t access; - uint8_t granularity; - uint8_t hBase; -} gdtEntry_t; -struct gdtSegmentPointer { - uint16_t limit; - uint32_t base; -}; +struct SegmentDescriptor { + unsigned short limit_low; + unsigned short base_low; + unsigned char base_middle; + unsigned char access; + unsigned char granularity; + unsigned char base_high; +}__attribute__((packed)); -extern gdtSegmentPointer gdtPointer; -extern void load_gdt(); -void setupGdt(); -} \ No newline at end of file +struct GlobalDescriptorTableDescriptor{ + unsigned short limit; + unsigned int base; +}__attribute__((packed)); + +extern SegmentDescriptor GlobalDescriptorTable[]; +extern GlobalDescriptorTableDescriptor gdtDescriptor; + + +void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ); + + +extern "C" void LoadGlobalDescriptorTable(); +void initGDT(); diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index cb338d2..d30350d 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -26,8 +26,7 @@ printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end); } - printf("Call to setupGdt!\n"); - setupGdt(); + initGDT(); }