Browse Source

Add a Console device and start refactoring screen output.

Andreas Kling 6 years ago
parent
commit
a70bfb87d5
5 changed files with 95 additions and 13 deletions
  1. 40 0
      Kernel/Console.cpp
  2. 25 0
      Kernel/Console.h
  3. 2 1
      Kernel/Makefile
  4. 15 0
      Kernel/VGA.cpp
  5. 13 12
      Kernel/init.cpp

+ 40 - 0
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;
+}
+

+ 25 - 0
Kernel/Console.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include <VirtualFileSystem/CharacterDevice.h>
+
+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 };
+};
+

+ 2 - 1
Kernel/Makefile

@@ -18,7 +18,8 @@ KERNEL_OBJS = \
        Disk.o \
        Disk.o \
        Userspace.o \
        Userspace.o \
        IDEDiskDevice.o \
        IDEDiskDevice.o \
-       MemoryManager.o
+       MemoryManager.o \
+       Console.o
 
 
 VFS_OBJS = \
 VFS_OBJS = \
     ../VirtualFileSystem/DiskDevice.o \
     ../VirtualFileSystem/DiskDevice.o \

+ 15 - 0
Kernel/VGA.cpp

@@ -5,6 +5,7 @@
 #include "StdLib.h"
 #include "StdLib.h"
 #include "Task.h"
 #include "Task.h"
 #include <stdarg.h>
 #include <stdarg.h>
+#include "Console.h"
 
 
 PRIVATE BYTE *vga_mem = 0L;
 PRIVATE BYTE *vga_mem = 0L;
 PRIVATE BYTE current_attr = 0x07;
 PRIVATE BYTE current_attr = 0x07;
@@ -15,6 +16,11 @@ template<typename PutChFunc> static int printNumber(PutChFunc, char*&, DWORD);
 template<typename PutChFunc> static int printHex(PutChFunc, char*&, DWORD, BYTE fields);
 template<typename PutChFunc> static int printHex(PutChFunc, char*&, DWORD, BYTE fields);
 template<typename PutChFunc> static int printSignedNumber(PutChFunc, char*&, int);
 template<typename PutChFunc> 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)
 static void vga_putch(char*, char ch)
 {
 {
     WORD row;
     WORD row;
@@ -120,6 +126,15 @@ int kprintfInternal(PutChFunc putch, char* buffer, const char*& fmt, char*& ap)
 }
 }
 
 
 int kprintf(const char* fmt, ...)
 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_list ap;
     va_start(ap, fmt);
     va_start(ap, fmt);

+ 13 - 12
Kernel/init.cpp

@@ -24,9 +24,10 @@
 #include <AK/OwnPtr.h>
 #include <AK/OwnPtr.h>
 #include "MemoryManager.h"
 #include "MemoryManager.h"
 #include <ELFLoader/ELFLoader.h>
 #include <ELFLoader/ELFLoader.h>
+#include "Console.h"
 
 
-#define TEST_ELF_LOADER
-#define TEST_CRASHY_USER_PROCESSES
+//#define TEST_ELF_LOADER
+//#define TEST_CRASHY_USER_PROCESSES
 
 
 #if 0
 #if 0
 /* Keyboard LED disco task ;^) */
 /* Keyboard LED disco task ;^) */
@@ -126,6 +127,8 @@ void init()
     kmalloc_init();
     kmalloc_init();
     vga_init();
     vga_init();
 
 
+    auto console = make<Console>();
+
     PIC::initialize();
     PIC::initialize();
     gdt_init();
     gdt_init();
     idt_init();
     idt_init();
@@ -160,7 +163,7 @@ void init()
 
 
     Disk::initialize();
     Disk::initialize();
 
 
-#if 1
+#if CHECK_VFS
     auto vfs = make<VirtualFileSystem>();
     auto vfs = make<VirtualFileSystem>();
 
 
     auto dev_zero = make<ZeroDevice>();
     auto dev_zero = make<ZeroDevice>();
@@ -181,15 +184,8 @@ void init()
 
 
     vfs->mountRoot(e2fs.copyRef());
     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("/");
     //vfs->listDirectory("/");
-#endif
 
 
-#if 1
     {
     {
         auto motdFile = vfs->open("/motd.txt");
         auto motdFile = vfs->open("/motd.txt");
         ASSERT(motdFile);
         ASSERT(motdFile);
@@ -201,6 +197,11 @@ void init()
     }
     }
 #endif
 #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
 #ifdef TEST_ELF_LOADER
     {
     {
         auto testExecutable = vfs->open("/_hello.o");
         auto testExecutable = vfs->open("/_hello.o");
@@ -220,8 +221,8 @@ void init()
     }
     }
 #endif
 #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.
     // The idle task will spend its eternity here for now.
     for (;;) {
     for (;;) {