aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2023-10-07 17:15:31 +0200
committerFelix Morgner <felix.morgner@ost.ch>2023-10-07 17:15:31 +0200
commitff81b5438f280a59ca1825bfdf120d8f256bd154 (patch)
tree0a63ea3eb9fc28ca655c3ca3d1c70000d514aecd
parent7e785ff5a7a2e9c98fd1679e74a728f4babf722a (diff)
downloadteachos-ff81b5438f280a59ca1825bfdf120d8f256bd154.tar.xz
teachos-ff81b5438f280a59ca1825bfdf120d8f256bd154.zip
x86_64: implement very simple VGA text output
-rw-r--r--.vscode/tasks.json18
-rw-r--r--source/.clang-format2
-rw-r--r--source/boot/CMakeLists.txt4
-rw-r--r--source/boot/arch/x86_64/CMakeLists.txt4
-rw-r--r--source/boot/arch/x86_64/include/boot/pointers.hpp12
-rw-r--r--source/boot/arch/x86_64/src/boot.s2
-rw-r--r--source/boot/include/boot/asm_pointer.hpp43
-rw-r--r--source/cmake/Platforms/x86_64.cmake2
-rw-r--r--source/kernel/arch/x86_64/CMakeLists.txt1
-rw-r--r--source/kernel/arch/x86_64/include/kernel/vga.hpp11
-rw-r--r--source/kernel/arch/x86_64/src/entry.cpp9
-rw-r--r--source/kernel/arch/x86_64/src/vga.cpp30
12 files changed, 129 insertions, 9 deletions
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index db94c63..c280971 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -2,7 +2,7 @@
"version": "2.0.0",
"tasks": [
{
- "label": "Boot in QEMU",
+ "label": "Debug-Boot in QEMU",
"command": "qemu-system-x86_64",
"type": "shell",
"args": [
@@ -18,6 +18,22 @@
},
"group": "none",
"problemMatcher": []
+ },
+ {
+ "label": "Boot in QEMU",
+ "command": "qemu-system-x86_64",
+ "type": "shell",
+ "args": [
+ "-m",
+ "32M",
+ "-cdrom",
+ "${workspaceFolder}/build/Debug/teachos.iso"
+ ],
+ "presentation": {
+ "reveal": "always"
+ },
+ "group": "none",
+ "problemMatcher": []
}
]
} \ No newline at end of file
diff --git a/source/.clang-format b/source/.clang-format
index fbcf7e4..89505b6 100644
--- a/source/.clang-format
+++ b/source/.clang-format
@@ -41,7 +41,7 @@ FixNamespaceComments: 'true'
IncludeBlocks: Regroup
IncludeCategories:
# Local Headers
- - Regex: '"(.*/)+/.+\.hpp"'
+ - Regex: '"(.*/?)+/.+\.hpp"'
Priority: 100
# STL Headers
- Regex: '<[[:alnum:]._]+(?!\.(h|hpp))>'
diff --git a/source/boot/CMakeLists.txt b/source/boot/CMakeLists.txt
index 5591d70..66f1d65 100644
--- a/source/boot/CMakeLists.txt
+++ b/source/boot/CMakeLists.txt
@@ -8,6 +8,10 @@
add_library("_boot" STATIC)
add_library("teachos::boot" ALIAS "_boot")
+target_include_directories("_boot" PUBLIC
+ "include"
+)
+
#[============================================================================[
# Apply the platform dependent settings to the bootstrapping library.
#]============================================================================]
diff --git a/source/boot/arch/x86_64/CMakeLists.txt b/source/boot/arch/x86_64/CMakeLists.txt
index 0fd6539..14b0610 100644
--- a/source/boot/arch/x86_64/CMakeLists.txt
+++ b/source/boot/arch/x86_64/CMakeLists.txt
@@ -4,3 +4,7 @@ target_sources("_boot" PRIVATE
"src/crtn.s"
"src/multiboot.s"
)
+
+target_include_directories("_boot" PUBLIC
+ "include"
+) \ No newline at end of file
diff --git a/source/boot/arch/x86_64/include/boot/pointers.hpp b/source/boot/arch/x86_64/include/boot/pointers.hpp
new file mode 100644
index 0000000..f4f504c
--- /dev/null
+++ b/source/boot/arch/x86_64/include/boot/pointers.hpp
@@ -0,0 +1,12 @@
+#ifndef TEACHOS_ARCH_X86_64_BOOT_POINTERS_HPP
+#define TEACHOS_ARCH_X86_64_BOOT_POINTERS_HPP
+
+#include <cstddef>
+
+namespace teachos::boot
+{
+ extern "C" std::byte const multiboot_information_pointer;
+ extern "C" std::byte * vga_buffer_pointer;
+} // namespace teachos::boot
+
+#endif \ No newline at end of file
diff --git a/source/boot/arch/x86_64/src/boot.s b/source/boot/arch/x86_64/src/boot.s
index 4781773..45f261e 100644
--- a/source/boot/arch/x86_64/src/boot.s
+++ b/source/boot/arch/x86_64/src/boot.s
@@ -103,6 +103,7 @@ mesage_long_mode_not_supported:
/**
* We need a pointer to our current position in the VGA text buffer.
*/
+.global vga_buffer_pointer
vga_buffer_pointer: .long 0xb8000
/**
@@ -369,6 +370,5 @@ _transition_to_long_mode:
call _init
- mov multiboot_information_pointer, %rdi
call kernel_main
hlt
diff --git a/source/boot/include/boot/asm_pointer.hpp b/source/boot/include/boot/asm_pointer.hpp
new file mode 100644
index 0000000..ec7141e
--- /dev/null
+++ b/source/boot/include/boot/asm_pointer.hpp
@@ -0,0 +1,43 @@
+#ifndef TEACHOS_BOOT_ASM_POINTER_HPP
+#define TEACHOS_BOOT_ASM_POINTER_HPP
+
+namespace teachos::boot
+{
+
+ template<typename Type>
+ struct asm_pointer
+ {
+ constexpr asm_pointer(Type & pointer)
+ : m_pointer{&pointer}
+ {
+ }
+
+ auto constexpr operator->() -> Type * { return m_pointer; }
+ auto constexpr operator->() const -> Type const * { return m_pointer; }
+ auto constexpr operator*() -> Type & { return *m_pointer; }
+ auto constexpr operator*() const -> Type const & { return *m_pointer; }
+
+ private:
+ Type * m_pointer;
+ };
+
+ template<typename Type>
+ struct asm_pointer<Type const>
+ {
+ constexpr asm_pointer(Type const & pointer)
+ : m_pointer{&pointer}
+ {
+ }
+
+ auto constexpr operator->() -> Type const * { return m_pointer; }
+ auto constexpr operator->() const -> Type const * { return m_pointer; }
+ auto constexpr operator*() -> Type const & { return *m_pointer; }
+ auto constexpr operator*() const -> Type const & { return *m_pointer; }
+
+ private:
+ Type const * m_pointer;
+ };
+
+} // namespace teachos::boot
+
+#endif \ No newline at end of file
diff --git a/source/cmake/Platforms/x86_64.cmake b/source/cmake/Platforms/x86_64.cmake
index 9e727cf..b681937 100644
--- a/source/cmake/Platforms/x86_64.cmake
+++ b/source/cmake/Platforms/x86_64.cmake
@@ -8,7 +8,7 @@ mark_as_advanced(CRT_BEGIN)
string(REGEX REPLACE "/crtbegin.o" "" CMAKE_SYSROOT "${CRT_BEGIN}")
mark_as_advanced(CMAKE_SYSROOT)
-set(CMAKE_CXX_FLAGS_INIT "-m64 -mno-red-zone -mcmodel=large")
+set(CMAKE_CXX_FLAGS_INIT "-m64 -mno-red-zone -mcmodel=large -fno-exceptions")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostartfiles")
set(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> \
diff --git a/source/kernel/arch/x86_64/CMakeLists.txt b/source/kernel/arch/x86_64/CMakeLists.txt
index 99fafe7..ffce50c 100644
--- a/source/kernel/arch/x86_64/CMakeLists.txt
+++ b/source/kernel/arch/x86_64/CMakeLists.txt
@@ -7,6 +7,7 @@ mark_as_advanced(TEACHOS_KERNEL_LINKER_SCRIPT)
target_sources("kernel" PRIVATE
"src/entry.cpp"
+ "src/vga.cpp"
)
target_include_directories("kernel" PRIVATE
diff --git a/source/kernel/arch/x86_64/include/kernel/vga.hpp b/source/kernel/arch/x86_64/include/kernel/vga.hpp
new file mode 100644
index 0000000..ee5a808
--- /dev/null
+++ b/source/kernel/arch/x86_64/include/kernel/vga.hpp
@@ -0,0 +1,11 @@
+#ifndef TEACHOS_KERNEL_VGA_HPP
+#define TEACHOS_KERNEL_VGA_HPP
+
+#include <string_view>
+
+namespace teachos::kernel::vga
+{
+ auto write(std::string_view text, std::byte color) -> void;
+}
+
+#endif \ No newline at end of file
diff --git a/source/kernel/arch/x86_64/src/entry.cpp b/source/kernel/arch/x86_64/src/entry.cpp
index 2d4e7fb..fd9d9d0 100644
--- a/source/kernel/arch/x86_64/src/entry.cpp
+++ b/source/kernel/arch/x86_64/src/entry.cpp
@@ -1,10 +1,9 @@
-namespace teachos
+#include "kernel/vga.hpp"
+
+namespace teachos::kernel
{
extern "C" auto kernel_main() -> void
{
- while (true)
- {
- asm volatile("nop");
- }
+ vga::write("TeachOS is starting up...", static_cast<std::byte>(0x4f));
}
} // namespace teachos
diff --git a/source/kernel/arch/x86_64/src/vga.cpp b/source/kernel/arch/x86_64/src/vga.cpp
new file mode 100644
index 0000000..d25eaa5
--- /dev/null
+++ b/source/kernel/arch/x86_64/src/vga.cpp
@@ -0,0 +1,30 @@
+#include "kernel/vga.hpp"
+
+#include "boot/asm_pointer.hpp"
+#include "boot/pointers.hpp"
+
+#include <string_view>
+#include <algorithm>
+
+namespace teachos::kernel::vga
+{
+
+ namespace
+ {
+ auto constinit text_buffer_pointer = boot::asm_pointer{boot::vga_buffer_pointer};
+
+ auto write(char character, std::byte color) -> void
+ {
+ auto & p = *text_buffer_pointer;
+ (*p++) = static_cast<std::byte>(character);
+ (*p++) = color;
+ };
+ } // namespace
+
+ auto write(std::string_view text, std::byte color) -> void {
+ std::ranges::for_each(text, [&](auto character) {
+ write(character, color);
+ });
+ }
+
+} // namespace teachos::kernel \ No newline at end of file