diff --git a/kernel/arch/i386/GDT.cpp b/kernel/arch/i386/GDT.cpp deleted file mode 100644 index ed251b5f..00000000 --- a/kernel/arch/i386/GDT.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include - -#include - -namespace GDT -{ - - union SegmentDesriptor - { - struct - { - uint16_t limit_lo; - uint16_t base_lo; - uint8_t base_hi1; - - uint8_t type : 4; - uint8_t system : 1; - uint8_t DPL : 2; - uint8_t present : 1; - - uint8_t limit_hi : 4; - uint8_t flags : 4; - - uint8_t base_hi2; - } __attribute__((packed)); - - struct - { - uint32_t low; - uint32_t high; - } __attribute__((packed)); - - SegmentDesriptor() : low(0), high(0) {} - SegmentDesriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t _flags) - : low(0), high(0) - { - set_base(base); - set_limit(limit); - - high |= ((uint16_t)access) << 8; - flags = _flags; - } - - void set_base(uint32_t base) - { - base_lo = base & 0xFFFF; - base_hi1 = (base >> 16) & 0x00FF; - base_hi2 = (base >> 24) & 0x00FF; - } - - void set_limit(uint32_t limit) - { - limit_lo = limit & 0xFFFF; - limit_hi = (limit >> 16) & 0x00FF; - } - - } __attribute__((packed)); - - struct GDTR - { - uint16_t size; - void* address; - } __attribute__((packed)); - - static GDTR s_gdtr; - static SegmentDesriptor s_gdt[5]; - - extern "C" void load_gdt(void* gdt_ptr); - asm( - ".global load_gdt;" - "load_gdt:" - "movl 4(%esp),%eax;" - "lgdt (%eax);" - - "movw $0x10, %ax;" - "movw %ax, %ds;" - "movw %ax, %es;" - "movw %ax, %fs;" - "movw %ax, %gs;" - "movw %ax, %ss;" - "jmp $0x08,$flush;" - - "flush:" - "ret;" - ); - - void write_entry_raw(uint8_t segment, uint32_t low, uint32_t high) - { - uint8_t index = segment >> 3; - s_gdt[index].low = low; - s_gdt[index].high = high; - } - - void write_entry(uint8_t segment, SegmentDesriptor descriptor) - { - write_entry_raw(segment, descriptor.low, descriptor.high); - } - - void initialize() - { - s_gdtr.address = s_gdt; - s_gdtr.size = sizeof(s_gdt) - 1; - - write_entry(0x00, { 0, 0x00000, 0x00, 0x0 }); // null - write_entry(0x08, { 0, 0xFFFFF, 0x9A, 0xC }); // kernel code - write_entry(0x10, { 0, 0xFFFFF, 0x92, 0xC }); // kernel data - write_entry(0x18, { 0, 0xFFFFF, 0xFA, 0xC }); // user code - write_entry(0x20, { 0, 0xFFFFF, 0xF2, 0xC }); // user data - - load_gdt(&s_gdtr); - } - -} \ No newline at end of file diff --git a/kernel/arch/i386/boot.S b/kernel/arch/i386/boot.S index 8a13e13c..29fc471a 100644 --- a/kernel/arch/i386/boot.S +++ b/kernel/arch/i386/boot.S @@ -29,6 +29,13 @@ g_kernel_cmdline: .skip 4096 + .global g_gdtr + g_gdtr: + .skip 2 + 4 + .global g_gdt + g_gdt: + .skip 5 * 8 + # Reserve memory for paging structures, # we will identity map first 4 MiB @@ -110,19 +117,7 @@ enable_sse: movl %eax, %cr4 ret -.global _start -.type _start, @function -_start: - # Initialize stack and multiboot info - movl $stack_top, %esp - movl %eax, g_multiboot_magic - movl %ebx, g_multiboot_info - - # Copy kernel command line to known location - call copy_kernel_commandline - call check_requirements - call enable_sse - +initialize_paging: # identity map first 4 MiB movl $(0x00000000 + 0x83), boot_page_directory1 + 0 movl $(0x00200000 + 0x83), boot_page_directory1 + 8 @@ -142,14 +137,55 @@ _start: orl $0x80000000, %ecx movl %ecx, %cr0 - # call global constuctors + ret + +initialize_gdt: + # setup gdt + movw $(5 * 8 - 1), g_gdtr + movl $(g_gdt), g_gdtr + 2 + movl $(0x0000FFFF), g_gdt + 0x08 + movl $(0x00CF9A00), g_gdt + 0x08 + 4 + movl $(0x0000FFFF), g_gdt + 0x10 + movl $(0x00CF9200), g_gdt + 0x10 + 4 + movl $(0x0000FFFF), g_gdt + 0x18 + movl $(0x00CFFA00), g_gdt + 0x18 + 4 + movl $(0x0000FFFF), g_gdt + 0x20 + movl $(0x00CFF200), g_gdt + 0x20 + 4 + lgdt g_gdtr + + # flush gdt + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + jmp $0x08, $flush +flush: + ret + + +.global _start +.type _start, @function +_start: + # Initialize stack and multiboot info + movl $stack_top, %esp + movl %eax, g_multiboot_magic + movl %ebx, g_multiboot_info + + call copy_kernel_commandline + call check_requirements + call enable_sse + + call initialize_paging + call initialize_gdt + call _init # call to the kernel itself (clear ebp for stacktrace) xorl %ebp, %ebp call kernel_main - # call global destructors call _fini system_halt: diff --git a/kernel/arch/i386/make.config b/kernel/arch/i386/make.config index 5f59e678..c933cf40 100644 --- a/kernel/arch/i386/make.config +++ b/kernel/arch/i386/make.config @@ -7,7 +7,6 @@ KERNEL_ARCH_OBJS= \ $(ARCHDIR)/APIC.o \ $(ARCHDIR)/boot.o \ $(ARCHDIR)/CPUID.o \ -$(ARCHDIR)/GDT.o \ $(ARCHDIR)/IDT.o \ $(ARCHDIR)/MMU.o \ $(ARCHDIR)/Panic.o \ diff --git a/kernel/include/kernel/GDT.h b/kernel/include/kernel/GDT.h index 9e23c4b2..c28ccc71 100644 --- a/kernel/include/kernel/GDT.h +++ b/kernel/include/kernel/GDT.h @@ -1,8 +1,44 @@ #pragma once +#include + namespace GDT { - void initialize(); + union SegmentDesriptor + { + struct + { + uint16_t limit_lo; + uint16_t base_lo; + uint8_t base_hi1; + + uint8_t type : 4; + uint8_t system : 1; + uint8_t DPL : 2; + uint8_t present : 1; + + uint8_t limit_hi : 4; + uint8_t flags : 4; + + uint8_t base_hi2; + } __attribute__((packed)); + + struct + { + uint32_t low; + uint32_t high; + } __attribute__((packed)); + + } __attribute__((packed)); + + struct GDTR + { + uint16_t size; + void* address; + } __attribute__((packed)); + + extern "C" GDTR g_gdtr[]; + extern "C" SegmentDesriptor g_gdt[]; } \ No newline at end of file diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 176f87d3..55585574 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -70,8 +70,6 @@ extern "C" void kernel_main() kmalloc_initialize(); dprintln("kmalloc initialized"); - GDT::initialize(); - dprintln("GDT initialized"); IDT::initialize(); dprintln("IDT initialized");