aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/include/arch/memory/paging/active_page_table.hpp2
-rw-r--r--arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp16
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_entry.hpp6
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_table.hpp3
-rw-r--r--arch/x86_64/include/arch/user/main.hpp5
-rw-r--r--arch/x86_64/src/memory/main.cpp3
-rw-r--r--arch/x86_64/src/memory/paging/inactive_page_table.cpp2
-rw-r--r--arch/x86_64/src/memory/paging/page_entry.cpp10
-rw-r--r--arch/x86_64/src/memory/paging/temporary_page.cpp10
-rw-r--r--arch/x86_64/src/user/main.cpp12
10 files changed, 38 insertions, 31 deletions
diff --git a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp
index 9e91a8c..a4a5b64 100644
--- a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp
+++ b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp
@@ -89,7 +89,7 @@ namespace teachos::arch::memory::paging
arch::exception_handling::assert(!level1_entry.contains_flags(entry::HUGE_PAGE),
"[Page Mapper] Unable to map huge pages");
arch::exception_handling::assert(level1_entry.is_unused(), "[Page Mapper] Page table entry is already used");
- level1_entry.set_entry(frame, flags.to_ulong() | entry::PRESENT);
+ level1_entry.set_entry(frame, flags.to_ulong() | entry::PRESENT | entry::USER_ACCESSIBLE);
}
/**
diff --git a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
index 8d36fde..09e9bf4 100644
--- a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
+++ b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
@@ -81,11 +81,12 @@ namespace teachos::arch::memory::paging
kernel::cpu::read_control_register(kernel::cpu::control_register::CR3));
auto page_table_level4 = temporary_page.map_table_frame(backup, active_table);
- active_table[511].set_entry(inactive_table.page_table_level_4_frame, entry::PRESENT | entry::WRITABLE);
+ active_table[511].set_entry(inactive_table.page_table_level_4_frame,
+ entry::PRESENT | entry::WRITABLE | entry::USER_ACCESSIBLE);
kernel::cpu::tlb_flush_all();
map_elf_kernel_sections(active_table);
- page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE);
+ page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE | entry::USER_ACCESSIBLE);
kernel::cpu::tlb_flush_all();
temporary_page.unmap_page(active_table);
}
@@ -136,7 +137,14 @@ namespace teachos::arch::memory::paging
allocator::frame_container::iterator const begin{start_frame};
allocator::frame_container::iterator const end{end_frame};
allocator::frame_container const frames{begin, end};
- entry const entry{section.flags};
+ entry entry{section.flags};
+
+ // TODO: Only set this if we are in the .user_text section.
+ // address: 0000000000216000, offset: 013000, size: varies depending on code not a a good idea
+ // Alternatively index Nr. 8 could be used to detect section, can also change if we add more section
+ entry.set_user_accesible();
+
+ // TODO: Entering User Mode still works, but then attempting to execute an instruction immedatiately fails.
for (auto const & frame : frames)
{
@@ -146,7 +154,7 @@ namespace teachos::arch::memory::paging
auto const vga_buffer_frame =
allocator::physical_frame::containing_address(video::vga::text::DEFAULT_VGA_TEXT_BUFFER_ADDRESS);
- active_table.identity_map(allocator, vga_buffer_frame, entry::WRITABLE);
+ active_table.identity_map(allocator, vga_buffer_frame, entry::WRITABLE | entry::USER_ACCESSIBLE);
}
T & allocator;
diff --git a/arch/x86_64/include/arch/memory/paging/page_entry.hpp b/arch/x86_64/include/arch/memory/paging/page_entry.hpp
index ef4fe61..5cba1bc 100644
--- a/arch/x86_64/include/arch/memory/paging/page_entry.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_entry.hpp
@@ -72,6 +72,12 @@ namespace teachos::arch::memory::paging
auto set_unused() -> void;
/**
+ * @brief Marks the page as accessible in User mode, meaning the underlying std::bitset has the 2nd bit aditonally
+ * set.
+ */
+ auto set_user_accesible() -> void;
+
+ /**
* @brief Calculates the physical frame this entry is pointing too, can be null if the page is not present in
* memory.
*
diff --git a/arch/x86_64/include/arch/memory/paging/page_table.hpp b/arch/x86_64/include/arch/memory/paging/page_table.hpp
index 60a0a2f..db7ba6c 100644
--- a/arch/x86_64/include/arch/memory/paging/page_table.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_table.hpp
@@ -94,7 +94,8 @@ namespace teachos::arch::memory::paging
{
auto const allocated_frame = allocator.allocate_frame();
exception_handling::assert(allocated_frame.has_value(), "[Page mapper] Unable to allocate frame");
- this->operator[](table_index).set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE);
+ this->operator[](table_index)
+ .set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE | entry::USER_ACCESSIBLE);
// There should now be an entry at the previously not existent index, therefore we can simply access it again.
next_handle = next_table(table_index);
exception_handling::assert(next_handle.has_value(), "[Page mapper] Unable to create new entry into page table");
diff --git a/arch/x86_64/include/arch/user/main.hpp b/arch/x86_64/include/arch/user/main.hpp
index 4f1d005..ba30864 100644
--- a/arch/x86_64/include/arch/user/main.hpp
+++ b/arch/x86_64/include/arch/user/main.hpp
@@ -3,6 +3,11 @@
namespace teachos::arch::user
{
+ /**
+ * @brief User Main method. If this method finishes there is no code left to run and the whole OS will shut down.
+ * Additionally this main method is executed at Ring 3 and accessing CPU Registers or Kernel level functionality can
+ * only be done over syscalls and not directly anymore.
+ */
auto main() -> void;
} // namespace teachos::arch::user
diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp
index bd094e0..4cccabb 100644
--- a/arch/x86_64/src/memory/main.cpp
+++ b/arch/x86_64/src/memory/main.cpp
@@ -31,7 +31,8 @@ namespace teachos::arch::memory
for (auto const & page : pages)
{
- active_table.map_page_to_next_free_frame(allocator, page, paging::entry::WRITABLE);
+ active_table.map_page_to_next_free_frame(allocator, page,
+ paging::entry::WRITABLE | paging::entry::USER_ACCESSIBLE);
}
}
} // namespace
diff --git a/arch/x86_64/src/memory/paging/inactive_page_table.cpp b/arch/x86_64/src/memory/paging/inactive_page_table.cpp
index 4e0610e..780f12c 100644
--- a/arch/x86_64/src/memory/paging/inactive_page_table.cpp
+++ b/arch/x86_64/src/memory/paging/inactive_page_table.cpp
@@ -14,7 +14,7 @@ namespace teachos::arch::memory::paging
{
auto table = temporary_page.map_table_frame(page_table_level_4_frame, active_page_table);
table.zero_entries();
- table[511].set_entry(page_table_level_4_frame, entry::PRESENT | entry::WRITABLE);
+ table[511].set_entry(page_table_level_4_frame, entry::PRESENT | entry::WRITABLE | entry::USER_ACCESSIBLE);
temporary_page.unmap_page(active_page_table);
}
} // namespace teachos::arch::memory::paging
diff --git a/arch/x86_64/src/memory/paging/page_entry.cpp b/arch/x86_64/src/memory/paging/page_entry.cpp
index 3a0f03f..c76c673 100644
--- a/arch/x86_64/src/memory/paging/page_entry.cpp
+++ b/arch/x86_64/src/memory/paging/page_entry.cpp
@@ -10,7 +10,7 @@ namespace teachos::arch::memory::paging
} // namespace
entry::entry(uint64_t flags)
- : flags(flags | entry::USER_ACCESSIBLE) // TODO: Temporarily make all entries user accessible
+ : flags(flags)
{
// Nothing to do.
}
@@ -31,15 +31,14 @@ namespace teachos::arch::memory::paging
{
flags |= entry::EXECUTING_CODE_FORBIDDEN;
}
-
- // TODO: Temporarily make all entries user accessible
- flags |= entry::USER_ACCESSIBLE;
}
auto entry::is_unused() const -> bool { return flags == 0U; }
auto entry::set_unused() -> void { flags = 0U; }
+ auto entry::set_user_accesible() -> void { flags |= entry::USER_ACCESSIBLE; }
+
auto entry::calculate_pointed_to_frame() const -> std::optional<allocator::physical_frame>
{
if (contains_flags(PRESENT))
@@ -57,8 +56,7 @@ namespace teachos::arch::memory::paging
exception_handling::assert((frame.start_address() & ~PHYSICAL_ADDRESS_MASK) == 0,
"[Paging Entry] Start address is not aligned with page");
- // TODO: Temporarily make all entries user accessible
- flags = frame.start_address() | additional_flags.to_ulong() | entry::USER_ACCESSIBLE;
+ flags = frame.start_address() | additional_flags.to_ulong();
}
auto entry::get_flags() const -> std::bitset<64U> { return flags.to_ulong() & ~PHYSICAL_ADDRESS_MASK; }
diff --git a/arch/x86_64/src/memory/paging/temporary_page.cpp b/arch/x86_64/src/memory/paging/temporary_page.cpp
index 152241d..9946f36 100644
--- a/arch/x86_64/src/memory/paging/temporary_page.cpp
+++ b/arch/x86_64/src/memory/paging/temporary_page.cpp
@@ -4,21 +4,21 @@
namespace teachos::arch::memory::paging
{
- auto temporary_page::map_table_frame(allocator::physical_frame frame,
- active_page_table & active_table) -> page_table_handle
+ auto temporary_page::map_table_frame(allocator::physical_frame frame, active_page_table & active_table)
+ -> page_table_handle
{
page_table_handle handle{reinterpret_cast<page_table *>(map_to_frame(frame, active_table)),
page_table_handle::LEVEL1};
return handle;
}
- auto temporary_page::map_to_frame(allocator::physical_frame frame,
- active_page_table & active_table) -> virtual_address
+ auto temporary_page::map_to_frame(allocator::physical_frame frame, active_page_table & active_table)
+ -> virtual_address
{
exception_handling::assert(!active_table.translate_page(page).has_value(),
"[Temporary page] Page is already mapped");
- active_table.map_page_to_frame(allocator, page, frame, entry::WRITABLE);
+ active_table.map_page_to_frame(allocator, page, frame, entry::WRITABLE | entry::USER_ACCESSIBLE);
return page.start_address();
}
diff --git a/arch/x86_64/src/user/main.cpp b/arch/x86_64/src/user/main.cpp
index 1d56d2e..3ddcb32 100644
--- a/arch/x86_64/src/user/main.cpp
+++ b/arch/x86_64/src/user/main.cpp
@@ -10,18 +10,6 @@ namespace teachos::arch::user
[[gnu::section(".user_text")]]
auto main() -> void
{
- // TODO: Remove or replace this wall of text
- // RFLAGS is saved into R11, RIP of the next instruction into RCX
- // Required for SYSRETURN to know where to return too.
- // Additional state needs to be saved by calling convention:
-
- // Syscall Number: RAX, Return Value: RAX (0 indicating no error, and -1 indicating an error, use as a boolean)
- // Argument in this order (max 6. no argument on stack): RDI, RSI, RDX, R10, R8, R9
- // Not used registers: RBX, RSP, R12, R13, R14
-
- // Actual Source: https://man7.org/linux/man-pages/man2/syscall.2.html More cleare documentation:
- // https://sys.readthedocs.io/en/latest/doc/05_calling_system_calls.html
-
char constexpr syscall_message[] = "Successfully entered user mode and wrote to VGA buffer via syscall!";
auto const error = context_switching::syscall::syscall(context_switching::syscall::type::WRITE,
{reinterpret_cast<uint64_t>(&syscall_message)});