From a70bfb87d535e0f0d90bee57c8a64393b86dfa3d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 21 Oct 2018 21:59:43 +0200 Subject: [PATCH] Add a Console device and start refactoring screen output. --- Kernel/Console.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ Kernel/Console.h | 25 +++++++++++++++++++++++++ Kernel/Makefile | 3 ++- Kernel/VGA.cpp | 15 +++++++++++++++ Kernel/init.cpp | 25 +++++++++++++------------ 5 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 Kernel/Console.cpp create mode 100644 Kernel/Console.h diff --git a/Kernel/Console.cpp b/Kernel/Console.cpp new file mode 100644 index 0000000000..5e4239f172 --- /dev/null +++ b/Kernel/Console.cpp @@ -0,0 +1,40 @@ +#include "Console.h" +#include "VGA.h" + +static Console* s_the; + +Console& Console::the() +{ + return *s_the; +} + +Console::Console() +{ + s_the = this; +} + +Console::~Console() +{ +} + +ssize_t Console::read(byte* buffer, size_t bufferSize) +{ + // FIXME: Implement reading from the console. + // Maybe we could use a ring buffer for this device? + // A generalized ring buffer would probably be useful. + return 0; +} + +extern int kprintfFromConsole(const char*, ...); + +ssize_t Console::write(const byte* data, size_t size) +{ + if (!size) + return 0; + + for (size_t i = 0; i < size; ++i) { + kprintfFromConsole("%c", data[i]); + } + return 0; +} + diff --git a/Kernel/Console.h b/Kernel/Console.h new file mode 100644 index 0000000000..51b41839dd --- /dev/null +++ b/Kernel/Console.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +class Console final : public CharacterDevice { +public: + static Console& the(); + + Console(); + virtual ~Console() override; + + virtual ssize_t read(byte* buffer, size_t size) override; + virtual ssize_t write(const byte* data, size_t size) override; + +private: + byte m_rows { 25 }; + byte m_columns { 80 }; + byte m_cursorRow { 0 }; + byte m_cursorColumn { 0 }; + + byte m_currentAttribute { 0x07 }; + + const byte* s_vgaMemory { (const byte*)0xb8000 }; +}; + diff --git a/Kernel/Makefile b/Kernel/Makefile index f650b3f24f..7729cefa1f 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -18,7 +18,8 @@ KERNEL_OBJS = \ Disk.o \ Userspace.o \ IDEDiskDevice.o \ - MemoryManager.o + MemoryManager.o \ + Console.o VFS_OBJS = \ ../VirtualFileSystem/DiskDevice.o \ diff --git a/Kernel/VGA.cpp b/Kernel/VGA.cpp index 5949f0ad0e..bb9cb49b4b 100644 --- a/Kernel/VGA.cpp +++ b/Kernel/VGA.cpp @@ -5,6 +5,7 @@ #include "StdLib.h" #include "Task.h" #include +#include "Console.h" PRIVATE BYTE *vga_mem = 0L; PRIVATE BYTE current_attr = 0x07; @@ -15,6 +16,11 @@ template static int printNumber(PutChFunc, char*&, DWORD); template static int printHex(PutChFunc, char*&, DWORD, BYTE fields); template static int printSignedNumber(PutChFunc, char*&, int); +static void console_putch(char*, char ch) +{ + Console::the().write((byte*)&ch, 1); +} + static void vga_putch(char*, char ch) { WORD row; @@ -120,6 +126,15 @@ int kprintfInternal(PutChFunc putch, char* buffer, const char*& fmt, char*& ap) } int kprintf(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int ret = kprintfInternal(console_putch, nullptr, fmt, ap); + va_end(ap); + return ret; +} + +int kprintfFromConsole(const char* fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 5ab81f4005..1e96ef12c3 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -24,9 +24,10 @@ #include #include "MemoryManager.h" #include +#include "Console.h" -#define TEST_ELF_LOADER -#define TEST_CRASHY_USER_PROCESSES +//#define TEST_ELF_LOADER +//#define TEST_CRASHY_USER_PROCESSES #if 0 /* Keyboard LED disco task ;^) */ @@ -126,6 +127,8 @@ void init() kmalloc_init(); vga_init(); + auto console = make(); + PIC::initialize(); gdt_init(); idt_init(); @@ -160,7 +163,7 @@ void init() Disk::initialize(); -#if 1 +#if CHECK_VFS auto vfs = make(); auto dev_zero = make(); @@ -181,15 +184,8 @@ void init() vfs->mountRoot(e2fs.copyRef()); -#ifdef TEST_CRASHY_USER_PROCESSES - new Task(user_main, "user", IPC::Handle::UserTask, Task::Ring3); - new Task(user_kprintf_main, "user_kprintf", IPC::Handle::UserTask, Task::Ring3); -#endif - //vfs->listDirectory("/"); -#endif -#if 1 { auto motdFile = vfs->open("/motd.txt"); ASSERT(motdFile); @@ -201,6 +197,11 @@ void init() } #endif +#ifdef TEST_CRASHY_USER_PROCESSES + new Task(user_main, "user", IPC::Handle::UserTask, Task::Ring3); + new Task(user_kprintf_main, "user_kprintf", IPC::Handle::UserTask, Task::Ring3); +#endif + #ifdef TEST_ELF_LOADER { auto testExecutable = vfs->open("/_hello.o"); @@ -220,8 +221,8 @@ void init() } #endif - new Task(motd_main, "motd", IPC::Handle::MotdTask, Task::Ring0); - new Task(syscall_test_main, "syscall_test", IPC::Handle::MotdTask, Task::Ring0); + //new Task(motd_main, "motd", IPC::Handle::MotdTask, Task::Ring0); + //new Task(syscall_test_main, "syscall_test", IPC::Handle::MotdTask, Task::Ring3); // The idle task will spend its eternity here for now. for (;;) {