From 00ad163cc353a9e69b5e1e00c6f7a9a1e15f3e7a Mon Sep 17 00:00:00 2001 From: Quinten Kock Date: Fri, 4 Dec 2020 03:07:27 +0100 Subject: [PATCH] implement platform-agnostic printf --- kernel/src/arch/x86/vga.c | 14 +++---- kernel/src/hal/print.h | 1 + kernel/src/main.c | 10 +---- kernel/src/print/print.c | 77 +++++++++++++++++++++++++++++++++++++++ kernel/src/print/print.h | 5 +++ 5 files changed, 90 insertions(+), 17 deletions(-) create mode 100644 kernel/src/hal/print.h create mode 100644 kernel/src/print/print.c create mode 100644 kernel/src/print/print.h diff --git a/kernel/src/arch/x86/vga.c b/kernel/src/arch/x86/vga.c index 03c06fc..3bb5fb7 100644 --- a/kernel/src/arch/x86/vga.c +++ b/kernel/src/arch/x86/vga.c @@ -11,6 +11,10 @@ static volatile size_t terminal_column; static volatile uint8_t current_color = VGA_WHITE; static uint16_t *terminal_buffer = (uint16_t*)0xb8000; +void putchar(char c) { + vga_putc(c); +} + void vga_putc(char c) { size_t index = terminal_row*VGA_WIDTH + terminal_column; if(c == '\t') { @@ -30,14 +34,6 @@ void vga_putc(char c) { } } -void vga_puts(const char *c) { - char cur = *(c++); - while(cur != '\0') { - vga_putc(cur); - cur = *(c++); - } -} - void vga_setcolor(uint8_t new_color) { current_color = new_color; } @@ -47,7 +43,7 @@ void vga_write_elsewhere(const char *c, size_t y, size_t x) { size_t old_column = terminal_column; terminal_row = y; terminal_column = x; - vga_puts(c); + puts(c); terminal_row=old_row; terminal_column=old_column; } diff --git a/kernel/src/hal/print.h b/kernel/src/hal/print.h new file mode 100644 index 0000000..f8c2025 --- /dev/null +++ b/kernel/src/hal/print.h @@ -0,0 +1 @@ +void putchar(char); diff --git a/kernel/src/main.c b/kernel/src/main.c index d1db8e2..f140678 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -2,14 +2,8 @@ #include "hal/ops.h" void kmain(int argc, char **argv) { - vga_puts("Kernel initialized! Platform: "); - vga_puts(arch); - vga_putc('\n'); - vga_puts("Bootloader information:\t"); - for(int i = 0; i < argc; i++) { - vga_puts(argv[i]); - vga_putc('\t'); - } + printf("Kernel initialized! Platform: %s\n", arch); + printf("Bootloader type: %s (%s %s)\n", argv[0], argv[1], argv[2]); vga_setcolor(VGA_DARK_GRAY); vga_write_elsewhere("(c) Quinten Kock 2020 (MIT License)", 24, 0); diff --git a/kernel/src/print/print.c b/kernel/src/print/print.c new file mode 100644 index 0000000..8e1dea5 --- /dev/null +++ b/kernel/src/print/print.c @@ -0,0 +1,77 @@ +#include +#include + +#include "print.h" + +void puts(const char* c) { + for(size_t i = 0; c[i]; i++) + putchar(c[i]); +} + +void print(const char* c) { + puts(c); + putchar('\n');; +} + +static const char CONVERSION_TABLE[] = "0123456789abcdef"; + +static void printhex(size_t num) { + int i; + char buf[17]; + + if (!num) { + puts("0x0"); + return; + } + + buf[16] = 0; + + for (i = 15; num; i--) { + buf[i] = CONVERSION_TABLE[num % 16]; + num /= 16; + } + + i++; + puts("0x"); + puts(&buf[i]); +} + +static void printdec(size_t num) { + int i; + char buf[21] = {0}; + + if (!num) { + putchar('0'); + return; + } + + for (i = 19; num; i--) { + buf[i] = (num % 10) + 0x30; + num = num / 10; + } + + i++; + puts(buf + i); +} + +void printf(const char *format, ...) { + va_list argp; + va_start(argp, format); + + while (*format != '\0') { + if (*format == '%') { + format++; + if (*format == 'x') { + printhex(va_arg(argp, size_t)); + } else if (*format == 'd') { + printdec(va_arg(argp, size_t)); + } else if (*format == 's') { + puts(va_arg(argp, char*)); + } + } else { + putchar(*format); + } + format++; + } + va_end(argp); +} diff --git a/kernel/src/print/print.h b/kernel/src/print/print.h new file mode 100644 index 0000000..4e4be31 --- /dev/null +++ b/kernel/src/print/print.h @@ -0,0 +1,5 @@ +#include "../hal/print.h" + +void puts(const char*); +void print(const char*); +void printf(const char *format, ...);