From 0e46ea8adabe5e6fd8d67835d8a75b497da633c8 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 1 Oct 2022 14:27:45 +0200 Subject: [PATCH] Finally, a text renderer that actually works. We can now see the kernel messages without a serial port :) --- kernel/include/std/stdio.h | 6 ++++-- kernel/src/log/Log.cpp | 11 +++++++++++ kernel/src/main.cpp | 10 ++++------ kernel/src/render/TextRenderer.cpp | 22 ++++++++++++---------- kernel/src/std/stdio.cpp | 17 +++++++++++++++++ kernel/src/sys/stdio.cpp | 2 ++ 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/kernel/include/std/stdio.h b/kernel/include/std/stdio.h index 21c6cd64..ffe7e14e 100644 --- a/kernel/include/std/stdio.h +++ b/kernel/include/std/stdio.h @@ -4,9 +4,11 @@ #define PRINTF_LIKE(n, m) __attribute__((format(printf, n, m))) -int printf(const char* fmt, ...) PRINTF_LIKE(1, 2); +int printf(const char* fmt, ...) PRINTF_LIKE(1, 2); // Outputs to serial. int sprintf(char* __s, const char* fmt, ...) PRINTF_LIKE(2, 3); int snprintf(char* __s, size_t max, const char* fmt, ...) PRINTF_LIKE(3, 4); int vprintf(const char* fmt, va_list ap); int vsprintf(char* __s, const char* fmt, va_list ap); -int vsnprintf(char* __s, size_t max, const char* fmt, va_list ap); \ No newline at end of file +int vsnprintf(char* __s, size_t max, const char* fmt, va_list ap); +int kprintf(const char* fmt, ...) PRINTF_LIKE(1, 2); // Outputs to text console. +int vkprintf(const char* fmt, va_list ap); \ No newline at end of file diff --git a/kernel/src/log/Log.cpp b/kernel/src/log/Log.cpp index bd0d7ab4..b5337752 100644 --- a/kernel/src/log/Log.cpp +++ b/kernel/src/log/Log.cpp @@ -15,15 +15,20 @@ void KernelLog::log(const char* function, LogLevel level, const char* message, . printf("[%ld.%ld] ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000); Serial::print(function); Serial::print(": "); + kprintf("%s: ", function); switch (level) { case LogLevel::WARN: Serial::set_color(Color::Yellow); break; case LogLevel::ERROR: Serial::set_color(Color::Red); break; default: break; } + va_list graphical; + va_copy(graphical, ap); vprintf(message, ap); + vkprintf(message, ap); Serial::reset_color(); va_end(ap); + va_end(graphical); } void KernelLog::logln(const char* function, LogLevel level, const char* message, ...) @@ -35,16 +40,22 @@ void KernelLog::logln(const char* function, LogLevel level, const char* message, printf("[%ld.%ld] ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000); Serial::print(function); Serial::print(": "); + kprintf("%s: ", function); switch (level) { case LogLevel::WARN: Serial::set_color(Color::Yellow); break; case LogLevel::ERROR: Serial::set_color(Color::Red); break; default: break; } + va_list graphical; + va_copy(graphical, ap); vprintf(message, ap); + vkprintf(message, graphical); Serial::reset_color(); Serial::print("\n"); + kprintf("\n"); va_end(ap); + va_end(graphical); } void KernelLog::toggle_log_level(LogLevel level) diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 75e54b2e..62b6fdd9 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -70,7 +70,7 @@ extern "C" void _start() kinfoln("Prepared scheduler"); - Scheduler::add_kernel_task([]() { + /*Scheduler::add_kernel_task([]() { int64_t x = 0; int64_t y = 0; int64_t xvel = 10; @@ -103,9 +103,9 @@ extern "C" void _start() } framebuffer0.paint_rect(x, y, 10, 10, Color::from_integer(color)); } - }); + });*/ - Scheduler::add_kernel_task([]() { + /*Scheduler::add_kernel_task([]() { while (1) { sleep(100); @@ -114,7 +114,7 @@ extern "C" void _start() Mersenne::get() % (framebuffer0.height() - 256), Mersenne::get() % 255, Mersenne::get() % 255, Color::from_integer(color)); } - }); + });*/ Scheduler::add_kernel_task([]() { while (1) @@ -128,8 +128,6 @@ extern "C" void _start() kinfoln("Prepared scheduler tasks"); - framebuffer0.clear(Color::Cyan); - Interrupts::enable(); kinfoln("Interrupts enabled"); diff --git a/kernel/src/render/TextRenderer.cpp b/kernel/src/render/TextRenderer.cpp index 3bcfb5f4..3492046d 100644 --- a/kernel/src/render/TextRenderer.cpp +++ b/kernel/src/render/TextRenderer.cpp @@ -33,7 +33,8 @@ bool TextRenderer::is_initialized() #pragma GCC push_options #pragma GCC optimize("O0") -static void putchar_at_offset(char c, uint32_t cx, uint32_t cy, Color& fg, Color& bg) +static void putchar_at_offset(char c, [[maybe_unused]] uint32_t cx, [[maybe_unused]] uint32_t cy, + [[maybe_unused]] Color& fg, [[maybe_unused]] Color& bg) { uint8_t* glyph = &font[c * 16]; for (uint32_t y = 0; y < FONT_HEIGHT; y++) @@ -41,9 +42,8 @@ static void putchar_at_offset(char c, uint32_t cx, uint32_t cy, Color& fg, Color for (uint32_t x = 0; x < FONT_WIDTH; x++) { volatile uint8_t mask = *glyph; - printf("%d", mask); - if (mask & (1 << x)) { framebuffer0.set_pixel(cx + x, cy + y, fg); } - else { framebuffer0.set_pixel(cx + x, cy + y, bg); } + if ((mask & (0b10000000 >> x)) > 0) { framebuffer0.set_pixel(cx + x, cy + y, Color::White); } + else { framebuffer0.set_pixel(cx + x, cy + y, Color::Black); } } glyph++; } @@ -55,17 +55,18 @@ void TextRenderer::putchar(char chr) { switch (chr) { - case '\n': + case '\n': { ypos += FONT_HEIGHT; if ((ypos + FONT_HEIGHT) >= bootboot.fb_height) { - memcpy((void*)bootboot.fb_ptr, (uint32_t*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT), - bootboot.fb_size - (sizeof(uint32_t) * bootboot.fb_scanline * FONT_HEIGHT)); + memcpy((void*)bootboot.fb_ptr, (char*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT), + bootboot.fb_size - (bootboot.fb_scanline * FONT_HEIGHT)); ypos -= FONT_HEIGHT; framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black); } xpos = 0; break; + } case '\r': xpos = 0; break; case '\b': if (xpos != 0) @@ -74,7 +75,7 @@ void TextRenderer::putchar(char chr) framebuffer0.paint_rect(xpos, ypos, FONT_WIDTH, FONT_HEIGHT, Color::Black); } break; - default: + default: { putchar_at_offset(chr, xpos, ypos, fgColor, bgColor); xpos += FONT_WIDTH; if ((xpos + FONT_WIDTH) > bootboot.fb_width) @@ -83,14 +84,15 @@ void TextRenderer::putchar(char chr) ypos += FONT_HEIGHT; if (ypos > bootboot.fb_height) { - memcpy((void*)bootboot.fb_ptr, (uint32_t*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT), - bootboot.fb_size - (sizeof(uint32_t) * bootboot.fb_scanline * FONT_HEIGHT)); + memcpy((void*)bootboot.fb_ptr, (char*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT), + bootboot.fb_size - (bootboot.fb_scanline * FONT_HEIGHT)); ypos -= FONT_HEIGHT; framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black); } } break; } + } } void TextRenderer::write(const char* str, size_t size) diff --git a/kernel/src/std/stdio.cpp b/kernel/src/std/stdio.cpp index 93ce38da..09d45717 100644 --- a/kernel/src/std/stdio.cpp +++ b/kernel/src/std/stdio.cpp @@ -1,6 +1,8 @@ #include "std/stdio.h" #include "io/Serial.h" +#include "render/TextRenderer.h" #include "std/stdlib.h" +#include "std/string.h" #include typedef long int ssize_t; @@ -205,6 +207,15 @@ int printf(const char* fmt, ...) return written; } +int kprintf(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int written = vkprintf(fmt, ap); + va_end(ap); + return written; +} + int sprintf(char* __s, const char* fmt, ...) { va_list ap; @@ -239,6 +250,12 @@ int vprintf(const char* fmt, va_list ap) fmt, [](const char* s) { Serial::print(s); }, -1, ap); } +int vkprintf(const char* fmt, va_list ap) +{ + return internal_printf( + fmt, [](const char* s) { TextRenderer::write(s, strlen(s)); }, -1, ap); +} + int vsprintf(char* __s, const char* fmt, va_list ap) { return internal_printf( diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp index 1d4c6d9f..5aaddee3 100644 --- a/kernel/src/sys/stdio.cpp +++ b/kernel/src/sys/stdio.cpp @@ -1,8 +1,10 @@ #include "interrupts/Context.h" #include "io/Serial.h" +#include "render/TextRenderer.h" void sys_write(Context* context, const char* addr, size_t size) { context->rax = size; Serial::write(addr, size); + TextRenderer::write(addr, size); } \ No newline at end of file