From ff81b5438f280a59ca1825bfdf120d8f256bd154 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 7 Oct 2023 17:15:31 +0200 Subject: x86_64: implement very simple VGA text output --- .vscode/tasks.json | 18 +++++++++- source/.clang-format | 2 +- source/boot/CMakeLists.txt | 4 +++ source/boot/arch/x86_64/CMakeLists.txt | 4 +++ source/boot/arch/x86_64/include/boot/pointers.hpp | 12 +++++++ source/boot/arch/x86_64/src/boot.s | 2 +- source/boot/include/boot/asm_pointer.hpp | 43 +++++++++++++++++++++++ source/cmake/Platforms/x86_64.cmake | 2 +- source/kernel/arch/x86_64/CMakeLists.txt | 1 + source/kernel/arch/x86_64/include/kernel/vga.hpp | 11 ++++++ source/kernel/arch/x86_64/src/entry.cpp | 9 +++-- source/kernel/arch/x86_64/src/vga.cpp | 30 ++++++++++++++++ 12 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 source/boot/arch/x86_64/include/boot/pointers.hpp create mode 100644 source/boot/include/boot/asm_pointer.hpp create mode 100644 source/kernel/arch/x86_64/include/kernel/vga.hpp create mode 100644 source/kernel/arch/x86_64/src/vga.cpp 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 + +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 + 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 + struct asm_pointer + { + 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 " \ 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 + +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(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 +#include + +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(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 -- cgit v1.2.3