diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-11-24 16:59:24 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-11-24 16:59:24 +0100 |
| commit | 1a3c20cc9ea191a862eb7e8ac55b3a69ac74ad5e (patch) | |
| tree | e740d842eb64f9dcde4a70ff138092d349e717c1 /arch/x86_64/src | |
| parent | 2b3dca0d0329b61881ffbecca0f120cfda3314fa (diff) | |
| download | teachos-1a3c20cc9ea191a862eb7e8ac55b3a69ac74ad5e.tar.xz teachos-1a3c20cc9ea191a862eb7e8ac55b3a69ac74ad5e.zip | |
x86_64/vga: rely less on magic state
Diffstat (limited to 'arch/x86_64/src')
| -rw-r--r-- | arch/x86_64/src/boot/entry64.s | 19 | ||||
| -rw-r--r-- | arch/x86_64/src/kapi/memory.cpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/src/vga/text.cpp | 50 |
3 files changed, 50 insertions, 23 deletions
diff --git a/arch/x86_64/src/boot/entry64.s b/arch/x86_64/src/boot/entry64.s index c5df5db..636e4cd 100644 --- a/arch/x86_64/src/boot/entry64.s +++ b/arch/x86_64/src/boot/entry64.s @@ -1,3 +1,16 @@ +.section .bss, "aw", @nobits + +//! A structure containing information gathered during the bootstrap process. +//! Expected layout (as described by teachos::boot::information): +//! +//! struct +//! { +//! multiboot2::information_view const * mbi; +//! std::size_t vga_buffer_index; +//! } +.global bootstrap_information +bootstrap_information: .skip 16 + .section .boot_text, "ax", @progbits .code64 @@ -10,6 +23,12 @@ _entry64: mov %rax, %fs mov %rax, %gs + mov multiboot_information_pointer, %rax + mov vga_buffer_pointer, %rdx + sub $0xb8000, %rdx + mov %rax, (bootstrap_information) + mov %rdx, (bootstrap_information + 8) + call invoke_global_constructors xor %rax, %rax diff --git a/arch/x86_64/src/kapi/memory.cpp b/arch/x86_64/src/kapi/memory.cpp index 5142a2a..3848fb8 100644 --- a/arch/x86_64/src/kapi/memory.cpp +++ b/arch/x86_64/src/kapi/memory.cpp @@ -24,7 +24,7 @@ namespace teachos::memory auto create_memory_information() -> x86_64::region_allocator::memory_information { - auto const & mbi = boot::x86_64::multiboot_information_pointer.get(); + auto const & mbi = boot::bootstrap_information.mbi; return {.image_range = std::make_pair(physical_address{&boot::x86_64::_start_physical}, physical_address{&boot::x86_64::_end_physical}), @@ -35,7 +35,7 @@ namespace teachos::memory auto create_early_frame_allocator() { - auto memory_map = boot::x86_64::multiboot_information_pointer->maybe_memory_map(); + auto memory_map = boot::bootstrap_information.mbi->maybe_memory_map(); if (!memory_map) { system::panic("[x86_64] Failed to create early allocator, no memory map available."); diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 6ecffa3..8b7f01b 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -1,38 +1,41 @@ #include "x86_64/vga/text.hpp" +#include "kapi/boot.hpp" + #include "x86_64/boot/boot.hpp" +#include "x86_64/boot/ld.hpp" #include "x86_64/vga/crtc.hpp" #include <algorithm> #include <bit> #include <cstddef> +#include <cstdint> #include <string_view> #include <utility> namespace teachos::vga::x86_64::text { - using boot::x86_64::vga_buffer_pointer; - namespace { - // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) - auto constinit buffer_offset = std::ptrdiff_t{}; - + constexpr auto BUFFER_BASE_ADDRESS = std::uintptr_t{0xb8000}; constexpr auto DEFAULT_TEXT_BUFFER_WIDTH = 80U; constexpr auto DEFAULT_TEXT_BUFFER_HEIGHT = 25U; constexpr auto CURSOR_ENABLED_BIT = 5U; - - auto write_char(char code_point, attribute attribute) -> void - { - vga_buffer_pointer[buffer_offset++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)}; - }; } // namespace + std::span<device::glyph> const device::buffer = + std::span{std::bit_cast<device::glyph *>(BUFFER_BASE_ADDRESS + + std::bit_cast<std::uintptr_t>(&teachos::boot::x86_64::TEACHOS_VMA)), + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT}; + + device::device() + : m_position{boot::bootstrap_information.vga_buffer_index} + {} + auto device::clear(attribute attribute) -> void { - buffer_offset = 0; - std::ranges::fill_n(vga_buffer_pointer.get(), DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT, - std::pair{' ', std::bit_cast<std::byte>(attribute)}); + m_position = 0; + std::ranges::fill(buffer, std::pair{' ', std::bit_cast<std::byte>(attribute)}); } auto device::cursor(bool enabled) -> void @@ -45,30 +48,35 @@ namespace teachos::vga::x86_64::text auto device::newline() -> void { - auto current_line = buffer_offset / DEFAULT_TEXT_BUFFER_WIDTH; + auto current_line = m_position / DEFAULT_TEXT_BUFFER_WIDTH; auto next_line = current_line + 1; if (std::cmp_greater_equal(next_line, DEFAULT_TEXT_BUFFER_HEIGHT)) { - auto begin = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH; - auto end = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT; - std::ranges::move(begin, end, vga_buffer_pointer.get()); - buffer_offset = current_line * DEFAULT_TEXT_BUFFER_WIDTH; + auto begin = buffer.begin() + DEFAULT_TEXT_BUFFER_WIDTH; + auto end = buffer.begin() + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT; + std::ranges::move(begin, end, buffer.begin()); + m_position = current_line * DEFAULT_TEXT_BUFFER_WIDTH; } else { - buffer_offset = next_line * DEFAULT_TEXT_BUFFER_WIDTH; + m_position = next_line * DEFAULT_TEXT_BUFFER_WIDTH; } } auto device::write(std::string_view code_points, attribute attribute) -> void { - std::ranges::for_each(code_points, [&](auto code_point) -> void { write_char(code_point, attribute); }); + std::ranges::for_each(code_points, [&](auto code_point) -> void { write(code_point, attribute); }); } + auto device::write(char code_point, attribute attribute) -> void + { + buffer[m_position++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)}; + }; + auto device::writeln(std::string_view code_points, attribute attribute) -> void { - std::ranges::for_each(code_points, [&](auto code_point) -> void { write_char(code_point, attribute); }); + std::ranges::for_each(code_points, [&](auto code_point) -> void { write(code_point, attribute); }); newline(); } |
