diff --git a/Makefile b/Makefile index e5fef1f..b75f318 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ LD:=$(ENV)/$(TARGET)-ld CFLAGS:=-Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -std=c99 -g CFLAGS+=-I ./include +CXFLAGS:= -Wall -Werror -nostdlib -fno-builtin -nostartfiles -I ./include +CXFLAGS+= -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector LFLAGS:=-nostdlib -nostartfiles -nodefaultlibs .PHONY: all clean kernel.bin emulate hdd.img @@ -34,20 +36,28 @@ obj/src/%.o : src/%.c @mkdir -p obj/src/$*.o @rmdir obj/src/$*.o @$(CC) $(CFLAGS) -c src/$*.c -o obj/src/$*.o + +obj/src/%.xo : src/%.cpp + @echo "[i] Compiling $*.cpp ..." + @mkdir -p obj/src/$*.xo + @rmdir obj/src/$*.xo + @$(CX) $(CXFLAGS) -c src/$*.cpp -o obj/src/$*.xo TIER0SRC := $(shell find src/Tier0 -mindepth 1 -maxdepth 3 -name "*.c") TIER0SRC += $(shell find src/Tier0 -mindepth 1 -maxdepth 3 -name "*.asm") - TIER0OBJ := $(patsubst %.c,%.o,$(TIER0SRC)) TIER0OBJ := $(patsubst %.asm,%.nao,$(TIER0OBJ)) - TIER0 := $(foreach i, $(TIER0OBJ), obj/$(i)) - Tier0: $(TIER0) -kernel.bin: Tier0 +TIER1SRC := $(shell find src/Tier1 -mindepth 1 -maxdepth 3 -name "*.cpp") +TIER1OBJ := $(patsubst %.cpp,%.xo,$(TIER1SRC)) +TIER1 := $(foreach i, $(TIER1OBJ), obj/$(i)) +Tier1: $(TIER1) + +kernel.bin: Tier0 Tier1 @echo "[i] Linking kernel.bin..." - @$(LD) -T src/kernel.ld -o kernel.bin $(TIER0) + @$(LD) -T src/kernel.ld -o kernel.bin $(TIER0) $(TIER1) hdd.img: kernel.bin @echo "[i] Creating HDD image..." diff --git a/include/Tier0/cpp.h b/include/Tier0/cpp.h new file mode 100644 index 0000000..2ae45a9 --- /dev/null +++ b/include/Tier0/cpp.h @@ -0,0 +1,13 @@ +#ifndef __CPP_H__ +#define __CPP_H__ + +#include "types.h" + +void cpp_call_ctors(void); +void cpp_start_ckernel(void); + +void __cxa_pure_virtual(); +int __cxa_atexit(void (*f)(void *), void *objptr, void *dso); +void __cxa_finalize(void *f); + +#endif diff --git a/include/Tier0/kstdio.h b/include/Tier0/kstdio.h index f448cb9..c2726c6 100644 --- a/include/Tier0/kstdio.h +++ b/include/Tier0/kstdio.h @@ -8,14 +8,14 @@ void koutb(u16 Port, u8 Data); u8 kinb(u16 Port); void kio_wait(void); -u32 kstrlen(s8 *szString); +u32 kstrlen(const s8 *szString); void kmove_cursor(u8 X, u8 Y); -void kputs(s8 *szString); -void kputch(s8 Character); +void kputs(const s8 *szString); +void kputch(const s8 Character); void kclear(void); -void kprint(s8 *szString); +void kprint(const s8 *szString); void kputi(s32 Number); -void kprintf(s8 *Format, ...); +void kprintf(const s8 *Format, ...); void kdump(u8 *bData, u32 Length); void kprint_hex(u32 Number); s32 kmemcmp(u8 *MemA, u8 *MemB, u32 Length); diff --git a/include/Tier1/CKernel.h b/include/Tier1/CKernel.h new file mode 100644 index 0000000..2efe4b5 --- /dev/null +++ b/include/Tier1/CKernel.h @@ -0,0 +1,21 @@ +#ifndef __CKERNEL_H__ +#define __CKERNEL_H__ + +#include "types.h" +#include "Tier1/CLogger.h" + +#define CKERNEL_MAGIC 0x8BA67FE9 + +namespace cb { + class CKernel { + public: + CKernel(void); + void Start(void); + CLogger &Logger(void); + private: + u32 m_Magic; + CLogger *m_Logger; + }; +}; + +#endif diff --git a/include/Tier1/CLogger.h b/include/Tier1/CLogger.h new file mode 100644 index 0000000..fb23f98 --- /dev/null +++ b/include/Tier1/CLogger.h @@ -0,0 +1,28 @@ +#ifndef __CLOGGER_H__ +#define __CLOGGER_H__ + +#include "types.h" + +namespace cb { + class CHexNumber { + public: + CHexNumber(const u32 Data); + u32 Get(void); + private: + u32 m_Data; + }; + class CLogger { + public: + CLogger(void); + CLogger &operator << (const s8 *Data); + CLogger &operator << (const u32 Data); + CLogger &operator << (const s32 Data); + CLogger &operator << (CHexNumber &Data); + void Flush(void); + private: + bool m_Flushed; + void Prefix(void); + }; +}; + +#endif diff --git a/src/Tier0/cpp.c b/src/Tier0/cpp.c index 742bdf6..01512dd 100644 --- a/src/Tier0/cpp.c +++ b/src/Tier0/cpp.c @@ -1 +1,39 @@ // Basically stuff that is needed to go into C++ Land + +#include "Tier0/cpp.h" +#include "Tier0/kstdio.h" + +extern u32 g_start_ctors; +extern u32 g_end_ctors; +void CKernelStart(void); + +void cpp_call_ctors(void) +{ + u32 Number = ((void *)&g_end_ctors - (void *)&g_start_ctors) / 4; + kprintf("[i] Calling %i constructors before jumping to Tier1..\n", Number); + for(u32 *C = (u32*)&g_start_ctors; C < (u32*)&g_end_ctors; ++C) + { + ((void (*) (void)) (*C)) (); + } +} + +void cpp_start_ckernel(void) +{ + CKernelStart(); +} + +void __cxa_pure_virtual() +{ + kprintf("[e] A pure virtual call happened. WTF?\n"); +} + +int __cxa_atexit(void (*f)(void *), void *objptr, void *dso) +{ + // Do nothing, for now. + return 0; +} + +void __cxa_finalize(void *f) +{ + // -- " -- " -- +} diff --git a/src/Tier0/kmain.c b/src/Tier0/kmain.c index 7396f03..cb22604 100644 --- a/src/Tier0/kmain.c +++ b/src/Tier0/kmain.c @@ -10,6 +10,7 @@ #include "Tier0/kbd_layout.h" #include "Tier0/physical_alloc.h" #include "Tier0/heap.h" +#include "Tier0/cpp.h" void interrupts_irq_sample(void); @@ -66,6 +67,10 @@ void kmain(void *MultibootHeader, u32 Magic) kprintf("[i] Hardware interrupts are now enabled.\n"); heap_init_simple(); - + + cpp_call_ctors(); + cpp_start_ckernel(); + + kprintf("[i] Returned from Tier1, sleeping forever.\n"); LOOPFOREVER; } diff --git a/src/Tier0/kstdio.c b/src/Tier0/kstdio.c index 934878c..a000853 100644 --- a/src/Tier0/kstdio.c +++ b/src/Tier0/kstdio.c @@ -54,7 +54,7 @@ void kputi(s32 Number) } } -void kprintf(s8 *szFormat, ...) +void kprintf(const s8 *szFormat, ...) { va_list ap; va_start(ap, szFormat); @@ -120,7 +120,7 @@ void kscroll_up(void) } } -u32 kstrlen(s8 *szString) +u32 kstrlen(const s8 *szString) { const s8 *s; for (s = szString; *s; ++s) @@ -203,7 +203,7 @@ void kputch(s8 Character) } } -void kputs(s8 *szString) +void kputs(const s8 *szString) { while (*szString != 0) { @@ -212,7 +212,7 @@ void kputs(s8 *szString) } } -void kprint(s8 *szString) +void kprint(const s8 *szString) { kputs(szString); } diff --git a/src/Tier1/CKernel.cpp b/src/Tier1/CKernel.cpp new file mode 100644 index 0000000..08c2cff --- /dev/null +++ b/src/Tier1/CKernel.cpp @@ -0,0 +1,42 @@ +#include "Tier1/CKernel.h" +using namespace cb; + +CKernel g_Kernel; + +extern "C" { + #include "Tier0/kstdio.h" + + void CKernelStart(void) + { + g_Kernel.Start(); + } +} + +CKernel::CKernel(void) +{ + m_Magic = CKERNEL_MAGIC; +} + +CLogger &CKernel::Logger(void) +{ + return *m_Logger; +} + +void CKernel::Start(void) +{ + kprintf("[i] Hello from C++ land!\n"); + + if (m_Magic != CKERNEL_MAGIC) + { + kprintf("[e] Error! My constructor wasn't called properly.\n"); + return; + } + + m_Logger = new CLogger(); + + Logger() << "FUCK YEAH C++!"; + Logger().Flush(); + + for (;;) {} +} + diff --git a/src/Tier1/CLogger.cpp b/src/Tier1/CLogger.cpp new file mode 100644 index 0000000..6fc5394 --- /dev/null +++ b/src/Tier1/CLogger.cpp @@ -0,0 +1,58 @@ +#include "Tier1/CLogger.h" +using namespace cb; + +extern "C" { + #include "Tier0/kstdio.h" +} + +CHexNumber::CHexNumber(const u32 Data) +{ + m_Data = Data; +} + +u32 CHexNumber::Get(void) +{ + return m_Data; +} + +CLogger::CLogger(void) +{ + kprintf(":: CLogger Initialized.\n"); + m_Flushed = true; +} + +CLogger &CLogger::operator << (const s8 *Data) +{ + Prefix(); + kprintf("%s", Data); + return *this; +} + +CLogger &CLogger::operator << (const u32 Data) +{ + Prefix(); + kprintf("%u", Data); + return *this; +} + +CLogger &CLogger::operator << (const s32 Data) +{ + Prefix(); + kprintf("%i", Data); + return *this; +} + +void CLogger::Prefix(void) +{ + if (m_Flushed) + { + m_Flushed = false; + kprintf(":: "); + } +} + +void CLogger::Flush(void) +{ + kprintf("\n"); + m_Flushed = true; +} diff --git a/src/Tier1/new.cpp b/src/Tier1/new.cpp new file mode 100644 index 0000000..50547a5 --- /dev/null +++ b/src/Tier1/new.cpp @@ -0,0 +1,26 @@ +#include "types.h" +extern "C" { + #include "Tier0/heap.h" +}; + +typedef long unsigned int size_t; + +void *operator new(size_t size) +{ + return kmalloc(size); +} + +void *operator new[](size_t size) +{ + return kmalloc(size); +} + +void operator delete(void *p) +{ + kfree(p); +} + +void operator delete[](void *p) +{ + kfree(p); +} diff --git a/src/kernel.ld b/src/kernel.ld index 1d3fdd1..7aabdca 100644 --- a/src/kernel.ld +++ b/src/kernel.ld @@ -23,15 +23,25 @@ SECTIONS .text : AT(g_section_code) { g_section_code = . - VMA; - *(.text) + *(.text*) + *(.gnu.linkonce.t*) + + . = ALIGN(0x4); + g_start_ctors = .; + *(.ctors) + g_end_ctors = .; + . = ALIGN(0x1000); } .data : AT(g_section_data) { g_section_data = . - VMA; - *(.data) + *(.data*) + *(.gnu.linkonce.d*) *(.rodata*) + *(.gnu.linkonce.r*) + . = ALIGN(0x1000); } @@ -44,5 +54,11 @@ SECTIONS } . = ALIGN(0x1000); + + /DISCARD/ : + { + *(.comment) + *(.eh_frame) + } }