summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Johnson <[email protected]>2025-07-01 10:33:05 -0400
committerSamuel Johnson <[email protected]>2025-07-01 10:33:05 -0400
commit571a656a6bd9b4b9d5c595c578d15ba79bb19ef7 (patch)
tree46f75b47f4edab4281de14ffa1c4a91a5a84f8f1
parent12fd3a91f138bf90520134682e38bf3b0341e660 (diff)
Add serial loggingHEADtrunkdev
-rw-r--r--.gitignore2
-rw-r--r--Makefile32
-rw-r--r--compile_commands.json113
-rw-r--r--kernel/amd64/io/com1.cxx44
-rw-r--r--kernel/amd64/io/com1.h17
-rw-r--r--kernel/amd64/io/ports.S24
-rw-r--r--kernel/amd64/io/ports.h12
-rw-r--r--kernel/entry.cxx23
-rw-r--r--kernel/io/font.h15
-rw-r--r--kernel/io/logger/base.cxx11
-rw-r--r--kernel/io/logger/base.h31
-rw-r--r--kernel/io/logger/base.ipp145
-rw-r--r--kernel/io/psf2.h37
-rw-r--r--kernel/io/tamsyn.psfbin0 -> 4677 bytes
-rw-r--r--kernel/utils.cxx27
-rw-r--r--kernel/utils.h21
-rw-r--r--version.h9
17 files changed, 554 insertions, 9 deletions
diff --git a/.gitignore b/.gitignore
index ac1fdbb..de9b66d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.cache/
bin/
iso/
toolchain/
@@ -5,4 +6,5 @@ vendor/
*.iso
*.o
+*.d
*.swp
diff --git a/Makefile b/Makefile
index 0b534fb..e4c0022 100644
--- a/Makefile
+++ b/Makefile
@@ -22,9 +22,21 @@ KERNEL := bin/core
K_OBJS := \
kernel/entry.o \
kernel/cxx/constructors.o \
- kernel/cxx/icxxabi.o
+ kernel/cxx/icxxabi.o \
+ kernel/utils.o \
+ kernel/io/logger/base.o \
+ kernel/amd64/io/com1.o
+K_SRCS := $(patsubst %.o,%.cxx,$(K_OBJS))
+K_ASM_OBJS := \
+ kernel/amd64/io/ports.o
K_LINKSCRIPT := kernel/ldscript
+CPPSTDDIRS := \
+ vendor/x86_64-elf/include/c++/14.2.0 \
+ vendor/x86_64-elf/include/c++/14.2.0/x86_64-elf \
+ vendor/x86_64-elf/include/c++/14.2.0/backward
+CPPSTD := $(addprefix -I ,$(CPPSTDDIRS))
+
BINARIES := \
$(KERNEL)
@@ -35,10 +47,11 @@ OVMF_ROOT := /usr/share/qemu
all: hinterOS.iso
run:
- qemu-system-x86_64 --bios $(OVMF_ROOT)/ovmf-x86_64.bin -cdrom hinterOS.iso
+ qemu-system-x86_64 --serial stdio --bios $(OVMF_ROOT)/ovmf-x86_64.bin -cdrom hinterOS.iso
clean:
- find kernel -type f -name '*.o' -exec rm {} +
+ - find kernel -type f -name '*.d' -exec rm {} +
- rm hinterOS.iso
- rm $(BINARIES)
@@ -59,10 +72,19 @@ hinterOS.iso: $(BINARIES)
iso -o $@
vendor/limine/limine bios-install $@
-$(KERNEL): $(K_OBJS)
+$(KERNEL): $(K_OBJS) $(K_ASM_OBJS)
rm -rf bin
mkdir -p bin
- $(LD) -o $@ -T$(K_LINKSCRIPT) $^
+ $(LD) -o $@ -T $(K_LINKSCRIPT) $^
+
+.SECONDEXPANSION:
+$(K_OBJS): %.o: %.cxx %.d
+ $(CC) -c $(CFLAGS) -MT $@ -MMD -MP -MF $(basename $<).d -I kernel $(CPPSTD) $< -o $@
-$(K_OBJS): %.o: %.cxx
+$(K_ASM_OBJS): %.o: %.S
$(CC) -c $(CFLAGS) $^ -o $@
+
+DEPFILES := $(K_SRCS:%.cxx=%.d)
+$(DEPFILES):
+
+-include $(wildcard $(DEPFILES))
diff --git a/compile_commands.json b/compile_commands.json
new file mode 100644
index 0000000..ad143de
--- /dev/null
+++ b/compile_commands.json
@@ -0,0 +1,113 @@
+[
+ {
+ "arguments": [
+ "vendor/bin/x86_64-elf-g++",
+ "-c",
+ "-g",
+ "-O2",
+ "-pipe",
+ "-Wall",
+ "-Wextra",
+ "-std=c++17",
+ "-ffreestanding",
+ "-mno-red-zone",
+ "-msoft-float",
+ "-mno-sse",
+ "-fno-stack-protector",
+ "-fno-stack-check",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-ffunction-sections",
+ "-fdata-sections",
+ "-mcmodel=kernel",
+ "-I",
+ "kernel",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0/x86_64-elf",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0/backward",
+ "-o",
+ "kernel/entry.o",
+ "kernel/entry.cxx"
+ ],
+ "directory": "/home/samuelj/Documents/repos/hinteros",
+ "file": "/home/samuelj/Documents/repos/hinteros/kernel/entry.cxx",
+ "output": "/home/samuelj/Documents/repos/hinteros/kernel/entry.o"
+ },
+ {
+ "arguments": [
+ "vendor/bin/x86_64-elf-g++",
+ "-c",
+ "-g",
+ "-O2",
+ "-pipe",
+ "-Wall",
+ "-Wextra",
+ "-std=c++17",
+ "-ffreestanding",
+ "-mno-red-zone",
+ "-msoft-float",
+ "-mno-sse",
+ "-fno-stack-protector",
+ "-fno-stack-check",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-ffunction-sections",
+ "-fdata-sections",
+ "-mcmodel=kernel",
+ "-I",
+ "kernel",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0/x86_64-elf",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0/backward",
+ "-o",
+ "kernel/cxx/constructors.o",
+ "kernel/cxx/constructors.cxx"
+ ],
+ "directory": "/home/samuelj/Documents/repos/hinteros",
+ "file": "/home/samuelj/Documents/repos/hinteros/kernel/cxx/constructors.cxx",
+ "output": "/home/samuelj/Documents/repos/hinteros/kernel/cxx/constructors.o"
+ },
+ {
+ "arguments": [
+ "vendor/bin/x86_64-elf-g++",
+ "-c",
+ "-g",
+ "-O2",
+ "-pipe",
+ "-Wall",
+ "-Wextra",
+ "-std=c++17",
+ "-ffreestanding",
+ "-mno-red-zone",
+ "-msoft-float",
+ "-mno-sse",
+ "-fno-stack-protector",
+ "-fno-stack-check",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-ffunction-sections",
+ "-fdata-sections",
+ "-mcmodel=kernel",
+ "-I",
+ "kernel",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0/x86_64-elf",
+ "-I",
+ "vendor/x86_64-elf/include/c++/14.2.0/backward",
+ "-o",
+ "kernel/cxx/icxxabi.o",
+ "kernel/cxx/icxxabi.cxx"
+ ],
+ "directory": "/home/samuelj/Documents/repos/hinteros",
+ "file": "/home/samuelj/Documents/repos/hinteros/kernel/cxx/icxxabi.cxx",
+ "output": "/home/samuelj/Documents/repos/hinteros/kernel/cxx/icxxabi.o"
+ }
+]
diff --git a/kernel/amd64/io/com1.cxx b/kernel/amd64/io/com1.cxx
new file mode 100644
index 0000000..fc67b65
--- /dev/null
+++ b/kernel/amd64/io/com1.cxx
@@ -0,0 +1,44 @@
+#include <amd64/io/com1.h>
+#include <amd64/io/ports.h>
+#include <utils.h>
+
+#define COM1 0x3f8
+
+int is_transmit_empty ()
+{
+ return hos::io::inb(COM1 + 5) & 0x20;
+}
+
+namespace hos::io
+{
+ com_logger::com_logger (enum log_level level)
+ : logger (level)
+ {
+ outb(COM1 + 1, 0x00);
+ outb(COM1 + 3, 0x80);
+ outb(COM1 + 0, 0x03);
+ outb(COM1 + 1, 0x00);
+ outb(COM1 + 3, 0x03);
+ outb(COM1 + 2, 0xc7);
+ outb(COM1 + 4, 0x0b);
+ outb(COM1 + 4, 0x1e);
+ outb(COM1 + 0, 0xae);
+
+ if (inb(COM1 + 0) != 0xae)
+ {
+ return;
+ }
+
+ outb(COM1 + 4, 0x0f);
+ }
+
+ void com_logger::flush ()
+ {
+ std::size_t len = strlen(this->buffer);
+ for (std::size_t i = 0; i < len; i++)
+ {
+ while (is_transmit_empty() == 0);
+ outb(COM1 + 0, this->buffer[i]);
+ }
+ }
+}
diff --git a/kernel/amd64/io/com1.h b/kernel/amd64/io/com1.h
new file mode 100644
index 0000000..0ee04ac
--- /dev/null
+++ b/kernel/amd64/io/com1.h
@@ -0,0 +1,17 @@
+#ifndef HOS_AMD64_IO_COM1_H
+#define HOS_AMD64_IO_COM1_H
+
+#include <amd64/io/ports.h>
+#include <io/logger/base.h>
+
+namespace hos::io
+{
+ class com_logger : public hos::io::logger<com_logger>
+ {
+ public:
+ com_logger (enum log_level level);
+ void flush ();
+ };
+}
+
+#endif
diff --git a/kernel/amd64/io/ports.S b/kernel/amd64/io/ports.S
new file mode 100644
index 0000000..37301a4
--- /dev/null
+++ b/kernel/amd64/io/ports.S
@@ -0,0 +1,24 @@
+.section .text
+.global inb, outb
+
+inb:
+ push %rbp
+ mov %rsp, %rbp
+ sub $0x10, %rsp
+ mov %rdi, %rdx
+ xor %rax, %rax
+ in (%dx), %al
+ add $0x10, %rsp
+ pop %rbp
+ ret
+
+outb:
+ push %rbp
+ mov %rsp, %rbp
+ sub $0x10, %rsp
+ mov %rdi, %rdx
+ mov %rsi, %rax
+ out %al, (%dx)
+ add $0x10, %rsp
+ pop %rbp
+ ret
diff --git a/kernel/amd64/io/ports.h b/kernel/amd64/io/ports.h
new file mode 100644
index 0000000..6de2acb
--- /dev/null
+++ b/kernel/amd64/io/ports.h
@@ -0,0 +1,12 @@
+#ifndef HOS_AMD64_IO_PORTS_H
+#define HOS_AMD64_IO_PORTS_H
+
+#include <cstdint>
+
+namespace hos::io
+{
+ extern "C" std::uint8_t inb (std::uint16_t port);
+ extern "C" void outb (std::uint16_t port, std::uint8_t value);
+}
+
+#endif
diff --git a/kernel/entry.cxx b/kernel/entry.cxx
index b5bc210..643fbc0 100644
--- a/kernel/entry.cxx
+++ b/kernel/entry.cxx
@@ -1,6 +1,15 @@
#include "../vendor/limine/limine.h"
+#include "../version.h"
+
+#include <io/logger/base.h>
#include <cstdint>
+#if defined (__x86_64__)
+#include <amd64/io/com1.h>
+#endif
+
+using namespace hos::io;
+
__attribute__ ((used, section(".requests")))
static volatile LIMINE_BASE_REVISION(3);
@@ -30,20 +39,26 @@ void init (void);
extern "C" void _launch (void);
void _launch (void)
{
+ // Global C++ Constructors
+ init();
+
+ logger<com_logger> logger(log_level::DEBUG);
+ logger.write(log_level::INFO, "Welcome to HinterOS %s!", HOS_CORE_VERSION);
+
if (LIMINE_BASE_REVISION_SUPPORTED == false)
{
+ logger.write(log_level::FATAL, "Limine revision mismatch.");
hcf();
}
+ logger.write(log_level::DEBUG, "Limine... ok");
+
struct limine_framebuffer *fb = framebuffer_request.response->framebuffers[0];
for (std::size_t i = 0; i < (fb->width - 1) * (fb->height - 1); i += 2)
{
volatile std::uint32_t *fbptr = static_cast<std::uint32_t *>(fb->address);
- fbptr[i] = 0xffffff;
+ fbptr[i] = 0xffffff00;
}
- // Global C++ constructors
- init();
-
hcf();
}
diff --git a/kernel/io/font.h b/kernel/io/font.h
new file mode 100644
index 0000000..e4f72ca
--- /dev/null
+++ b/kernel/io/font.h
@@ -0,0 +1,15 @@
+#ifndef HOS_IO_FONT_H
+#define HOS_IO_FONT_H
+
+#include <cstdint>
+
+namespace hos::io
+{
+ class font
+ {
+ public:
+ virtual void write (unsigned char character, void *fb_addr, std::uint16_t bpp) = 0;
+ };
+}
+
+#endif
diff --git a/kernel/io/logger/base.cxx b/kernel/io/logger/base.cxx
new file mode 100644
index 0000000..bb1e3c4
--- /dev/null
+++ b/kernel/io/logger/base.cxx
@@ -0,0 +1,11 @@
+#include <io/logger/base.ipp>
+
+#if defined (__x86_64__)
+#include <amd64/io/com1.h>
+
+namespace hos::io
+{
+ template class logger<com_logger>;
+}
+
+#endif
diff --git a/kernel/io/logger/base.h b/kernel/io/logger/base.h
new file mode 100644
index 0000000..7aa9e2d
--- /dev/null
+++ b/kernel/io/logger/base.h
@@ -0,0 +1,31 @@
+#ifndef HOS_IO_BASE_H
+#define HOS_IO_BASE_H
+
+namespace hos::io
+{
+ enum log_level
+ {
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR,
+ FATAL
+ };
+
+ /// Ah, the glorious CRTP...
+ template <typename concrete_logger>
+ class logger
+ {
+ public:
+ logger (enum log_level level);
+
+ void set_level (enum log_level level);
+ void write (enum log_level level, const char *message, ...);
+ protected:
+ char buffer[512];
+ private:
+ enum log_level level;
+ };
+}
+
+#endif
diff --git a/kernel/io/logger/base.ipp b/kernel/io/logger/base.ipp
new file mode 100644
index 0000000..b48a132
--- /dev/null
+++ b/kernel/io/logger/base.ipp
@@ -0,0 +1,145 @@
+#ifndef HOS_IO_BASE_IMPL
+#define HOS_IO_BASE_IMPL
+
+#include <io/logger/base.h>
+#include <utils.h>
+
+#include <stdarg.h>
+
+namespace hos::io
+{
+ template <typename concrete_logger>
+ logger<concrete_logger>::logger (enum log_level level)
+ {
+ this->set_level(level);
+ }
+
+ template <typename concrete_logger>
+ void logger<concrete_logger>::set_level (enum log_level level)
+ {
+ this->level = level;
+ }
+
+ template <typename concrete_logger>
+ void logger<concrete_logger>::write (enum log_level level, const char *message, ...)
+ {
+ if (level < this->level)
+ {
+ return;
+ }
+
+ char *bufferptr = this->buffer;
+ memset(bufferptr, 0, sizeof(this->buffer));
+
+ const char *logtypes[] = {
+ "DEBUG: ",
+ "INFO: ",
+ "WARN: ",
+ "ERROR: ",
+ "FATAL: "
+ };
+
+ int len = 0;
+ switch (level)
+ {
+ case log_level::DEBUG: {
+ len = strlen(logtypes[0]);
+
+ memcpy(bufferptr, logtypes[0], len);
+ bufferptr += len;
+ break;
+ }
+ case log_level::INFO: {
+ len = strlen(logtypes[1]);
+
+ memcpy(bufferptr, logtypes[1], len);
+ bufferptr += len;
+ break;
+ }
+ case log_level::WARN: {
+ len = strlen(logtypes[2]);
+
+ memcpy(bufferptr, logtypes[2], len);
+ bufferptr += len;
+ break;
+ }
+ case log_level::ERROR: {
+ len = strlen(logtypes[3]);
+
+ memcpy(bufferptr, logtypes[3], len);
+ bufferptr += len;
+ break;
+ }
+ case log_level::FATAL: {
+ len = strlen(logtypes[4]);
+
+ memcpy(bufferptr, logtypes[4], len);
+ bufferptr += len;
+ break;
+ }
+ }
+
+ len = strlen(message);
+ if (bufferptr + len >= this->buffer + 510) {
+ const char failed[] = "LOGGER: Message longer than display buffer.";
+ memcpy(bufferptr, failed, strlen(failed));
+ static_cast<concrete_logger*>(this)->flush();
+ }
+
+ va_list args;
+ va_start(args, message);
+
+ char temp_buffer[this->buffer + 510 - bufferptr];
+ char *tempptr = temp_buffer;
+ memset(tempptr, 0, sizeof(temp_buffer));
+
+ char next;
+ while ((next = *message++) != 0)
+ {
+ if (next == '%')
+ {
+ next = *message++;
+ switch (next)
+ {
+ case 'c': {
+ char c = va_arg(args, int);
+
+ if (!((tempptr + 1) - temp_buffer > (long int) sizeof(temp_buffer)))
+ {
+ memcpy(tempptr, &c, 1);
+ tempptr++;
+ }
+
+ break;
+ }
+ case 's': {
+ char *string = va_arg(args, char *);
+
+ len = strlen(string);
+ if (!((tempptr + len) - temp_buffer > (long int) sizeof(temp_buffer)))
+ {
+ memcpy(tempptr, string, len);
+ tempptr += len;
+ }
+
+ break;
+ }
+ }
+ } else {
+ memcpy(tempptr, &next, 1);
+ tempptr++;
+ }
+ }
+
+ va_end(args);
+
+ len = strlen(temp_buffer);
+ memcpy(bufferptr, temp_buffer, len);
+ bufferptr += len;
+
+ memcpy(bufferptr, "\n", 1);
+ static_cast<concrete_logger*>(this)->flush();
+ }
+}
+
+#endif
diff --git a/kernel/io/psf2.h b/kernel/io/psf2.h
new file mode 100644
index 0000000..e8dda44
--- /dev/null
+++ b/kernel/io/psf2.h
@@ -0,0 +1,37 @@
+#ifndef HOS_IO_PSF2_H
+#define HOS_IO_PSF2_H
+
+#include <cstdint>
+#include <io/font.h>
+
+#define PSF2_MAGIC0 0x72
+#define PSF2_MAGIC1 0xb5
+#define PSF2_MAGIC2 0x4a
+#define PSF2_MAGIC3 0x86
+
+#define PSF2_HAS_UNICODE_TABLE 0x01
+
+#define PSF2_SEPARATOR 0xff
+#define PSF2_STARTSEQ 0xfe
+
+namespace hos::io
+{
+ class psf2 : public font
+ {
+ public:
+ psf2 (void *font_start_addr);
+
+ void write (unsigned char character, void *fb_addr, std::uint16_t bpp);
+ private:
+ unsigned char magic[4];
+ unsigned int version;
+ unsigned int header_size;
+ unsigned int flags;
+ unsigned int length;
+ unsigned int charsize;
+ unsigned int height;
+ unsigned int width;
+ };
+}
+
+#endif
diff --git a/kernel/io/tamsyn.psf b/kernel/io/tamsyn.psf
new file mode 100644
index 0000000..6fd82c1
--- /dev/null
+++ b/kernel/io/tamsyn.psf
Binary files differ
diff --git a/kernel/utils.cxx b/kernel/utils.cxx
new file mode 100644
index 0000000..8a131d1
--- /dev/null
+++ b/kernel/utils.cxx
@@ -0,0 +1,27 @@
+#include <utils.h>
+
+void *memset (void *bufferptr, int value, std::size_t size)
+{
+ unsigned char *buffer = (unsigned char *) bufferptr;
+
+ for (std::size_t i = 0; i < size; i++)
+ {
+ buffer[i] = (unsigned char) value;
+ }
+
+ return bufferptr;
+}
+
+void *memcpy (void *destptr, const void *srcptr, std::size_t size)
+{
+ unsigned char *dest = (unsigned char *) destptr;
+ const unsigned char *src = (const unsigned char *) srcptr;
+
+ for (std::size_t i = 0; i < size; i++)
+ {
+ dest[i] = src[i];
+ }
+
+ return destptr;
+}
+
diff --git a/kernel/utils.h b/kernel/utils.h
new file mode 100644
index 0000000..aaf342f
--- /dev/null
+++ b/kernel/utils.h
@@ -0,0 +1,21 @@
+#ifndef HOS_UTILS_H
+#define HOS_UTILS_H
+
+#include <cstddef>
+
+void *memset (void *buffer, int value, std::size_t size);
+void *memcpy (void *destptr, const void *srcptr, std::size_t size);
+
+constexpr std::size_t strlen (const char *in)
+{
+ std::size_t len = 0;
+
+ while (in[len])
+ {
+ len++;
+ }
+
+ return len;
+}
+
+#endif
diff --git a/version.h b/version.h
new file mode 100644
index 0000000..ffb2783
--- /dev/null
+++ b/version.h
@@ -0,0 +1,9 @@
+#ifndef HOS_SUITE_VERSION_H
+#define HOS_SUITE_VERSION_H
+
+#define HOS_CORE_MAJOR "0"
+#define HOS_CORE_MINOR "1"
+#define HOS_CORE_PATCH "0"
+#define HOS_CORE_VERSION HOS_CORE_MAJOR "." HOS_CORE_MINOR "." HOS_CORE_PATCH
+
+#endif