aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/kernel/main.cpp26
-rw-r--r--arch/x86_64/src/memory/frame_allocator.cpp35
-rw-r--r--arch/x86_64/src/memory/multiboot.cpp28
-rw-r--r--arch/x86_64/src/memory/paging.cpp53
4 files changed, 98 insertions, 44 deletions
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index bdf530c..7e4a336 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -5,6 +5,8 @@
#include "arch/memory/multiboot.hpp"
#include "arch/video/vga/text.hpp"
+#include <algorithm>
+
namespace teachos::arch::kernel
{
auto assert(bool condition) -> void
@@ -63,7 +65,7 @@ namespace teachos::arch::kernel
for (auto section = begin; section != end; ++section)
{
- bool const writeable = section->flags.writeable();
+ bool const writable = section->flags.writable();
bool const occupies_memory = section->flags.occupies_memory();
bool const is_executable = section->flags.is_executable();
bool const contains_duplicate_data = section->flags.contains_duplicate_data();
@@ -79,7 +81,7 @@ namespace teachos::arch::kernel
bool const is_excluded_unless_referenced_or_allocated =
section->flags.is_excluded_unless_referenced_or_allocated();
- if (writeable && occupies_memory && is_executable && contains_duplicate_data && contains_strings &&
+ if (writable && occupies_memory && is_executable && contains_duplicate_data && contains_strings &&
section_header_info_is_section_header_table_index && preserve_ordering_after_combination &&
requires_special_os_processing && is_section_group_member && holds_thread_local_data && is_compressed &&
has_special_ordering_requirements && is_excluded_unless_referenced_or_allocated)
@@ -182,20 +184,16 @@ namespace teachos::arch::kernel
// Address of Frame: 0x203F00
auto allocator = arch::memory::area_frame_allocator(kernel_start, kernel_end, multiboot_start, multiboot_end,
memory_areas, area_count);
- auto allocated = allocator.allocate_frame();
// WATCH OUT: using optional::value() crashes the build... I think its because of missing exception handling
- if (allocated.has_value())
- {
- video::vga::text::write("Allocated Frame address: ", video::vga::text::common_attributes::green_on_black);
- video::vga::text::write_number(reinterpret_cast<uint64_t>(&allocated->frame_number),
- video::vga::text::common_attributes::green_on_black);
- video::vga::text::write("Allocated Frame number: ", video::vga::text::common_attributes::green_on_black);
- video::vga::text::write_number(allocated->frame_number, video::vga::text::common_attributes::green_on_black);
- }
- else
+ auto last_allocated = allocator.allocate_frame();
+ auto allocated = last_allocated;
+ do
{
- video::vga::text::write("NO VALUE", video::vga::text::common_attributes::green_on_black);
- }
+ last_allocated = allocated;
+ allocated = allocator.allocate_frame();
+ } while (allocated.has_value());
+ video::vga::text::write("Allocated Frames", video::vga::text::common_attributes::green_on_black);
+ video::vga::text::write_number(allocated->frame_number, video::vga::text::common_attributes::green_on_black);
}
} // namespace teachos::arch::kernel
diff --git a/arch/x86_64/src/memory/frame_allocator.cpp b/arch/x86_64/src/memory/frame_allocator.cpp
index 3ad2d96..3733cc3 100644
--- a/arch/x86_64/src/memory/frame_allocator.cpp
+++ b/arch/x86_64/src/memory/frame_allocator.cpp
@@ -2,13 +2,16 @@
namespace teachos::arch::memory
{
- frame::frame(std::size_t frame_number)
+ physical_frame::physical_frame(std::size_t frame_number)
: frame_number(frame_number)
{
// Nothing to do
}
- auto frame::containing_address(std::size_t address) -> frame { return frame{address / PAGE_FRAME_SIZE}; }
+ auto physical_frame::containing_address(std::size_t address) -> physical_frame
+ {
+ return physical_frame{address / PAGE_FRAME_SIZE};
+ }
memory_area_iterator::memory_area_iterator(memory_area * p)
: ptr(p)
@@ -39,7 +42,7 @@ namespace teachos::arch::memory
memory_area & area = *it;
std::size_t address = area.base_address + area.area_length - 1;
- if (frame::containing_address(address) >= next_free_frame)
+ if (physical_frame::containing_address(address) >= next_free_frame)
{
// The `next_free_frame` address is smaller than the last address of the current area
if (!current_area || area.base_address < current_area->base_address)
@@ -52,7 +55,7 @@ namespace teachos::arch::memory
if (current_area)
{
// Update the `next_free_frame` according to the new memory area
- frame start_frame = frame::containing_address(current_area->base_address);
+ physical_frame start_frame = physical_frame::containing_address(current_area->base_address);
if (next_free_frame < start_frame)
{
next_free_frame = start_frame;
@@ -60,7 +63,7 @@ namespace teachos::arch::memory
}
}
- auto area_frame_allocator::allocate_frame() -> std::optional<frame>
+ auto area_frame_allocator::allocate_frame() -> std::optional<physical_frame>
{
/*
* Only try to allocate memory if current_area is not null, because
@@ -68,29 +71,29 @@ namespace teachos::arch::memory
*/
if (current_area)
{
- frame frame{next_free_frame.frame_number};
+ physical_frame physical_frame{next_free_frame.frame_number};
- struct frame current_area_last_frame = {
- frame::containing_address(current_area->base_address + current_area->area_length - 1)};
+ struct physical_frame current_area_last_frame = {
+ physical_frame::containing_address(current_area->base_address + current_area->area_length - 1)};
if (next_free_frame > current_area_last_frame)
{
// All frames of current area are used, switch to next area
choose_next_area();
}
- else if (frame >= multiboot_start && frame <= kernel_end)
+ else if (physical_frame >= multiboot_start && physical_frame <= kernel_end)
{
- // `frame` is used by the kernel or multiboot information structure
- next_free_frame = arch::memory::frame{kernel_end.frame_number + 1};
+ // `physical_frame` is used by the kernel or multiboot information structure
+ next_free_frame = arch::memory::physical_frame{kernel_end.frame_number + 1};
}
else
{
// Frame is unused, increment `next_free_frame` and return it
next_free_frame.frame_number += 1;
- return frame;
+ return physical_frame;
}
- // `frame` was not valid, try it again with the updated `next_free_frame`
+ // `physical_frame` was not valid, try it again with the updated `next_free_frame`
return allocate_frame();
}
@@ -98,10 +101,10 @@ namespace teachos::arch::memory
return std::nullopt;
}
- auto area_frame_allocator::deallocate_frame(frame frame) -> void
+ auto area_frame_allocator::deallocate_frame(physical_frame physical_frame) -> void
{
- // TODO: Fix, simply done because compiler will complain if frame is unused and not compile
- if (frame.frame_number == 3)
+ // TODO: Fix, simply done because compiler will complain if physical_frame is unused and not compile
+ if (physical_frame.frame_number == 3)
{
}
}
diff --git a/arch/x86_64/src/memory/multiboot.cpp b/arch/x86_64/src/memory/multiboot.cpp
index 3f6248d..bd3b00b 100644
--- a/arch/x86_64/src/memory/multiboot.cpp
+++ b/arch/x86_64/src/memory/multiboot.cpp
@@ -2,35 +2,35 @@
namespace teachos::arch::memory
{
- auto elf_section_flags::writeable() const -> bool { return is_bit_set(0); }
+ auto elf_section_flags::writable() const -> bool { return is_bit_set(0U); }
- auto elf_section_flags::occupies_memory() const -> bool { return is_bit_set(1); }
+ auto elf_section_flags::occupies_memory() const -> bool { return is_bit_set(1U); }
- auto elf_section_flags::is_executable() const -> bool { return is_bit_set(2); }
+ auto elf_section_flags::is_executable() const -> bool { return is_bit_set(2U); }
- auto elf_section_flags::contains_duplicate_data() const -> bool { return is_bit_set(4); }
+ auto elf_section_flags::contains_duplicate_data() const -> bool { return is_bit_set(4U); }
- auto elf_section_flags::contains_strings() const -> bool { return is_bit_set(5); }
+ auto elf_section_flags::contains_strings() const -> bool { return is_bit_set(5U); }
- auto elf_section_flags::section_header_info_is_section_header_table_index() const -> bool { return is_bit_set(6); }
+ auto elf_section_flags::section_header_info_is_section_header_table_index() const -> bool { return is_bit_set(6U); }
- auto elf_section_flags::preserve_ordering_after_combination() const -> bool { return is_bit_set(7); }
+ auto elf_section_flags::preserve_ordering_after_combination() const -> bool { return is_bit_set(7U); }
- auto elf_section_flags::requires_special_os_processing() const -> bool { return is_bit_set(8); }
+ auto elf_section_flags::requires_special_os_processing() const -> bool { return is_bit_set(8U); }
- auto elf_section_flags::is_section_group_member() const -> bool { return is_bit_set(9); }
+ auto elf_section_flags::is_section_group_member() const -> bool { return is_bit_set(9U); }
- auto elf_section_flags::holds_thread_local_data() const -> bool { return is_bit_set(10); }
+ auto elf_section_flags::holds_thread_local_data() const -> bool { return is_bit_set(10U); }
- auto elf_section_flags::is_compressed() const -> bool { return is_bit_set(11); }
+ auto elf_section_flags::is_compressed() const -> bool { return is_bit_set(11U); }
- auto elf_section_flags::has_special_ordering_requirements() const -> bool { return is_bit_set(30); }
+ auto elf_section_flags::has_special_ordering_requirements() const -> bool { return is_bit_set(30U); }
- auto elf_section_flags::is_excluded_unless_referenced_or_allocated() const -> bool { return is_bit_set(31); }
+ auto elf_section_flags::is_excluded_unless_referenced_or_allocated() const -> bool { return is_bit_set(31U); }
auto elf_section_flags::operator==(elf_section_flags const & other) const -> bool { return flags == other.flags; }
- auto elf_section_flags::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1; }
+ auto elf_section_flags::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1U; }
auto elf_section_header::is_null() const -> bool
{
diff --git a/arch/x86_64/src/memory/paging.cpp b/arch/x86_64/src/memory/paging.cpp
new file mode 100644
index 0000000..555357c
--- /dev/null
+++ b/arch/x86_64/src/memory/paging.cpp
@@ -0,0 +1,53 @@
+#include "arch/memory/paging.hpp"
+
+namespace teachos::arch::memory
+{
+ auto entry::is_unused() const -> bool { return flags == 0U; }
+
+ auto entry::set_unused() -> void { flags = 0U; }
+
+ auto entry::present() const -> bool { return is_bit_set(0U); }
+
+ auto entry::writable() const -> bool { return is_bit_set(1U); }
+
+ auto entry::user_accessible() const -> bool { return is_bit_set(2U); }
+
+ auto entry::write_through_caching() const -> bool { return is_bit_set(3U); }
+
+ auto entry::disabled_caching() const -> bool { return is_bit_set(4U); }
+
+ auto entry::is_accessing() const -> bool { return is_bit_set(5U); }
+
+ auto entry::is_diry() const -> bool { return is_bit_set(6U); }
+
+ auto entry::is_huge_page() const -> bool { return is_bit_set(7U); }
+
+ auto entry::is_global() const -> bool { return is_bit_set(8U); }
+
+ auto entry::executing_code_forbidden() const -> bool { return is_bit_set(63U); }
+
+ auto entry::calculate_pointed_to_frame() const -> std::optional<physical_frame>
+ {
+ if (present())
+ {
+ auto physical_address = calculate_physical_address();
+ return physical_frame::containing_address(physical_address);
+ }
+ return std::nullopt;
+ }
+
+ auto entry::calculate_physical_address() const -> std::size_t
+ {
+ constexpr std::size_t start_bit = 12U;
+ constexpr std::size_t end_bit = 51U;
+ size_t value = 0U;
+
+ for (auto i = start_bit; i < end_bit; i++)
+ {
+ value |= (flags[i] ? (1 << (i - start_bit)) : 0);
+ }
+ return value;
+ }
+
+ auto entry::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1U; }
+} // namespace teachos::arch::memory