From b8a0024ee71a64ec0e87a1e2d0c0c7280dc954e6 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 09:36:00 +0000 Subject: create GDT and fix segment descriptor bit order --- .../descriptor_table/access_byte.cpp | 4 +- .../descriptor_table/gdt_flags.cpp | 2 +- .../descriptor_table/segment_descriptor.cpp | 22 ++++++++-- arch/x86_64/src/kernel/main.cpp | 50 ++++++++++++++++++++++ 4 files changed, 72 insertions(+), 6 deletions(-) (limited to 'arch/x86_64/src') diff --git a/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp index 7a2b0b0..4e5459f 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/access_byte.cpp @@ -2,9 +2,9 @@ namespace teachos::arch::context_switching::descriptor_table { - access_byte::access_byte(uint8_t flags) + access_byte::access_byte(uint8_t flags, uint8_t type_field) : _flags(flags) - , _type(flags) + , _type(type_field) { // Nothing to do. } diff --git a/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp index 8fbf869..65f2e90 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/gdt_flags.cpp @@ -5,7 +5,7 @@ namespace teachos::arch::context_switching::descriptor_table { gdt_flags::gdt_flags(uint8_t flags) - : _flags(flags << 5U) + : _flags(flags) { // Nothing to do. } diff --git a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp index 57564f2..ab8eaba 100644 --- a/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp +++ b/arch/x86_64/src/context_switching/descriptor_table/segment_descriptor.cpp @@ -4,7 +4,7 @@ namespace teachos::arch::context_switching::descriptor_table { segment_descriptor::segment_descriptor(uint128_t flags) : _reserved(flags >> 96U) - , _access((flags >> 40U) << 80U) + , _access((flags >> 44U) << 80U, (flags >> 40U) << 84U) , _flag((flags >> 52U) << 72U) , _base(((flags >> 64U) << 32U) << 32U | ((flags >> 56U) << 64U) << 24U | (flags >> 16U) << 88U) , _limit(((flags >> 48U) << 72U) << 16U | flags << 112U) @@ -12,13 +12,29 @@ namespace teachos::arch::context_switching::descriptor_table // Nothing to do. } + segment_descriptor::segment_descriptor(access_byte access_byte, gdt_flags flags, uint64_t base, + std::bitset<20U> limit) + : _reserved(0U) + , _access(access_byte) + , _flag(flags) + , _base(base) + , _limit(limit) + { + // Nothing to do + } + auto segment_descriptor::get_segment_type() const -> segment_descriptor_type { if (!_access.contains_flags(access_byte::CODE_OR_DATA_SEGMENT)) { return segment_descriptor_type::SYSTEM_SEGMENT; } - return _access.get_type_field().contains_flags(type_field::CODE_SEGMENT) ? segment_descriptor_type::CODE_SEGMENT - : segment_descriptor_type::DATA_SEGMENT; + + if (_access.get_type_field().contains_flags(type_field::CODE_SEGMENT)) + { + return segment_descriptor_type::CODE_SEGMENT; + } + + return segment_descriptor_type::DATA_SEGMENT; } } // namespace teachos::arch::context_switching::descriptor_table diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 472aed5..d3938ed 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,9 +1,11 @@ #include "arch/kernel/main.hpp" +#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" #include "arch/memory/multiboot/reader.hpp" +#include "arch/stl/vector.hpp" #include "arch/video/vga/text.hpp" namespace teachos::arch::kernel @@ -57,5 +59,53 @@ namespace teachos::arch::kernel memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); heap_test(); + + using context_switching::descriptor_table::access_byte; + using context_switching::descriptor_table::gdt_flags; + using context_switching::descriptor_table::segment_descriptor; + using context_switching::descriptor_table::segment_descriptor_type; + using context_switching::descriptor_table::type_field; + + segment_descriptor null_segment{0}; + + // Kernel space code segment + access_byte kernel_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::CODE_SEGMENT | type_field::READABLE}; + gdt_flags kernel_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; + segment_descriptor kernel_code_segment{kernel_code_access_byte, kernel_code_gdt_flags, 0, 0xFFFFF}; + + // Kernel space data segment + access_byte kernel_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_KERNEL | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::WRITABLE}; + gdt_flags kernel_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; + segment_descriptor kernel_data_segment{kernel_data_access_byte, kernel_data_gdt_flags, 0, 0xFFFFF}; + + // User space code segment + access_byte user_code_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::CODE_SEGMENT | type_field::READABLE}; + gdt_flags user_code_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::LENGTH}; + segment_descriptor user_code_segment{user_code_access_byte, user_code_gdt_flags, 0, 0xFFFFF}; + + // User space data segment + access_byte user_data_access_byte{access_byte::PRESENT | access_byte::ACCESS_LEVEL_USER | + access_byte::CODE_OR_DATA_SEGMENT, + type_field::WRITABLE}; + gdt_flags user_data_gdt_flags{gdt_flags::GRANULARITY | gdt_flags::UPPER_BOUND}; + segment_descriptor user_data_segment{user_data_access_byte, user_data_gdt_flags, 0, 0xFFFFF}; + + stl::vector global_descriptor_table{null_segment, kernel_code_segment, kernel_data_segment, + user_code_segment, user_data_segment}; + + decltype(auto) x = global_descriptor_table.at(1); + if (global_descriptor_table.size() == 0) + { + } + if (x.get_segment_type() == segment_descriptor_type::CODE_SEGMENT) + { + } + video::vga::text::write("GDT FILLED", video::vga::text::common_attributes::green_on_black); } } // namespace teachos::arch::kernel -- cgit v1.2.3