aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/CMakeLists.txt2
-rw-r--r--arch/x86_64/include/arch/exception_handling/assert.hpp7
-rw-r--r--arch/x86_64/include/arch/exception_handling/panic.hpp13
-rw-r--r--arch/x86_64/include/arch/kernel/halt.hpp9
-rw-r--r--arch/x86_64/include/arch/video/vga/text.hpp5
-rw-r--r--arch/x86_64/src/boot/boot.s13
-rw-r--r--arch/x86_64/src/exception_handling/abort.cpp17
-rw-r--r--arch/x86_64/src/exception_handling/assert.cpp16
-rw-r--r--arch/x86_64/src/exception_handling/panic.cpp23
-rw-r--r--arch/x86_64/src/kernel/main.cpp3
-rw-r--r--arch/x86_64/src/video/vga/text.cpp22
-rw-r--r--src/kernel/main.cpp8
12 files changed, 119 insertions, 19 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 603393c..3f67d71 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -51,7 +51,9 @@ target_sources("_memory" PRIVATE
#]============================================================================]
target_sources("_exception" PRIVATE
+ "src/exception_handling/abort.cpp"
"src/exception_handling/assert.cpp"
+ "src/exception_handling/panic.cpp"
)
#[============================================================================[
diff --git a/arch/x86_64/include/arch/exception_handling/assert.hpp b/arch/x86_64/include/arch/exception_handling/assert.hpp
index eba43ac..f355a61 100644
--- a/arch/x86_64/include/arch/exception_handling/assert.hpp
+++ b/arch/x86_64/include/arch/exception_handling/assert.hpp
@@ -1,3 +1,6 @@
+#ifndef TEACHOS_ARCH_X86_64_EXCEPTION_HANDLING_ASSERT_HPP
+#define TEACHOS_ARCH_X86_64_EXCEPTION_HANDLING_ASSERT_HPP
+
namespace teachos::arch::exception_handling
{
/**
@@ -8,4 +11,6 @@ namespace teachos::arch::exception_handling
* @param message
*/
auto assert(bool condition, char const * message) -> void;
-} // namespace teachos::arch::exception_handling \ No newline at end of file
+} // namespace teachos::arch::exception_handling
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/include/arch/exception_handling/panic.hpp b/arch/x86_64/include/arch/exception_handling/panic.hpp
new file mode 100644
index 0000000..9566159
--- /dev/null
+++ b/arch/x86_64/include/arch/exception_handling/panic.hpp
@@ -0,0 +1,13 @@
+#ifndef TEACHOS_ARCH_X86_64_EXCEPTION_HANDLING_PANIC_HPP
+#define TEACHOS_ARCH_X86_64_EXCEPTION_HANDLING_PANIC_HPP
+
+namespace teachos::arch::exception_handling
+{
+ /**
+ * @brief Print a kernel panic message and then halt the system.
+ */
+ [[noreturn]] auto panic(char const * reason) -> void;
+ [[noreturn]] auto panic(char const * prefix, char const * reason) -> void;
+} // namespace teachos::arch::exception_handling
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/include/arch/kernel/halt.hpp b/arch/x86_64/include/arch/kernel/halt.hpp
new file mode 100644
index 0000000..6c58938
--- /dev/null
+++ b/arch/x86_64/include/arch/kernel/halt.hpp
@@ -0,0 +1,9 @@
+#ifndef TEACHOS_ARCH_X86_64_KERNEL_HALT_HPP
+#define TEACHOS_ARCH_X86_64_KERNEL_HALT_HPP
+
+namespace teachos::arch::kernel
+{
+ extern "C" [[noreturn]] auto halt() -> void;
+}
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/include/arch/video/vga/text.hpp b/arch/x86_64/include/arch/video/vga/text.hpp
index cfafce0..690f4aa 100644
--- a/arch/x86_64/include/arch/video/vga/text.hpp
+++ b/arch/x86_64/include/arch/video/vga/text.hpp
@@ -100,6 +100,11 @@ namespace teachos::arch::video::vga::text
auto cursor(bool enabled) -> void;
/**
+ * @brief Move the cursor to a new line, scrolling the buffer if necessary.
+ */
+ auto newline() -> void;
+
+ /**
* @brief Write a string of code points to the VGA text buffer.
*
* @note This function also updates the text mode buffer pointer.
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 2aa30c6..710d4ce 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -82,6 +82,7 @@ global_descriptor_table_pointer:
* We are going to print some messages in case we panic during boot, so we are
* going to store them here as well
*/
+.global message_prefix_panic
message_prefix_panic:
.string "TeachOS Panic: "
message_not_loaded_by_multiboot2:
@@ -109,6 +110,12 @@ vga_buffer_pointer: .long 0xb8000
.align 16
.code32
+.global halt
+halt:
+1:
+ hlt
+ jmp 1b
+
/**
* Print a given panic message and then halt the machine.
*
@@ -129,7 +136,7 @@ _panic:
call _print
add $8, %esp
- hlt
+ call halt
/**
* Print a message via the VGA buffer.
@@ -189,7 +196,7 @@ _start:
lgdt (global_descriptor_table_pointer)
jmp $global_descriptor_table_code,$_transition_to_long_mode
- hlt
+ call halt
/**
* Assert that the CPU supports going into long mode.
@@ -354,4 +361,4 @@ _transition_to_long_mode:
call _init
call kernel_main
- hlt
+ call halt
diff --git a/arch/x86_64/src/exception_handling/abort.cpp b/arch/x86_64/src/exception_handling/abort.cpp
new file mode 100644
index 0000000..dc40008
--- /dev/null
+++ b/arch/x86_64/src/exception_handling/abort.cpp
@@ -0,0 +1,17 @@
+#include "arch/exception_handling/panic.hpp"
+
+#include <cstdlib>
+
+namespace teachos::arch::exception_handling
+{
+
+ /**
+ * @brief Override for the newlib abort function.
+ *
+ * newlib defines @p ::abort as a weak symbol, thus allowing implementations to override it by simply providing a
+ * matching implementation. Since the default implemenatation calls a number of functions the kernel does not
+ * currently implement, @p ::abort gets overridden to simply panic.
+ */
+ extern "C" auto abort() -> void { panic("Terminate was called, possibly due to an unhandled exception"); }
+
+} // namespace teachos::arch::exception_handling \ No newline at end of file
diff --git a/arch/x86_64/src/exception_handling/assert.cpp b/arch/x86_64/src/exception_handling/assert.cpp
index b55da49..86696f8 100644
--- a/arch/x86_64/src/exception_handling/assert.cpp
+++ b/arch/x86_64/src/exception_handling/assert.cpp
@@ -1,4 +1,6 @@
-#include "arch/video/vga/text.hpp"
+#include "arch/exception_handling/assert.hpp"
+
+#include "arch/exception_handling/panic.hpp"
namespace teachos::arch::exception_handling
{
@@ -9,16 +11,6 @@ namespace teachos::arch::exception_handling
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));
- }
+ panic("Assertion Violation: ", message);
}
} // namespace teachos::arch::exception_handling \ No newline at end of file
diff --git a/arch/x86_64/src/exception_handling/panic.cpp b/arch/x86_64/src/exception_handling/panic.cpp
new file mode 100644
index 0000000..56edfd5
--- /dev/null
+++ b/arch/x86_64/src/exception_handling/panic.cpp
@@ -0,0 +1,23 @@
+#include "arch/exception_handling/panic.hpp"
+
+#include "arch/kernel/halt.hpp"
+#include "arch/video/vga/text.hpp"
+
+namespace teachos::arch::exception_handling
+{
+
+ extern "C" char const message_prefix_panic[];
+
+ auto panic(char const * reason) -> void { panic(message_prefix_panic, reason); }
+
+ auto panic(char const * prefix, char const * reason) -> void
+ {
+ using video::vga::text::common_attributes::white_on_red;
+
+ video::vga::text::newline();
+ video::vga::text::write(prefix, white_on_red);
+ video::vga::text::write(reason, white_on_red);
+
+ kernel::halt();
+ };
+} // 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 12498d0..babe251 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -165,7 +165,6 @@ namespace teachos::arch::kernel
auto allocator = arch::memory::area_frame_allocator(kernel_start, kernel_end, multiboot_start, multiboot_end,
memory_areas, area_count);
- // WATCH OUT: using optional::value() crashes the build... I think its because of missing exception handling
auto last_allocated = allocator.allocate_frame();
auto allocated = last_allocated;
do
@@ -174,6 +173,6 @@ namespace teachos::arch::kernel
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);
+ video::vga::text::write_number(allocated.value().frame_number, video::vga::text::common_attributes::green_on_black);
}
} // namespace teachos::arch::kernel
diff --git a/arch/x86_64/src/video/vga/text.cpp b/arch/x86_64/src/video/vga/text.cpp
index a613c3b..c14de16 100644
--- a/arch/x86_64/src/video/vga/text.cpp
+++ b/arch/x86_64/src/video/vga/text.cpp
@@ -13,6 +13,8 @@ namespace teachos::arch::video::vga::text
namespace
{
auto constexpr default_text_buffer_address = 0xb8000;
+ auto constexpr default_text_buffer_width = 80;
+ auto constexpr default_text_buffer_height = 25;
extern "C" std::pair<char, attribute> * vga_buffer_pointer;
auto constinit text_buffer = teachos::memory::asm_pointer{vga_buffer_pointer};
@@ -32,6 +34,26 @@ namespace teachos::arch::video::vga::text
crtc::data_port::write(vga::crtc::data_port::read() | cursor_disable_byte);
}
+ auto newline() -> void
+ {
+ auto base = reinterpret_cast<decltype(text_buffer)::pointer>(default_text_buffer_address);
+ auto & raw_buffer = *text_buffer;
+ auto current_line = (raw_buffer - base) / default_text_buffer_width;
+ auto next_line = current_line + 1;
+
+ if (next_line >= default_text_buffer_height)
+ {
+ auto begin = base + default_text_buffer_width;
+ auto end = base + default_text_buffer_width * default_text_buffer_height;
+ std::ranges::move(begin, end, base);
+ raw_buffer = base + current_line * default_text_buffer_width;
+ }
+ else
+ {
+ raw_buffer = base + next_line * default_text_buffer_width;
+ }
+ }
+
auto write_char(char code_point, attribute attribute) -> void
{
auto & p = *text_buffer;
diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp
index 4799b29..36c6d92 100644
--- a/src/kernel/main.cpp
+++ b/src/kernel/main.cpp
@@ -1,3 +1,9 @@
#include "arch/kernel/main.hpp"
-extern "C" auto kernel_main() -> void { teachos::arch::kernel::main(); }
+#include "arch/exception_handling/panic.hpp"
+
+extern "C" auto kernel_main() -> void
+{
+ teachos::arch::kernel::main();
+ teachos::arch::exception_handling::panic("Architecture specific main returned!");
+}