aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt10
-rw-r--r--arch/x86_64/CMakeLists.txt8
-rw-r--r--arch/x86_64/include/arch/exception_handling/assert.hpp11
-rw-r--r--arch/x86_64/include/arch/memory/frame_allocator.hpp7
-rw-r--r--arch/x86_64/include/arch/memory/paging.hpp99
-rw-r--r--arch/x86_64/src/exception_handling/assert.cpp24
-rw-r--r--arch/x86_64/src/kernel/main.cpp42
-rw-r--r--arch/x86_64/src/memory/frame_allocator.cpp12
-rw-r--r--arch/x86_64/src/memory/paging.cpp36
9 files changed, 113 insertions, 136 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f5cc7ea..3586669 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -101,13 +101,20 @@ add_library("_video" OBJECT)
add_library("teachos::video" ALIAS "_video")
#[============================================================================[
-# The memory Library
+# THE Memory Library
#]============================================================================]
add_library("_memory" OBJECT)
add_library("teachos::memory" ALIAS "_memory")
#[============================================================================[
+# The Exception handling Library
+#]============================================================================]
+
+add_library("_exception" OBJECT)
+add_library("teachos::exception" ALIAS "_exception")
+
+#[============================================================================[
# The Kernel
#]============================================================================]
@@ -120,6 +127,7 @@ target_link_libraries("_kernel" PRIVATE
"teachos::boot"
"teachos::video"
"teachos::memory"
+ "teachos::exception"
)
#[============================================================================[
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 25f8634..603393c 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -47,6 +47,14 @@ target_sources("_memory" PRIVATE
)
#[============================================================================[
+# The Exception handling Library
+#]============================================================================]
+
+target_sources("_exception" PRIVATE
+ "src/exception_handling/assert.cpp"
+)
+
+#[============================================================================[
# The Bootable ISO Image
#]============================================================================]
diff --git a/arch/x86_64/include/arch/exception_handling/assert.hpp b/arch/x86_64/include/arch/exception_handling/assert.hpp
new file mode 100644
index 0000000..eba43ac
--- /dev/null
+++ b/arch/x86_64/include/arch/exception_handling/assert.hpp
@@ -0,0 +1,11 @@
+namespace teachos::arch::exception_handling
+{
+ /**
+ * @brief assert a condition to be true, if not do not continue
+ * execution of the code and print message to screen
+ *
+ * @param condition
+ * @param message
+ */
+ auto assert(bool condition, char const * message) -> void;
+} // namespace teachos::arch::exception_handling \ No newline at end of file
diff --git a/arch/x86_64/include/arch/memory/frame_allocator.hpp b/arch/x86_64/include/arch/memory/frame_allocator.hpp
index ab93231..69c108c 100644
--- a/arch/x86_64/include/arch/memory/frame_allocator.hpp
+++ b/arch/x86_64/include/arch/memory/frame_allocator.hpp
@@ -32,6 +32,13 @@ namespace teachos::arch::memory
static auto containing_address(std::size_t address) -> physical_frame;
/**
+ * @brief TODO
+ *
+ * @return uint64_t
+ */
+ auto start_address() const -> uint64_t;
+
+ /**
* @brief Defaulted equals operator.
*/
constexpr auto operator==(const physical_frame & other) const -> bool = default;
diff --git a/arch/x86_64/include/arch/memory/paging.hpp b/arch/x86_64/include/arch/memory/paging.hpp
index a5408e1..1870c28 100644
--- a/arch/x86_64/include/arch/memory/paging.hpp
+++ b/arch/x86_64/include/arch/memory/paging.hpp
@@ -43,72 +43,6 @@ namespace teachos::arch::memory
auto set_unused() -> void;
/**
- * @brief Whether the current page is in memory and therefore present or not. Read from bit index 0.
- *
- * @return Current page is in memory.
- */
- auto present() const -> bool;
-
- /**
- * @brief Whether it is possible to write to the current page or not. Read from bit index 1.
- *
- * @return Current page can be written too.
- */
- auto writable() const -> bool;
-
- /**
- * @brief Whether the current page can be accessed in user mode, or only in kernel mode code. Read from bit index 2.
- *
- * @return Current page can be accessed in user mode.
- */
- auto user_accessible() const -> bool;
-
- /**
- * @brief Whether any write to the current page go directly to memory instead of the cache or not. Read from bit
- * index 3.
- *
- * @return Writes to the current page go directly to memory.
- */
- auto write_through_caching() const -> bool;
-
- /**
- * @brief Whether the current page uses caching or not. Read from bit index 4.
- *
- * @return Current page does not use caching.
- */
- auto disabled_caching() const -> bool;
-
- /**
- * @brief Whether the current page is currently being used or not. Read from bit index 5.
- *
- * @return Current page is currently being used.
- */
- auto is_accessing() const -> bool;
-
- /**
- * @brief Whether the current page has been writen too or not. Read from bit index 6.
- *
- * @return Current page has been writen too.
- */
- auto is_diry() const -> bool;
-
- /**
- * @brief Whether the current page is huge or not (2 MiB page size in P2 page table and 1 GiB in P3 page table,
- * instead of 4 KiB). Has to be false for P1 and P4 page tables. Read from bit index 7.
- *
- * @return Current page is huge
- */
- auto is_huge_page() const -> bool;
-
- /**
- * @brief Whether the current page is not flushed from caches on address space switches or not (PGE bit of CR4
- * register has to be set). Read from bit index 8.
- *
- * @return Current page is not flushed from caches on address space switches.
- */
- auto is_global() const -> bool;
-
- /**
* @brief Whether the current page is forbidden from executing code or not (NXE bit in the EFER register has to be
* set). Read from bit index 63.
*
@@ -124,6 +58,22 @@ namespace teachos::arch::memory
*/
auto calculate_pointed_to_frame() const -> std::optional<physical_frame>;
+ /**
+ * @brief TODO
+ *
+ * @param frame
+ */
+ auto set(physical_frame frame) -> void;
+
+ /**
+ * @brief TODO
+ *
+ * @param b
+ * @return true
+ * @return false
+ */
+ auto contains_flags(std::bitset<64U> b) const -> bool;
+
private:
/**
* @brief Extracts the physical address from the underlying bitset read from bit index 12 - 51. Is a 52 bit page
@@ -134,17 +84,18 @@ namespace teachos::arch::memory
*/
auto calculate_physical_address() const -> std::size_t;
- /**
- * @brief Checks the underlying std::bitset if the bit at the specific index is set, meaning a value of 1
- *
- * @param index Specific index we want to check at
- * @return Bit value 1 is set and will return true
- */
- auto is_bit_set(uint8_t index) const -> bool;
-
std::bitset<64U> flags; ///< Underlying bitset used to read the flags from. Bits 9 - 11 and 52 - 62 can be freely
///< used for additional flagsby the operating system.
};
+
+ /**
+ * @brief TODO
+ *
+ */
+ struct page_table
+ {
+ entry entries[PAGE_TABLE_ENTRY_COUNT];
+ };
} // namespace teachos::arch::memory
#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_HPP
diff --git a/arch/x86_64/src/exception_handling/assert.cpp b/arch/x86_64/src/exception_handling/assert.cpp
new file mode 100644
index 0000000..b55da49
--- /dev/null
+++ b/arch/x86_64/src/exception_handling/assert.cpp
@@ -0,0 +1,24 @@
+#include "arch/video/vga/text.hpp"
+
+namespace teachos::arch::exception_handling
+{
+ auto assert(bool condition, char const * message) -> void
+ {
+ if (condition)
+ {
+ return;
+ }
+
+ video::vga::text::write("Assert failed: ", video::vga::text::common_attributes::green_on_black);
+ video::vga::text::write(message, video::vga::text::common_attributes::green_on_black);
+ for (;;)
+ {
+ // Trick the compiler into thinking the variable is changes at run time,
+ // to prevent the while loop being optimized away
+ // See
+ // https://stackoverflow.com/questions/9495856/how-to-prevent-g-from-optimizing-out-a-loop-controlled-by-a-variable-that-can
+ // for more information.
+ asm volatile("" : "+g"(condition));
+ }
+ }
+} // namespace teachos::arch::exception_handling \ No newline at end of file
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index 7e4a336..c8981a8 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -1,6 +1,7 @@
#include "arch/kernel/main.hpp"
#include "arch/boot/pointers.hpp"
+#include "arch/exception_handling/assert.hpp"
#include "arch/memory/frame_allocator.hpp"
#include "arch/memory/multiboot.hpp"
#include "arch/video/vga/text.hpp"
@@ -9,31 +10,12 @@
namespace teachos::arch::kernel
{
- auto assert(bool condition) -> void
- {
- if (condition)
- {
- return;
- }
-
- video::vga::text::write("Assert failed", video::vga::text::common_attributes::green_on_black);
- for (;;)
- {
- // Trick the compiler into thinking the variable is changes at run time,
- // to prevent the while loop being optimized away
- // See
- // https://stackoverflow.com/questions/9495856/how-to-prevent-g-from-optimizing-out-a-loop-controlled-by-a-variable-that-can
- // for more information.
- asm volatile("" : "+g"(condition));
- }
- }
-
auto process_memory_map(arch::memory::memory_map * mminfo, arch::memory::memory_area *& memory_areas,
uint8_t & area_count) -> void
{
auto expected_entry_size = mminfo->entry_size;
constexpr auto actual_entry_size = sizeof(arch::memory::memory_area);
- assert(expected_entry_size == actual_entry_size);
+ arch::exception_handling::assert(expected_entry_size == actual_entry_size, "Unexpected memoryarea entry size");
auto total_size = mminfo->tag.size;
auto total_entries_size = total_size - sizeof(arch::memory::memory_map) + actual_entry_size;
@@ -48,17 +30,18 @@ namespace teachos::arch::kernel
{
auto expected_entry_size = symbol->entry_size;
constexpr auto actual_entry_size = sizeof(arch::memory::elf_section_header);
- assert(expected_entry_size == actual_entry_size);
+ arch::exception_handling::assert(expected_entry_size == actual_entry_size,
+ "Unexpected elf_section_header entry size");
auto expected_total_size = symbol->tag.size;
auto actual_total_entry_size = actual_entry_size * symbol->number_of_sections;
constexpr auto actual_total_section_size = sizeof(arch::memory::elf_symbols_section) - sizeof(uint32_t);
auto actual_total_size = actual_total_entry_size + actual_total_section_size;
- assert(expected_total_size == actual_total_size);
+ arch::exception_handling::assert(expected_total_size == actual_total_size, "Unexpected elf_symbols total size");
auto begin = reinterpret_cast<arch::memory::elf_section_header *>(&symbol->end);
auto end = begin + symbol->number_of_sections;
- assert(begin->is_null());
+ arch::exception_handling::assert(begin->is_null(), "Missing elf_section_header begin");
std::size_t symbol_table_section_count = 0U;
std::size_t dynamic_section_count = 0U;
@@ -115,8 +98,8 @@ namespace teachos::arch::kernel
}
}
- assert(symbol_table_section_count == 1U);
- assert(dynamic_section_count <= 1U);
+ arch::exception_handling::assert(symbol_table_section_count == 1U, "Unexpected symbol_table_count value");
+ arch::exception_handling::assert(dynamic_section_count <= 1U, "Unexpected dynamic_section_count value");
}
template<typename T>
@@ -173,15 +156,6 @@ namespace teachos::arch::kernel
}
}
- // Kernel start 0x100000
- // Kernel end 0x23E943
- // Kernel Size 0x13E943 -> 1'304'899
- // Multiboot start 0x241AA0
- // Multiboot end 0x242280
- // Multiboot Size 0x7E0 -> 2'016
- // Memory area start 0x241b10
- //
- // Address of Frame: 0x203F00
auto allocator = arch::memory::area_frame_allocator(kernel_start, kernel_end, multiboot_start, multiboot_end,
memory_areas, area_count);
diff --git a/arch/x86_64/src/memory/frame_allocator.cpp b/arch/x86_64/src/memory/frame_allocator.cpp
index 3733cc3..01dcc88 100644
--- a/arch/x86_64/src/memory/frame_allocator.cpp
+++ b/arch/x86_64/src/memory/frame_allocator.cpp
@@ -1,7 +1,11 @@
#include "arch/memory/frame_allocator.hpp"
+#include "arch/exception_handling/assert.hpp"
+
namespace teachos::arch::memory
{
+ uint64_t PAGE_SIZE;
+
physical_frame::physical_frame(std::size_t frame_number)
: frame_number(frame_number)
{
@@ -13,6 +17,8 @@ namespace teachos::arch::memory
return physical_frame{address / PAGE_FRAME_SIZE};
}
+ auto physical_frame::start_address() const -> uint64_t { return frame_number * PAGE_SIZE; }
+
memory_area_iterator::memory_area_iterator(memory_area * p)
: ptr(p)
{
@@ -103,10 +109,8 @@ namespace teachos::arch::memory
auto area_frame_allocator::deallocate_frame(physical_frame physical_frame) -> void
{
- // TODO: Fix, simply done because compiler will complain if physical_frame is unused and not compile
- if (physical_frame.frame_number == 3)
- {
- }
+ arch::exception_handling::assert(false && physical_frame.frame_number == 0,
+ "[deallocate_frame] Not implemented Exception");
}
auto area_frame_allocator::begin() -> memory_area_iterator { return area_begin; }
diff --git a/arch/x86_64/src/memory/paging.cpp b/arch/x86_64/src/memory/paging.cpp
index 555357c..90c4199 100644
--- a/arch/x86_64/src/memory/paging.cpp
+++ b/arch/x86_64/src/memory/paging.cpp
@@ -1,34 +1,16 @@
#include "arch/memory/paging.hpp"
+#include "arch/exception_handling/assert.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())
+ if (contains_flags(1))
{
auto physical_address = calculate_physical_address();
return physical_frame::containing_address(physical_address);
@@ -39,7 +21,7 @@ namespace teachos::arch::memory
auto entry::calculate_physical_address() const -> std::size_t
{
constexpr std::size_t start_bit = 12U;
- constexpr std::size_t end_bit = 51U;
+ constexpr std::size_t end_bit = 52U;
size_t value = 0U;
for (auto i = start_bit; i < end_bit; i++)
@@ -49,5 +31,13 @@ namespace teachos::arch::memory
return value;
}
- auto entry::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1U; }
+ auto entry::set(physical_frame frame) -> void
+ {
+ arch::exception_handling::assert((frame.start_address() & ~0x000fffff'fffff000) == 0,
+ "Start address is not aligned with Page");
+ flags = std::bitset<64U>(frame.start_address()) | flags;
+ }
+
+ auto entry::contains_flags(std::bitset<64U> b) const -> bool { return (flags & b) == b; }
+
} // namespace teachos::arch::memory