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. This file is part of Sortix.
@ -31,9 +31,18 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
typedef struct multiboot_info multiboot_info_t;
namespace Sortix {
class TextBufferHandle;
} // namespace Sortix
namespace Sortix { namespace Sortix {
namespace Log { namespace Log {
extern TextBufferHandle* device_textbufhandle;
extern size_t (*device_callback)(void*, const char*, size_t); extern size_t (*device_callback)(void*, const char*, size_t);
extern size_t (*device_width)(void*); extern size_t (*device_width)(void*);
extern size_t (*device_height)(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; return (size_t) result;
} }
void Init(multiboot_info_t* bootinfo);
} // namespace Log } // namespace Log
} // namespace Sortix } // 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. This file is part of Sortix.
@ -98,15 +98,14 @@ public:
// the screen resolution or the graphics driver. The backing text buffer can // 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 // 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. // so don't forget to release it when you are done.
class TextBufferHandle : public Refcountable class TextBufferHandle
{ {
public: public:
TextBufferHandle(TextBuffer* textbuf = NULL, bool deletebuf = true, TextBufferHandle(TextBuffer* textbuf = NULL);
TextBuffer* def = NULL, bool deletedef = true); ~TextBufferHandle();
virtual ~TextBufferHandle();
TextBuffer* Acquire(); TextBuffer* Acquire();
void Release(TextBuffer* textbuf); void Release(TextBuffer* textbuf);
void Replace(TextBuffer* newtextbuf, bool deletebuf = true); void Replace(TextBuffer* newtextbuf);
bool EmergencyIsImpaired(); bool EmergencyIsImpaired();
bool EmergencyRecoup(); bool EmergencyRecoup();
void EmergencyReset(); void EmergencyReset();
@ -117,10 +116,7 @@ private:
kthread_mutex_t mutex; kthread_mutex_t mutex;
kthread_cond_t unusedcond; kthread_cond_t unusedcond;
TextBuffer* textbuf; TextBuffer* textbuf;
TextBuffer* def;
size_t numused; 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. This file is part of Sortix.
@ -57,7 +57,6 @@ public:
namespace Sortix { namespace Sortix {
namespace Video { namespace Video {
void Init(Ref<TextBufferHandle> textbufhandle);
bool RegisterDevice(const char* name, VideoDevice* device); bool RegisterDevice(const char* name, VideoDevice* device);
} // namespace Video } // 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. This file is part of Sortix.
@ -82,10 +82,8 @@
#include "multiboot.h" #include "multiboot.h"
#include "net/fs.h" #include "net/fs.h"
#include "poll.h" #include "poll.h"
#include "textterminal.h"
#include "uart.h" #include "uart.h"
#include "vga.h" #include "vga.h"
#include "vgatextbuffer.h"
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
#include "x86-family/cmos.h" #include "x86-family/cmos.h"
@ -99,85 +97,13 @@ extern "C" { __attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_
namespace Sortix { namespace Sortix {
void DoWelcome()
{
Log::Print(BRAND_KERNEL_BOOT_MESSAGE);
}
// Forward declarations. // Forward declarations.
static void BootThread(void* user); static void BootThread(void* user);
static void InitThread(void* user); static void InitThread(void* user);
static void SystemIdleThread(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; addr_t initrd;
size_t initrdsize; size_t initrdsize;
Ref<TextBufferHandle> textbufhandle;
extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) 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. // Detect available physical memory.
Memory::Init(bootinfo); Memory::Init(bootinfo);
// Setup a text buffer handle for use by the text terminal. // Initialize the kernel log.
uint16_t* const VGAFB = (uint16_t*) 0xB8000; Log::Init(bootinfo);
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;
// Display the boot welcome screen. // Display the boot welcome screen.
DoWelcome(); Log::Print(BRAND_KERNEL_BOOT_MESSAGE);
#if defined(__x86_64__) #if defined(__x86_64__)
// TODO: Remove this hack when qemu 1.4.x and 1.5.0 are obsolete. // 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. // Initialize the VGA driver.
VGA::Init("/dev", slashdev); VGA::Init("/dev", slashdev);
// Initialize the Video Driver framework.
Video::Init(textbufhandle);
// Search for PCI devices and load their drivers. // Search for PCI devices and load their drivers.
PCI::Init(); 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. This file is part of Sortix.
@ -27,11 +27,15 @@
#include <sortix/kernel/kernel.h> #include <sortix/kernel/kernel.h>
#include <sortix/kernel/log.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 Sortix {
namespace Log { namespace Log {
TextBufferHandle* device_textbufhandle = NULL;
size_t (*device_callback)(void*, const char*, size_t) = NULL; size_t (*device_callback)(void*, const char*, size_t) = NULL;
size_t (*device_width)(void*) = NULL; size_t (*device_width)(void*) = NULL;
size_t (*device_height)(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; bool (*emergency_device_sync)(void*) = NULL;
void* emergency_device_pointer = 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 Log
} // namespace Sortix } // 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. This file is part of Sortix.
@ -23,6 +23,7 @@
*******************************************************************************/ *******************************************************************************/
#include <assert.h> #include <assert.h>
#include <errno.h>
#include <sortix/kernel/kernel.h> #include <sortix/kernel/kernel.h>
#include <sortix/kernel/kthread.h> #include <sortix/kernel/kthread.h>
@ -31,13 +32,9 @@
namespace Sortix { namespace Sortix {
TextBufferHandle::TextBufferHandle(TextBuffer* textbuf, bool deletebuf, TextBufferHandle::TextBufferHandle(TextBuffer* textbuf)
TextBuffer* def, bool deletedef)
{ {
this->textbuf = textbuf; this->textbuf = textbuf;
this->deletebuf = deletebuf;
this->def = def;
this->deletedef = deletedef;
this->numused = 0; this->numused = 0;
this->mutex = KTHREAD_MUTEX_INITIALIZER; this->mutex = KTHREAD_MUTEX_INITIALIZER;
this->unusedcond = KTHREAD_COND_INITIALIZER; this->unusedcond = KTHREAD_COND_INITIALIZER;
@ -45,21 +42,16 @@ TextBufferHandle::TextBufferHandle(TextBuffer* textbuf, bool deletebuf,
TextBufferHandle::~TextBufferHandle() TextBufferHandle::~TextBufferHandle()
{ {
if ( deletebuf )
delete textbuf; delete textbuf;
if ( deletedef )
delete def;
} }
TextBuffer* TextBufferHandle::Acquire() TextBuffer* TextBufferHandle::Acquire()
{ {
ScopedLock lock(&mutex); ScopedLock lock(&mutex);
if ( !textbuf )
return errno = EINIT, (TextBuffer*) NULL;
numused++; numused++;
if ( textbuf )
return textbuf; return textbuf;
if ( !def )
numused--;
return def;
} }
void TextBufferHandle::Release(TextBuffer* textbuf) void TextBufferHandle::Release(TextBuffer* textbuf)
@ -67,7 +59,8 @@ void TextBufferHandle::Release(TextBuffer* textbuf)
assert(textbuf); assert(textbuf);
ScopedLock lock(&mutex); ScopedLock lock(&mutex);
assert(numused); assert(numused);
if ( !--numused ) numused--;
if ( numused == 0 )
kthread_cond_signal(&unusedcond); 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 during a kernel emergency where preemption has been disabled and
// this is the only thread running. // this is the only thread running.
return textbuf ? textbuf : def; return textbuf;
} }
void TextBufferHandle::EmergencyRelease(TextBuffer* textbuf) void TextBufferHandle::EmergencyRelease(TextBuffer* textbuf)
@ -106,15 +99,13 @@ void TextBufferHandle::EmergencyRelease(TextBuffer* textbuf)
(void) textbuf; (void) textbuf;
} }
void TextBufferHandle::Replace(TextBuffer* newtextbuf, bool deletebuf) void TextBufferHandle::Replace(TextBuffer* newtextbuf)
{ {
ScopedLock lock(&mutex); ScopedLock lock(&mutex);
while ( numused ) while ( 0 < numused )
kthread_cond_wait(&unusedcond, &mutex); kthread_cond_wait(&unusedcond, &mutex);
if ( deletebuf )
delete textbuf; delete textbuf;
this->textbuf = newtextbuf; textbuf = newtextbuf;
this->deletebuf = deletebuf;
} }
} // namespace Sortix } // 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. This file is part of Sortix.
@ -18,7 +18,7 @@
Sortix. If not, see <http://www.gnu.org/licenses/>. Sortix. If not, see <http://www.gnu.org/licenses/>.
textterminal.cpp 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 DEFAULT_COLOR = COLOR8_LIGHT_GREY << 0U | COLOR8_BLACK << 4U;
const uint16_t ATTR_CHAR = 1U << 0U; const uint16_t ATTR_CHAR = 1U << 0U;
TextTerminal::TextTerminal(Ref<TextBufferHandle> textbufhandle) TextTerminal::TextTerminal(TextBufferHandle* textbufhandle)
{ {
memset(&ps, 0, sizeof(ps)); memset(&ps, 0, sizeof(ps));
this->textbufhandle = textbufhandle; 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. This file is part of Sortix.
@ -18,7 +18,7 @@
Sortix. If not, see <http://www.gnu.org/licenses/>. Sortix. If not, see <http://www.gnu.org/licenses/>.
textterminal.h 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 TextBufferHandle;
class TextTerminal //: public Printable ? class TextTerminal
{ {
public: public:
TextTerminal(Ref<TextBufferHandle> textbufhandle); TextTerminal(TextBufferHandle* textbufhandle);
~TextTerminal(); ~TextTerminal();
size_t Print(const char* string, size_t stringlen); size_t Print(const char* string, size_t stringlen);
size_t Width() const; size_t Width() const;
@ -66,7 +66,7 @@ private:
private: private:
mbstate_t ps; mbstate_t ps;
mutable Ref<TextBufferHandle> textbufhandle; mutable TextBufferHandle* textbufhandle;
mutable kthread_mutex_t termlock; mutable kthread_mutex_t termlock;
uint8_t vgacolor; uint8_t vgacolor;
unsigned column; 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. This file is part of Sortix.
@ -52,8 +52,6 @@ size_t num_devices = 0;
size_t devices_length = 0; size_t devices_length = 0;
DeviceEntry* devices = NULL; DeviceEntry* devices = NULL;
Ref<TextBufferHandle> textbufhandle;
bool RegisterDevice(const char* name, VideoDevice* device) bool RegisterDevice(const char* name, VideoDevice* device)
{ {
ScopedLock lock(&video_lock); ScopedLock lock(&video_lock);
@ -241,7 +239,7 @@ static int SetCrtcMode(void* ptr, size_t size)
// TODO: This could potentially fail. // TODO: This could potentially fail.
if ( msg.device == ONE_AND_ONLY_DEVICE && if ( msg.device == ONE_AND_ONLY_DEVICE &&
msg.connector == ONE_AND_ONLY_CONNECTOR ) msg.connector == ONE_AND_ONLY_CONNECTOR )
textbufhandle->Replace(device->CreateTextBuffer(msg.connector)); Log::device_textbufhandle->Replace(device->CreateTextBuffer(msg.connector));
// No need to respond. // No need to respond.
@ -429,14 +427,3 @@ int sys_dispmsg_issue(void* ptr, size_t size)
} }
} // namespace Sortix } // namespace Sortix
namespace Sortix {
namespace Video {
void Init(Ref<TextBufferHandle> thetextbufhandle)
{
textbufhandle = thetextbufhandle;
}
} // namespace Video
} // namespace Sortix