Global initialization of C++ static objects

I *think* I have this working right...?
This commit is contained in:
Eryn Wells 2016-02-28 03:46:30 -05:00
parent 760884de78
commit d997765710
4 changed files with 48 additions and 12 deletions

View file

@ -10,6 +10,16 @@
namespace kernel { namespace kernel {
/*
* TODO: The build currently complains about missing __cxa_guard_acquire and
* __cxa_guard_release symbols if I add it there though. Once I've written
* those, this can be moved Console::systemConsole().
*
* See http://wiki.osdev.org/C%2B%2B for details.
*/
static Console sSystemConsole;
/** Create a VGA color pair. */ /** Create a VGA color pair. */
static inline uint8_t static inline uint8_t
makeVGAColor(Console::Color fg, makeVGAColor(Console::Color fg,
@ -29,7 +39,21 @@ makeVGAEntry(char c,
return c16 | color16 << 8; return c16 | color16 << 8;
} }
/*
* Static
*/
auto
Console::systemConsole() -> Console&
{
return sSystemConsole;
}
/*
* Public
*/
// TODO: Make this private once the kernel supports local static variables.
Console::Console() Console::Console()
: mBase(reinterpret_cast<uint16_t *>(0xB8000)), : mBase(reinterpret_cast<uint16_t *>(0xB8000)),
mCursor{0, 0}, mCursor{0, 0},

View file

@ -41,6 +41,8 @@ struct Console
static const size_t Width = 80; static const size_t Width = 80;
static const size_t Height = 25; static const size_t Height = 25;
static auto systemConsole() -> Console&;
Console(); Console();
/** Clear the console to the provided color. */ /** Clear the console to the provided color. */

View file

@ -14,8 +14,15 @@
extern "C" extern "C"
void void
kearly() kearly()
{ }
/** The beginning of the world... */
extern "C"
void
kmain()
{ {
kernel::Console console; auto console = kernel::Console::systemConsole();
console.clear(kernel::Console::Color::Blue); console.clear(kernel::Console::Color::Blue);
console.writeString("Hello world!\n"); console.writeString("Hello world!\n");
@ -31,15 +38,8 @@ kearly()
i = (i + 1) % 26; i = (i + 1) % 26;
j = (j + 1) % 500; j = (j + 1) % 500;
for (uint32_t k = 0; k < (2u << 27) - 1; k++) { for (uint32_t k = 0; k < (2u << 20) - 1; k++) {
foo /= 2; foo /= 2;
} }
} }
} }
/** The beginning of the world... */
extern "C"
void
kmain()
{ }

View file

@ -4,11 +4,11 @@
import os import os
import os.path import os.path
import shlex
import subprocess
files = [ files = [
'boot.s', 'boot.s',
'crti.s',
'crtn.s',
'Main.cc', 'Main.cc',
'Console.cc' 'Console.cc'
] ]
@ -23,8 +23,18 @@ Append(CCFLAGS='-ffreestanding',
CXXFLAGS='-fno-exceptions -fno-rtti', CXXFLAGS='-fno-exceptions -fno-rtti',
LINKFLAGS='-nostdlib -lgcc') LINKFLAGS='-nostdlib -lgcc')
# Global constructor files. These must be linked IN THIS ORDER.
def crtfile_path(name):
cmd = shlex.split(env.subst('$CC $CCFLAGS $CFLAGS -print-file-name={}'.format(name)))
return subprocess.check_output(cmd).strip()
crtbegin_file = Command('crtbegin.o', [], Copy('$TARGET', crtfile_path('crtbegin.o')))
crtend_file = Command('crtend.o', [], Copy('$TARGET', crtfile_path('crtend.o')))
crtinit_files = ['crti.s', crtbegin_file]
crtfini_files = [crtend_file, 'crtn.s']
linker_script = File('linker.ld') linker_script = File('linker.ld')
kernel = Program('polka.bin', files, LINKFLAGS='-T {}'.format(linker_script.path)) kernel = Program('polka.bin', crtinit_files + files + crtfini_files, LINKFLAGS='-T {}'.format(linker_script.path))
Depends(kernel, linker_script) Depends(kernel, linker_script)
Alias('kernel', kernel) Alias('kernel', kernel)