Refactor kernel log.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-03-19 14:27:28 +01:00
parent 77467b7768
commit 20698b35c7
9 changed files with 171 additions and 171 deletions

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -31,9 +31,18 @@
#include <stdint.h>
#include <string.h>
typedef struct multiboot_info multiboot_info_t;
namespace Sortix {
class TextBufferHandle;
} // namespace Sortix
namespace Sortix {
namespace Log {
extern TextBufferHandle* device_textbufhandle;
extern size_t (*device_callback)(void*, const char*, size_t);
extern size_t (*device_width)(void*);
extern size_t (*device_height)(void*);
@ -106,6 +115,8 @@ inline size_t PrintFV(const char* format, va_list list)
return (size_t) result;
}
void Init(multiboot_info_t* bootinfo);
} // namespace Log
} // namespace Sortix

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -98,15 +98,14 @@ public:
// the screen resolution or the graphics driver. The backing text buffer can
// only be changed when there are no references (but our own) to the text buffer
// so don't forget to release it when you are done.
class TextBufferHandle : public Refcountable
class TextBufferHandle
{
public:
TextBufferHandle(TextBuffer* textbuf = NULL, bool deletebuf = true,
TextBuffer* def = NULL, bool deletedef = true);
virtual ~TextBufferHandle();
TextBufferHandle(TextBuffer* textbuf = NULL);
~TextBufferHandle();
TextBuffer* Acquire();
void Release(TextBuffer* textbuf);
void Replace(TextBuffer* newtextbuf, bool deletebuf = true);
void Replace(TextBuffer* newtextbuf);
bool EmergencyIsImpaired();
bool EmergencyRecoup();
void EmergencyReset();
@ -117,10 +116,7 @@ private:
kthread_mutex_t mutex;
kthread_cond_t unusedcond;
TextBuffer* textbuf;
TextBuffer* def;
size_t numused;
bool deletedef;
bool deletebuf;
};

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2014, 2015.
This file is part of Sortix.
@ -57,7 +57,6 @@ public:
namespace Sortix {
namespace Video {
void Init(Ref<TextBufferHandle> textbufhandle);
bool RegisterDevice(const char* name, VideoDevice* device);
} // namespace Video

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -82,10 +82,8 @@
#include "multiboot.h"
#include "net/fs.h"
#include "poll.h"
#include "textterminal.h"
#include "uart.h"
#include "vga.h"
#include "vgatextbuffer.h"
#if defined(__i386__) || defined(__x86_64__)
#include "x86-family/cmos.h"
@ -99,85 +97,13 @@ extern "C" { __attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_
namespace Sortix {
void DoWelcome()
{
Log::Print(BRAND_KERNEL_BOOT_MESSAGE);
}
// Forward declarations.
static void BootThread(void* user);
static void InitThread(void* user);
static void SystemIdleThread(void* user);
static size_t PrintToTextTerminal(void* user, const char* str, size_t len)
{
return ((TextTerminal*) user)->Print(str, len);
}
static size_t TextTermWidth(void* user)
{
return ((TextTerminal*) user)->Width();
}
static size_t TextTermHeight(void* user)
{
return ((TextTerminal*) user)->Height();
}
static void TextTermGetCursor(void* user, size_t* column, size_t* row)
{
((TextTerminal*) user)->GetCursor(column, row);
}
static bool TextTermSync(void* user)
{
return ((TextTerminal*) user)->Sync();
}
static bool EmergencyTextTermIsImpaired(void* user)
{
return ((TextTerminal*) user)->EmergencyIsImpaired();
}
static bool EmergencyTextTermRecoup(void* user)
{
return ((TextTerminal*) user)->EmergencyRecoup();
}
static void EmergencyTextTermReset(void* user)
{
((TextTerminal*) user)->EmergencyReset();
}
static
size_t EmergencyPrintToTextTerminal(void* user, const char* str, size_t len)
{
return ((TextTerminal*) user)->EmergencyPrint(str, len);
}
static size_t EmergencyTextTermWidth(void* user)
{
return ((TextTerminal*) user)->EmergencyWidth();
}
static size_t EmergencyTextTermHeight(void* user)
{
return ((TextTerminal*) user)->EmergencyHeight();
}
static void EmergencyTextTermGetCursor(void* user, size_t* column, size_t* row)
{
((TextTerminal*) user)->EmergencyGetCursor(column, row);
}
static bool EmergencyTextTermSync(void* user)
{
return ((TextTerminal*) user)->EmergencySync();
}
addr_t initrd;
size_t initrdsize;
Ref<TextBufferHandle> textbufhandle;
extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
{
@ -192,41 +118,11 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
// Detect available physical memory.
Memory::Init(bootinfo);
// Setup a text buffer handle for use by the text terminal.
uint16_t* const VGAFB = (uint16_t*) 0xB8000;
const size_t VGA_WIDTH = 80;
const size_t VGA_HEIGHT = 25;
static uint16_t vga_attr_buffer[VGA_WIDTH*VGA_HEIGHT];
static struct TextCharPOD vga_chars_pod_buffer[VGA_WIDTH*VGA_HEIGHT];
TextChar* vga_chars_buffer = (TextChar*) vga_chars_pod_buffer;
VGATextBuffer textbuf(VGAFB, vga_chars_buffer, vga_attr_buffer, VGA_WIDTH, VGA_HEIGHT);
TextBufferHandle textbufhandlestack(NULL, false, &textbuf, false);
textbufhandle = Ref<TextBufferHandle>(&textbufhandlestack);
// Setup a text terminal instance.
TextTerminal textterm(textbufhandle);
// Register the text terminal as the kernel log.
Log::device_callback = PrintToTextTerminal;
Log::device_width = TextTermWidth;
Log::device_height = TextTermHeight;
Log::device_get_cursor = TextTermGetCursor;
Log::device_sync = TextTermSync;
Log::device_pointer = &textterm;
// Register the emergency kernel log.
Log::emergency_device_is_impaired = EmergencyTextTermIsImpaired;
Log::emergency_device_recoup = EmergencyTextTermRecoup;
Log::emergency_device_reset = EmergencyTextTermReset;
Log::emergency_device_callback = EmergencyPrintToTextTerminal;
Log::emergency_device_width = EmergencyTextTermWidth;
Log::emergency_device_height = EmergencyTextTermHeight;
Log::emergency_device_get_cursor = EmergencyTextTermGetCursor;
Log::emergency_device_sync = EmergencyTextTermSync;
Log::emergency_device_pointer = &textterm;
// Initialize the kernel log.
Log::Init(bootinfo);
// Display the boot welcome screen.
DoWelcome();
Log::Print(BRAND_KERNEL_BOOT_MESSAGE);
#if defined(__x86_64__)
// TODO: Remove this hack when qemu 1.4.x and 1.5.0 are obsolete.
@ -573,9 +469,6 @@ static void BootThread(void* /*user*/)
// Initialize the VGA driver.
VGA::Init("/dev", slashdev);
// Initialize the Video Driver framework.
Video::Init(textbufhandle);
// Search for PCI devices and load their drivers.
PCI::Init();

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -27,11 +27,15 @@
#include <sortix/kernel/kernel.h>
#include <sortix/kernel/log.h>
#include <sortix/kernel/syscall.h>
#include <sortix/kernel/textbuffer.h>
#include "textterminal.h"
#include "vgatextbuffer.h"
namespace Sortix {
namespace Log {
TextBufferHandle* device_textbufhandle = NULL;
size_t (*device_callback)(void*, const char*, size_t) = NULL;
size_t (*device_width)(void*) = NULL;
size_t (*device_height)(void*) = NULL;
@ -48,5 +52,124 @@ size_t (*emergency_device_height)(void*) = NULL;
bool (*emergency_device_sync)(void*) = NULL;
void* emergency_device_pointer = NULL;
static size_t PrintToTextTerminal(void* user, const char* str, size_t len)
{
return ((TextTerminal*) user)->Print(str, len);
}
static size_t TextTermWidth(void* user)
{
return ((TextTerminal*) user)->Width();
}
static size_t TextTermHeight(void* user)
{
return ((TextTerminal*) user)->Height();
}
static void TextTermGetCursor(void* user, size_t* column, size_t* row)
{
((TextTerminal*) user)->GetCursor(column, row);
}
static bool TextTermSync(void* user)
{
return ((TextTerminal*) user)->Sync();
}
static bool EmergencyTextTermIsImpaired(void* user)
{
return ((TextTerminal*) user)->EmergencyIsImpaired();
}
static bool EmergencyTextTermRecoup(void* user)
{
return ((TextTerminal*) user)->EmergencyRecoup();
}
static void EmergencyTextTermReset(void* user)
{
((TextTerminal*) user)->EmergencyReset();
}
static
size_t EmergencyPrintToTextTerminal(void* user, const char* str, size_t len)
{
return ((TextTerminal*) user)->EmergencyPrint(str, len);
}
static size_t EmergencyTextTermWidth(void* user)
{
return ((TextTerminal*) user)->EmergencyWidth();
}
static size_t EmergencyTextTermHeight(void* user)
{
return ((TextTerminal*) user)->EmergencyHeight();
}
static void EmergencyTextTermGetCursor(void* user, size_t* column, size_t* row)
{
((TextTerminal*) user)->EmergencyGetCursor(column, row);
}
static bool EmergencyTextTermSync(void* user)
{
return ((TextTerminal*) user)->EmergencySync();
}
void Init(multiboot_info_t* bootinfo)
{
(void) bootinfo;
const char* oom_msg = "Out of memory setting up kernel log.";
// Create the backend text buffer.
TextBuffer* textbuf;
if ( true )
{
uint16_t* const VGAFB = (uint16_t*) 0xB8000;
const size_t VGA_WIDTH = 80;
const size_t VGA_HEIGHT = 25;
uint16_t* vga_attr_buffer = new uint16_t[VGA_WIDTH * VGA_HEIGHT];
TextChar* vga_chars_buffer = new TextChar[VGA_WIDTH * VGA_HEIGHT];
if ( !vga_attr_buffer || !vga_chars_buffer )
Panic(oom_msg);
textbuf = new VGATextBuffer(VGAFB, vga_chars_buffer, vga_attr_buffer,
VGA_WIDTH, VGA_HEIGHT);
if ( !textbuf )
Panic(oom_msg);
}
// Create the text buffer handle.
device_textbufhandle = new TextBufferHandle(textbuf);
if ( !device_textbufhandle )
Panic(oom_msg);
// Setup a text terminal instance.
TextTerminal* textterm = new TextTerminal(device_textbufhandle);
if ( !textterm )
Panic(oom_msg);
// Register the text terminal as the kernel log.
Log::device_callback = PrintToTextTerminal;
Log::device_width = TextTermWidth;
Log::device_height = TextTermHeight;
Log::device_get_cursor = TextTermGetCursor;
Log::device_sync = TextTermSync;
Log::device_pointer = textterm;
// Register the emergency kernel log.
Log::emergency_device_is_impaired = EmergencyTextTermIsImpaired;
Log::emergency_device_recoup = EmergencyTextTermRecoup;
Log::emergency_device_reset = EmergencyTextTermReset;
Log::emergency_device_callback = EmergencyPrintToTextTerminal;
Log::emergency_device_width = EmergencyTextTermWidth;
Log::emergency_device_height = EmergencyTextTermHeight;
Log::emergency_device_get_cursor = EmergencyTextTermGetCursor;
Log::emergency_device_sync = EmergencyTextTermSync;
Log::emergency_device_pointer = textterm;
}
} // namespace Log
} // namespace Sortix

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2015.
This file is part of Sortix.
@ -23,6 +23,7 @@
*******************************************************************************/
#include <assert.h>
#include <errno.h>
#include <sortix/kernel/kernel.h>
#include <sortix/kernel/kthread.h>
@ -31,13 +32,9 @@
namespace Sortix {
TextBufferHandle::TextBufferHandle(TextBuffer* textbuf, bool deletebuf,
TextBuffer* def, bool deletedef)
TextBufferHandle::TextBufferHandle(TextBuffer* textbuf)
{
this->textbuf = textbuf;
this->deletebuf = deletebuf;
this->def = def;
this->deletedef = deletedef;
this->numused = 0;
this->mutex = KTHREAD_MUTEX_INITIALIZER;
this->unusedcond = KTHREAD_COND_INITIALIZER;
@ -45,21 +42,16 @@ TextBufferHandle::TextBufferHandle(TextBuffer* textbuf, bool deletebuf,
TextBufferHandle::~TextBufferHandle()
{
if ( deletebuf )
delete textbuf;
if ( deletedef )
delete def;
delete textbuf;
}
TextBuffer* TextBufferHandle::Acquire()
{
ScopedLock lock(&mutex);
if ( !textbuf )
return errno = EINIT, (TextBuffer*) NULL;
numused++;
if ( textbuf )
return textbuf;
if ( !def )
numused--;
return def;
return textbuf;
}
void TextBufferHandle::Release(TextBuffer* textbuf)
@ -67,7 +59,8 @@ void TextBufferHandle::Release(TextBuffer* textbuf)
assert(textbuf);
ScopedLock lock(&mutex);
assert(numused);
if ( !--numused )
numused--;
if ( numused == 0 )
kthread_cond_signal(&unusedcond);
}
@ -95,7 +88,7 @@ TextBuffer* TextBufferHandle::EmergencyAcquire()
{
// This is during a kernel emergency where preemption has been disabled and
// this is the only thread running.
return textbuf ? textbuf : def;
return textbuf;
}
void TextBufferHandle::EmergencyRelease(TextBuffer* textbuf)
@ -106,15 +99,13 @@ void TextBufferHandle::EmergencyRelease(TextBuffer* textbuf)
(void) textbuf;
}
void TextBufferHandle::Replace(TextBuffer* newtextbuf, bool deletebuf)
void TextBufferHandle::Replace(TextBuffer* newtextbuf)
{
ScopedLock lock(&mutex);
while ( numused )
while ( 0 < numused )
kthread_cond_wait(&unusedcond, &mutex);
if ( deletebuf )
delete textbuf;
this->textbuf = newtextbuf;
this->deletebuf = deletebuf;
delete textbuf;
textbuf = newtextbuf;
}
} // namespace Sortix

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -18,7 +18,7 @@
Sortix. If not, see <http://www.gnu.org/licenses/>.
textterminal.cpp
Translates a character stream to a 2 dimensional array of character.
Translates a character stream to a 2 dimensional array of characters.
*******************************************************************************/
@ -39,7 +39,7 @@ namespace Sortix {
const uint16_t DEFAULT_COLOR = COLOR8_LIGHT_GREY << 0U | COLOR8_BLACK << 4U;
const uint16_t ATTR_CHAR = 1U << 0U;
TextTerminal::TextTerminal(Ref<TextBufferHandle> textbufhandle)
TextTerminal::TextTerminal(TextBufferHandle* textbufhandle)
{
memset(&ps, 0, sizeof(ps));
this->textbufhandle = textbufhandle;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -18,7 +18,7 @@
Sortix. If not, see <http://www.gnu.org/licenses/>.
textterminal.h
An indexable text buffer with the VGA text mode framebuffer as backend.
Translates a character stream to a 2 dimensional array of characters.
*******************************************************************************/
@ -34,10 +34,10 @@ namespace Sortix {
class TextBufferHandle;
class TextTerminal //: public Printable ?
class TextTerminal
{
public:
TextTerminal(Ref<TextBufferHandle> textbufhandle);
TextTerminal(TextBufferHandle* textbufhandle);
~TextTerminal();
size_t Print(const char* string, size_t stringlen);
size_t Width() const;
@ -66,7 +66,7 @@ private:
private:
mbstate_t ps;
mutable Ref<TextBufferHandle> textbufhandle;
mutable TextBufferHandle* textbufhandle;
mutable kthread_mutex_t termlock;
uint8_t vgacolor;
unsigned column;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2014, 2015.
This file is part of Sortix.
@ -52,8 +52,6 @@ size_t num_devices = 0;
size_t devices_length = 0;
DeviceEntry* devices = NULL;
Ref<TextBufferHandle> textbufhandle;
bool RegisterDevice(const char* name, VideoDevice* device)
{
ScopedLock lock(&video_lock);
@ -241,7 +239,7 @@ static int SetCrtcMode(void* ptr, size_t size)
// TODO: This could potentially fail.
if ( msg.device == ONE_AND_ONLY_DEVICE &&
msg.connector == ONE_AND_ONLY_CONNECTOR )
textbufhandle->Replace(device->CreateTextBuffer(msg.connector));
Log::device_textbufhandle->Replace(device->CreateTextBuffer(msg.connector));
// No need to respond.
@ -429,14 +427,3 @@ int sys_dispmsg_issue(void* ptr, size_t size)
}
} // namespace Sortix
namespace Sortix {
namespace Video {
void Init(Ref<TextBufferHandle> thetextbufhandle)
{
textbufhandle = thetextbufhandle;
}
} // namespace Video
} // namespace Sortix