diff options
-rw-r--r-- | boot/grub.cfg | 10 | ||||
-rw-r--r-- | kernel/drivers/serial.c | 42 | ||||
-rw-r--r-- | kernel/inc/serial.h | 2 | ||||
-rw-r--r-- | kernel/multiboot.c | 22 |
4 files changed, 61 insertions, 15 deletions
diff --git a/boot/grub.cfg b/boot/grub.cfg index f25a976..7f310e9 100644 --- a/boot/grub.cfg +++ b/boot/grub.cfg @@ -1,6 +1,12 @@ set timeout=0 set default=0 -menuentry "Melvix" { - multiboot /boot/melvix okidoki + +menuentry "Melvix with logging" { + multiboot /boot/melvix log + boot +} + +menuentry "Melvix without logging" { + multiboot /boot/melvix boot } diff --git a/kernel/drivers/serial.c b/kernel/drivers/serial.c index c6172a6..e56c91b 100644 --- a/kernel/drivers/serial.c +++ b/kernel/drivers/serial.c @@ -1,31 +1,55 @@ // MIT License, Copyright (c) 2020 Marvin Borner +#include <assert.h> #include <cpu.h> #include <def.h> #include <serial.h> #include <str.h> +#define PORT 0x3f8 + +PROTECTED static u8 serial_enabled = 0; + +CLEAR void serial_disable(void) +{ + outb(PORT + 4, 0x1e); // Enable loopback + serial_enabled = 0; +} + +CLEAR void serial_enable(void) +{ + outb(PORT + 4, 0x0f); + serial_enabled = 1; +} + CLEAR void serial_install(void) { - outb(0x3f8 + 1, 0x00); - outb(0x3f8 + 3, 0x80); - outb(0x3f8 + 0, 0x03); - outb(0x3f8 + 1, 0x00); - outb(0x3f8 + 3, 0x03); - outb(0x3f8 + 2, 0xC7); - outb(0x3f8 + 4, 0x0B); + outb(PORT + 1, 0x00); + outb(PORT + 3, 0x80); + outb(PORT + 0, 0x03); + outb(PORT + 1, 0x00); + outb(PORT + 3, 0x03); + outb(PORT + 2, 0xc7); + + // Test serial chip + outb(PORT + 4, 0x1e); // Enable loopback + outb(PORT + 0, 0xae); // Write + assert(inb(PORT + 0) == 0xae); // Verify receive } static int is_transmit_empty(void) { - return inb(0x3f8 + 5) & 0x20; + return inb(PORT + 5) & 0x20; } void serial_put(char ch) { + if (!serial_enabled) + return; + while (is_transmit_empty() == 0) ; - outb(0x3f8, (u8)ch); + outb(PORT, (u8)ch); } void serial_print(const char *data) diff --git a/kernel/inc/serial.h b/kernel/inc/serial.h index e96316a..72c9dc1 100644 --- a/kernel/inc/serial.h +++ b/kernel/inc/serial.h @@ -6,6 +6,8 @@ #include <def.h> void serial_install(void); +void serial_enable(void); +void serial_disable(void); void serial_print(const char *data) NONNULL; void serial_put(char ch); diff --git a/kernel/multiboot.c b/kernel/multiboot.c index 8fa7aa6..c99959c 100644 --- a/kernel/multiboot.c +++ b/kernel/multiboot.c @@ -2,20 +2,34 @@ #include <assert.h> #include <def.h> +#include <mem.h> #include <mm.h> #include <multiboot.h> +#include <serial.h> PROTECTED static struct multiboot_info *info = NULL; +CLEAR static void multiboot_parse_cmdline(const char *line) +{ + const char *start = line; + for (const char *p = line; p && *p; p++) { + if (*p == ' ') + start = p + 1; + + if (memcmp(start, "log", 3) == 0) { + serial_enable(); + start += 3; + } + } +} + CLEAR void multiboot_init(u32 magic, u32 addr) { assert(magic == MULTIBOOT_MAGIC); info = (void *)addr; - if (info->flags & MULTIBOOT_INFO_CMDLINE) { - // TODO: Do something useful with grub cmdline? - /* printf("CMDLINE: '%s'\n", info->cmdline); */ - } + if (info->flags & MULTIBOOT_INFO_CMDLINE) + multiboot_parse_cmdline((const char *)info->cmdline); } CLEAR u32 multiboot_vbe(void) |