Add a Console device and start refactoring screen output.

This commit is contained in:
Andreas Kling 2018-10-21 21:59:43 +02:00
parent d5ec18027e
commit a70bfb87d5
Notes: sideshowbarker 2024-07-19 18:45:57 +09:00
5 changed files with 95 additions and 13 deletions

40
Kernel/Console.cpp Normal file
View file

@ -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
Kernel/Console.h Normal file
View file

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

View file

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

View file

@ -5,6 +5,7 @@
#include "StdLib.h"
#include "Task.h"
#include <stdarg.h>
#include "Console.h"
PRIVATE BYTE *vga_mem = 0L;
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 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);

View file

@ -24,9 +24,10 @@
#include <AK/OwnPtr.h>
#include "MemoryManager.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
/* Keyboard LED disco task ;^) */
@ -126,6 +127,8 @@ void init()
kmalloc_init();
vga_init();
auto console = make<Console>();
PIC::initialize();
gdt_init();
idt_init();
@ -160,7 +163,7 @@ void init()
Disk::initialize();
#if 1
#if CHECK_VFS
auto vfs = make<VirtualFileSystem>();
auto dev_zero = make<ZeroDevice>();
@ -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 (;;) {