Finally, a text renderer that actually works. We can now see the kernel messages without a serial port :)

This commit is contained in:
apio 2022-10-01 14:27:45 +02:00
parent cde850258d
commit 0e46ea8ada
6 changed files with 50 additions and 18 deletions

View File

@ -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);
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);

View File

@ -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)

View File

@ -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");

View File

@ -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)

View File

@ -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 <string.h>
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(

View File

@ -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);
}