about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2020-06-22 17:06:46 +0200
committerYour Name <you@example.com>2020-06-22 17:06:46 +0200
commit6bacc4f30752e49733d6efb219d58eb4745a49a9 (patch)
treeb1459f86e5b5b0c2ad2fe81e1b96ad588de463d7
downloadpOS-6bacc4f30752e49733d6efb219d58eb4745a49a9.tar.gz
pOS-6bacc4f30752e49733d6efb219d58eb4745a49a9.tar.bz2
pOS-6bacc4f30752e49733d6efb219d58eb4745a49a9.zip
Git commit clean
-rw-r--r--.gitignore10
-rw-r--r--Makefile9
-rw-r--r--README.md7
-rw-r--r--TODO4
-rw-r--r--src/.Makefile4
-rwxr-xr-xsrc/.build.sh17
-rw-r--r--src/bootloader/boot.s33
-rw-r--r--src/linker.ld28
-rw-r--r--src/pOS/arch/x86/kernel/debug.cpp27
-rw-r--r--src/pOS/arch/x86/kernel/rtc.cpp36
-rw-r--r--src/pOS/arch/x86/kernel/serial.cpp64
-rw-r--r--src/pOS/arch/x86/kernel/system.cpp21
-rw-r--r--src/pOS/arch/x86/kernel/time.cpp134
-rw-r--r--src/pOS/arch/x86/kernel/tty.cpp111
-rw-r--r--src/pOS/arch/x86/libc/math.c22
-rw-r--r--src/pOS/arch/x86/libc/stdio/printf.cpp37
-rw-r--r--src/pOS/arch/x86/libc/stdio/putc.cpp6
-rw-r--r--src/pOS/arch/x86/libc/stdio/sprintf.cpp16
-rw-r--r--src/pOS/arch/x86/libc/stdlib/atoi.cpp34
-rw-r--r--src/pOS/arch/x86/libc/stdlib/itoa.cpp31
-rw-r--r--src/pOS/arch/x86/libc/string/memcpy.cpp10
-rw-r--r--src/pOS/arch/x86/libc/string/memset.cpp11
-rw-r--r--src/pOS/arch/x86/libc/string/strlen.cpp9
-rw-r--r--src/pOS/arch/x86/libc/string/strncpy.cpp14
-rw-r--r--src/pOS/include/kernel/debug.h11
-rw-r--r--src/pOS/include/kernel/pOS.h7
-rw-r--r--src/pOS/include/kernel/rtc.h30
-rw-r--r--src/pOS/include/kernel/serial.h24
-rw-r--r--src/pOS/include/kernel/system.h15
-rw-r--r--src/pOS/include/kernel/time.h43
-rw-r--r--src/pOS/include/kernel/tty.h29
-rw-r--r--src/pOS/include/kernel/vga.h44
-rw-r--r--src/pOS/include/libc/assert.h14
-rw-r--r--src/pOS/include/libc/math.h8
-rw-r--r--src/pOS/include/libc/printf_internal.h409
-rw-r--r--src/pOS/include/libc/stddef.h9
-rw-r--r--src/pOS/include/libc/stdint.h16
-rw-r--r--src/pOS/include/libc/stdio.h24
-rw-r--r--src/pOS/include/libc/stdlib.h11
-rw-r--r--src/pOS/include/libc/string.h12
-rw-r--r--src/pOS/kernel/kernel.cpp25
41 files changed, 1426 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ee55692
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+out/
+build/
+
+pOS.config
+pOS.creator
+pOS.creator.user
+pOS.cflags
+pOS.cxxflags
+pOS.files
+pOS.includes
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1dd6723
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+all: src/
+	cd src && make -f .Makefile && cd ..
+
+run: all
+	@echo -e "\033[32m"
+	@qemu-system-i386 -kernel out/pOS.bin -serial stdio
+	@echo -e "\033[0;39m"
+clean:
+	rm -rf out
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a0a81b3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# pOS - x86 Testing OS
+
+## Build
+`make`
+
+## Run
+`make run`
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..bc64800
--- /dev/null
+++ b/TODO
@@ -0,0 +1,4 @@
+[] Write x86 bootloader
+[] Add interrupts
+[] More cpp features
+[] Code cleanup
diff --git a/src/.Makefile b/src/.Makefile
new file mode 100644
index 0000000..e750f23
--- /dev/null
+++ b/src/.Makefile
@@ -0,0 +1,4 @@
+all: pOS.bin
+
+pOS.bin: ./.build.sh
+	./.build.sh
diff --git a/src/.build.sh b/src/.build.sh
new file mode 100755
index 0000000..fde3c02
--- /dev/null
+++ b/src/.build.sh
@@ -0,0 +1,17 @@
+out_dir="..\/out"
+include="-I pOS/include -I pOS/include/libc"
+
+mkdir $out_dir 2> /dev/null
+
+for f in $(find pOS/ -type f \( -iname \*.cpp -o -iname \*.c \))
+do
+	out_file=$(echo $f | sed 's/pOS/..\/out\/pOS/g' | sed 's/\.cpp/\.o/g' | sed 's/\.c/\.o/g')
+	mkdir -p $(dirname $out_file)
+	i686-elf-g++ $include -g -std=c++11 -c $f -o $out_file -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti
+done
+
+mkdir -p ../out/bootloader
+
+nasm -f elf32 bootloader/boot.s -o ../out/bootloader/boot.o
+
+i686-elf-g++ -T linker.ld -o ../out/pOS.bin -ffreestanding -O2 -nostdlib $(find ../out -type f -name "*.o") -lgcc
diff --git a/src/bootloader/boot.s b/src/bootloader/boot.s
new file mode 100644
index 0000000..0bb10d5
--- /dev/null
+++ b/src/bootloader/boot.s
@@ -0,0 +1,33 @@
+; Multiboot header
+MBALIGN  equ  1 << 0
+MEMINFO  equ  1 << 1
+FLAGS    equ  MBALIGN | MEMINFO
+MAGIC    equ  0x1BADB002
+CHECKSUM equ -(MAGIC + FLAGS)
+ 
+section .multiboot
+align 4
+	dd MAGIC
+	dd FLAGS
+	dd CHECKSUM
+ 
+; Setup stack
+section .bss
+align 16
+stack_bottom:
+resb 16384 ; 16 KiB
+stack_top:
+ 
+section .text
+global _start:function (_start.end - _start)
+_start:
+	; Initialize stack
+	mov esp, stack_top
+ 
+	extern kmain
+	call kmain
+ 
+	cli
+.inf:	hlt
+	jmp .inf
+.end:	
diff --git a/src/linker.ld b/src/linker.ld
new file mode 100644
index 0000000..141428c
--- /dev/null
+++ b/src/linker.ld
@@ -0,0 +1,28 @@
+ENTRY(_start)
+SECTIONS
+{
+	. = 1M;
+ 
+	/* Multiboot header */
+	.text BLOCK(4K) : ALIGN(4K)
+	{
+		*(.multiboot)
+		*(.text)
+	}
+ 
+	.rodata BLOCK(4K) : ALIGN(4K)
+	{
+		*(.rodata)
+	}
+ 
+	.data BLOCK(4K) : ALIGN(4K)
+	{
+		*(.data)
+	}
+ 
+	.bss BLOCK(4K) : ALIGN(4K)
+	{
+		*(COMMON)
+		*(.bss)
+	}
+} 
diff --git a/src/pOS/arch/x86/kernel/debug.cpp b/src/pOS/arch/x86/kernel/debug.cpp
new file mode 100644
index 0000000..43c81c7
--- /dev/null
+++ b/src/pOS/arch/x86/kernel/debug.cpp
@@ -0,0 +1,27 @@
+#include <kernel/debug.h>
+
+static void debugger_out(char c)
+{
+     Serial::serial_putch(c);
+}
+
+static void debugger_putch(char*&, char c) //wrapper so that we can sprintf
+{
+    debugger_out(c);
+}
+
+int dbgprint(const char* str, int len)
+{
+    for (int i = 0; i < len; ++i)
+        debugger_out(str[i]);
+    return 0;
+}
+
+int dbgprintf(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    int ret = printf_internal(debugger_putch, nullptr, fmt, ap);
+    va_end(ap);
+    return ret;
+}
diff --git a/src/pOS/arch/x86/kernel/rtc.cpp b/src/pOS/arch/x86/kernel/rtc.cpp
new file mode 100644
index 0000000..ab64a90
--- /dev/null
+++ b/src/pOS/arch/x86/kernel/rtc.cpp
@@ -0,0 +1,36 @@
+#include <kernel/rtc.h>
+
+int RTC::get_update_in_progress_flag(void)
+{
+      System::outb(CMOS_PORT, 0x0A);
+      return (System::inb(CMOS_DATA) & 0x80);
+}
+
+uint8_t RTC::read_cmos(uint8_t registr)
+{
+    uint8_t result;
+    System::outb(CMOS_PORT, registr);
+    do
+        result = System::inb(CMOS_DATA);
+    while(RTC::get_update_in_progress_flag());
+
+    System::outb(CMOS_PORT, 0x0B);
+    if(!(System::inb(CMOS_DATA) & 0x04)) //to binary
+        result = (result & 0x0F) + ((result/ 16) * 10);
+
+    return result;
+}
+
+timedate RTC::get_date(void)
+{
+    return timedate {
+                    RTC::read_cmos(CMOS_READ_SECOND),
+                    RTC::read_cmos(CMOS_READ_MINUTE),
+                    RTC::read_cmos(CMOS_READ_HOUR),
+                    RTC::read_cmos(CMOS_READ_DAY),
+                    RTC::read_cmos(CMOS_READ_MONTH),
+                    RTC::read_cmos(CMOS_READ_YEAR),
+                    CURRENT_CENTURY,
+                    CURRENT_MILLENNIUM
+                };
+}
diff --git a/src/pOS/arch/x86/kernel/serial.cpp b/src/pOS/arch/x86/kernel/serial.cpp
new file mode 100644
index 0000000..2dd0358
--- /dev/null
+++ b/src/pOS/arch/x86/kernel/serial.cpp
@@ -0,0 +1,64 @@
+#include <kernel/serial.h>
+
+int Serial::init_serial(uint16_t port)
+{
+   System::outb(port + 1, 0x00); //cli
+   System::outb(port + 3, 0x80);
+   System::outb(port + 0, 0x03);
+   System::outb(port + 1, 0x00);
+   System::outb(port + 3, 0x03);
+   System::outb(port + 2, 0xC7);
+   System::outb(port + 4, 0x0B); //sti
+
+   return 0;
+}
+
+int Serial::is_transmit_empty(uint16_t port)
+{
+   return System::inb(port + 5) & 0x20;
+}
+
+int Serial::write_serial(uint8_t data, uint16_t port)
+{
+   while (!is_transmit_empty(port));
+
+   System::outb(port, data);
+
+   return 0;
+}
+
+int Serial::serial_received(uint16_t port)
+{
+   return System::inb(port + 5) & 1;
+}
+
+uint8_t Serial::read_serial(uint16_t port)
+{
+   while (!serial_received(port));
+
+   return System::inb(port);
+}
+
+int Serial::serial_putch(char c)
+{
+    static bool serial_ready = false;
+    static bool was_cr = false;
+
+    if (!serial_ready)
+    {
+       init_serial(COM1_PORT);
+       serial_ready = true;
+    }
+
+    if (c == '\n' && !was_cr)
+        write_serial('\r', COM1_PORT);
+
+    write_serial(c, COM1_PORT);
+
+    if (c == '\r')
+        was_cr = true;
+    else
+        was_cr = false;
+
+    return 0;
+}
diff --git a/src/pOS/arch/x86/kernel/system.cpp b/src/pOS/arch/x86/kernel/system.cpp
new file mode 100644
index 0000000..ade04f8
--- /dev/null
+++ b/src/pOS/arch/x86/kernel/system.cpp
@@ -0,0 +1,21 @@
+#include <kernel/system.h>
+
+uint8_t System::inb(uint16_t port)
+{
+    uint8_t result;
+    asm volatile( "inb %1, %0" : "=a"(result) : "Nd"(port));
+        return result;
+}
+
+void System::outb(uint16_t port, uint8_t data)
+{
+   asm volatile( "outb %0, %1" : : "a"(data), "Nd"(port));
+}
+
+int System::idle_loop(void)
+{
+    while(1)
+        asm("hlt");
+
+    return 1;
+}
diff --git a/src/pOS/arch/x86/kernel/time.cpp b/src/pOS/arch/x86/kernel/time.cpp
new file mode 100644
index 0000000..b0e50b9
--- /dev/null
+++ b/src/pOS/arch/x86/kernel/time.cpp
@@ -0,0 +1,134 @@
+#include <kernel/time.h>
+
+static constexpr const char* months[12] = {
+    "January",
+    "Febuary",
+    "March",
+    "April",
+    "May",
+    "June",
+    "July",
+    "August",
+    "September",
+    "October",
+    "November",
+    "December"
+};
+
+static constexpr const char* days[7] = {
+    "Monday",
+    "Tuesday",
+    "Wednesday",
+    "Thursday",
+    "Friday",
+    "Saturday",
+    "Sunday"
+};
+
+timedate Time::get_date(void)
+{
+    return RTC::get_date();
+}
+
+uint8_t Time::get_second(void)
+{
+    return Time::get_date().second;
+}
+
+uint8_t Time::get_minute(void)
+{
+    return Time::get_date().minute;
+}
+
+uint8_t Time::get_hour(void)
+{
+    return Time::get_date().hour;
+}
+
+uint8_t Time::get_day(void)
+{
+    return Time::get_date().day;
+}
+
+uint8_t Time::get_month(void)
+{
+    return Time::get_date().month;
+}
+
+uint8_t Time::get_year(void)
+{
+    return Time::get_date().year;
+}
+
+uint8_t Time::get_century(void)
+{
+    return Time::get_date().century;
+}
+
+uint8_t Time::get_millennium(void)
+{
+    return Time::get_date().millennia;
+}
+
+const char* Time::get_day_string(void)
+{
+    return days[0]; //TODO
+}
+
+const char* Time::get_day_string(int day)
+{
+    return days[day - 1];
+}
+
+const char* Time::get_month_string(void)
+{
+    return months[get_month() - 1];
+}
+
+const char* Time::get_month_string(int month)
+{
+    return months[month - 1];
+}
+
+const char* Time::get_weekday(void)
+{
+    timedate date = RTC::get_date();
+    UNUSED_VARIABLE(date);
+    return days[0]; //TODO
+}
+
+const char* Time::get_weekday(timedate date)
+{
+    UNUSED_VARIABLE(date);
+    return days[0]; //TODO
+}
+
+const char* Time::get_date_formatted(void)
+{
+    //HH:MM:SS
+    static char buf[9]; //temp as we dont have mem alloc
+    itoa(get_hour(), buf, 2);
+    if(strlen(buf) == 1)
+    {
+        buf[1] = buf[0];
+        buf[0] = '0';
+    }
+    buf[2] = ':';
+    itoa(get_minute(), buf + 3, 2);
+    if(strlen(buf) == 4)
+    {
+        buf[4] = buf[3];
+        buf[3] = '0';
+    }
+    buf[5] = ':';
+    itoa(get_second(), buf + 6, 2);
+    if(strlen(buf) == 7)
+    {
+        buf[7] = buf[6];
+        buf[6] = '0';
+    }
+
+    buf[8] = '\0';
+
+    return buf;
+}
diff --git a/src/pOS/arch/x86/kernel/tty.cpp b/src/pOS/arch/x86/kernel/tty.cpp
new file mode 100644
index 0000000..daada0f
--- /dev/null
+++ b/src/pOS/arch/x86/kernel/tty.cpp
@@ -0,0 +1,111 @@
+#include <kernel/tty.h>
+
+size_t TTY::tty_y;
+size_t TTY::tty_x;
+uint8_t TTY::tty_color;
+uint16_t* TTY::tty_buf;
+uint16_t TTY::tty_map[VGA::VGA::VGA_WIDTH][VGA::VGA::VGA_HEIGHT];
+
+int TTY::tty_cursor_updt(void)
+{
+     uint16_t indx = tty_y * VGA::VGA::VGA_WIDTH + tty_x;
+
+     System::outb(0x3D4, 14);
+     System::outb(0x3D5, indx >> 8);
+     System::outb(0x3D4, 15);
+     System::outb(0x3D5, indx);
+
+     return 0;
+}
+
+int TTY::tty_scroll(void)
+{
+    if(tty_y + 1 >= VGA::VGA::VGA_HEIGHT)
+    {
+        /* move everything up */
+        for(size_t x = 0; x < VGA::VGA::VGA_WIDTH; x++)
+            for(size_t y = 0; y < VGA::VGA::VGA_HEIGHT - 1; y++)
+                tty_map[x][y] = tty_map[x][y + 1];
+
+        /* clear last line */
+        for(size_t i = 0; i < VGA::VGA::VGA_WIDTH; i++)
+            tty_map[i][VGA::VGA::VGA_HEIGHT - 1] = VGA::vga_entry(' ', tty_color);
+
+        tty_y--;
+        tty_update();
+    }
+
+    return 0;
+}
+
+int TTY::tty_update(void) /* NOT EFFICIENT */
+{
+    for (size_t x = 0; x < VGA::VGA::VGA_WIDTH; x++)
+        for (size_t y = 0; y < VGA::VGA::VGA_HEIGHT; y++)
+            tty_buf[y * VGA::VGA::VGA_WIDTH + x] = tty_map[x][y];
+
+    tty_cursor_updt();
+    tty_scroll();
+
+    return 0;
+}
+
+int TTY::tty_putentryat(unsigned char c, uint8_t color, size_t x, size_t y)
+{
+    tty_map[x][y] = VGA::vga_entry(c, color);
+    if(++tty_x >= VGA::VGA::VGA_WIDTH)
+    {
+        tty_x = tty_x - VGA::VGA::VGA_WIDTH;
+        tty_y++;
+    }
+
+    tty_update();
+    return 0;
+}
+
+int TTY::tty_initialize(void)
+{
+    tty_y = 0;
+    tty_x = 0;
+    tty_color = VGA::vga_entry_color(VGA::VGA_COLOR_GREEN, VGA::VGA_COLOR_BLACK);
+    tty_buf = (uint16_t*)VGA::VGA_MEMORY;
+    for (size_t y = 0; y < VGA::VGA::VGA_HEIGHT; y++)
+        for (size_t x = 0; x < VGA::VGA::VGA_WIDTH; x++)
+            tty_map[x][y] = VGA::vga_entry(' ', tty_color);
+
+    tty_update();
+
+    return 0;
+}
+
+int TTY::tty_setcolor(uint8_t color)
+{
+    tty_color = color;
+    return 0;
+}
+
+int TTY::tty_putc(char c)
+{
+    if(c == '\n')
+    {
+        tty_x = 0;
+        tty_y++;
+        return 0;
+    }
+    else if(c == '\t')
+    {
+        tty_x += 4;
+        return 0;
+    } //add \r
+
+    tty_putentryat((unsigned char)c, tty_color, tty_x, tty_y);
+
+    return 0;
+}
+
+int TTY::tty_write(const char* data, size_t size)
+{
+    for (size_t i = 0; i < size; i++)
+        tty_putc(data[i]);
+    return 0;
+}
diff --git a/src/pOS/arch/x86/libc/math.c b/src/pOS/arch/x86/libc/math.c
new file mode 100644
index 0000000..c83d132
--- /dev/null
+++ b/src/pOS/arch/x86/libc/math.c
@@ -0,0 +1,22 @@
+#include <math.h>
+
+int min(int a, int b)
+{
+    return (a < b) ? a : b;
+}
+
+int max(int a, int b)
+{
+    return (a > b) ? a : b;
+}
+
+int pow(int num, int p)
+{
+    int result = 1;
+    for(int i = 0; i < p; i++)
+    {
+        result *= num;
+    }
+
+    return result;
+}
diff --git a/src/pOS/arch/x86/libc/stdio/printf.cpp b/src/pOS/arch/x86/libc/stdio/printf.cpp
new file mode 100644
index 0000000..dc880ac
--- /dev/null
+++ b/src/pOS/arch/x86/libc/stdio/printf.cpp
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+static bool serial_debug = false;
+
+void Debug::set_serial_debug(bool state)
+{
+    serial_debug = state;
+}
+
+static void console_out(char c)
+{
+   if (serial_debug)
+        Serial::serial_putch(c);
+
+    putc(c);
+}
+
+static void console_putch(char*&, char c) //wrapper so that we can sprintf
+{
+    console_out(c);
+}
+
+int printf(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    int result = printf_internal(console_putch, nullptr, fmt, ap);
+    va_end(ap);
+    return result;
+}
+
+int print(const char* str, int len)
+{
+    for (int i = 0; i < len; ++i)
+        console_out(str[i]);
+    return 0;
+}
diff --git a/src/pOS/arch/x86/libc/stdio/putc.cpp b/src/pOS/arch/x86/libc/stdio/putc.cpp
new file mode 100644
index 0000000..ce01839
--- /dev/null
+++ b/src/pOS/arch/x86/libc/stdio/putc.cpp
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int putc(const char c)
+{
+    return TTY::tty_putc(c);
+}
diff --git a/src/pOS/arch/x86/libc/stdio/sprintf.cpp b/src/pOS/arch/x86/libc/stdio/sprintf.cpp
new file mode 100644
index 0000000..e7df4d3
--- /dev/null
+++ b/src/pOS/arch/x86/libc/stdio/sprintf.cpp
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+static void buffer_putch(char*& bufptr, char c)
+{
+    *bufptr++ = c;
+}
+
+int sprintf(char* buf, const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    int result = printf_internal(buffer_putch, buf, fmt, ap);
+    buf[result] = '\0';
+    va_end(ap);
+    return result;
+}
diff --git a/src/pOS/arch/x86/libc/stdlib/atoi.cpp b/src/pOS/arch/x86/libc/stdlib/atoi.cpp
new file mode 100644
index 0000000..46b8d5f
--- /dev/null
+++ b/src/pOS/arch/x86/libc/stdlib/atoi.cpp
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+
+static int to_int(char c)
+{
+    return c - '0';
+}
+
+static bool is_num(char c)
+{
+    return (c >= '0' && c <= '9');
+}
+
+int atoi(const char* str)
+{
+    int result = 0;
+    int index = 0;
+
+    if(str[0] == '-')
+        index++;
+
+    while(str[index] != '\0')
+    {
+        ASSERT(is_num(str[index]));
+        result = (to_int(str[index]) + (10 * result));
+        index++;
+    }
+
+    if(str[0] == '-')
+    {
+        result *= -1;
+    }
+
+    return result;
+}
diff --git a/src/pOS/arch/x86/libc/stdlib/itoa.cpp b/src/pOS/arch/x86/libc/stdlib/itoa.cpp
new file mode 100644
index 0000000..722265d
--- /dev/null
+++ b/src/pOS/arch/x86/libc/stdlib/itoa.cpp
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+
+int itoa(int i, char* buf, size_t len)
+{
+    const char* digit = "0123456789";
+    size_t index = 0;
+
+    if(i < 0)
+    {
+        buf[index++] = '-';
+        i *= -1;
+    }
+
+    int shifter = i;
+
+    do
+    {
+        index++;
+        shifter /= 10;
+    }while(len > index && shifter);
+
+    buf[index] = '\0';
+
+    do
+    {
+        buf[--index] = digit[i % 10];
+        i /= 10;
+    }while(i);
+
+    return 0;
+}
diff --git a/src/pOS/arch/x86/libc/string/memcpy.cpp b/src/pOS/arch/x86/libc/string/memcpy.cpp
new file mode 100644
index 0000000..2f5c978
--- /dev/null
+++ b/src/pOS/arch/x86/libc/string/memcpy.cpp
@@ -0,0 +1,10 @@
+#include <string.h>
+
+void* memcpy(void* dst, const void* src, size_t size)
+{
+    uint8_t* dstptr = static_cast<uint8_t*>(dst);
+    const uint8_t* srcptr = static_cast<const uint8_t*>(src);
+    for (size_t i = 0; i < size; i++)
+        dstptr[i] = srcptr[i];
+    return dst;
+}
diff --git a/src/pOS/arch/x86/libc/string/memset.cpp b/src/pOS/arch/x86/libc/string/memset.cpp
new file mode 100644
index 0000000..35ab14a
--- /dev/null
+++ b/src/pOS/arch/x86/libc/string/memset.cpp
@@ -0,0 +1,11 @@
+#include <string.h>
+
+void* memset(void* buf, int value, size_t size)
+{
+    uint8_t* bufptr = static_cast<uint8_t*>(buf);
+
+    for(size_t i = 0; i < size; i++)
+        *bufptr = (uint8_t)value;
+
+    return buf;
+}
diff --git a/src/pOS/arch/x86/libc/string/strlen.cpp b/src/pOS/arch/x86/libc/string/strlen.cpp
new file mode 100644
index 0000000..e28aed6
--- /dev/null
+++ b/src/pOS/arch/x86/libc/string/strlen.cpp
@@ -0,0 +1,9 @@
+#include <string.h>
+
+size_t strlen(const char* str)
+{
+    size_t len = 0;
+    while (str[len] != '\0')
+        len++;
+    return len;
+}
diff --git a/src/pOS/arch/x86/libc/string/strncpy.cpp b/src/pOS/arch/x86/libc/string/strncpy.cpp
new file mode 100644
index 0000000..1881001
--- /dev/null
+++ b/src/pOS/arch/x86/libc/string/strncpy.cpp
@@ -0,0 +1,14 @@
+#include <string.h>
+
+char* strncpy(char* dst, const char* src, size_t len)
+{
+    if(!dst)
+        return NULL;
+    char* dstptr = dst;
+
+    while(*src && len--)
+        *dst++ = *src++;
+    *dst = '\0';
+
+    return dstptr;
+}
diff --git a/src/pOS/include/kernel/debug.h b/src/pOS/include/kernel/debug.h
new file mode 100644
index 0000000..61dddee
--- /dev/null
+++ b/src/pOS/include/kernel/debug.h
@@ -0,0 +1,11 @@
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#include <stdarg.h>
+#include <printf_internal.h>
+#include <kernel/serial.h>
+
+int dbgprintf(const char* fmt, ...);
+int dbgprint(const char* str, int len);
+
+#endif
diff --git a/src/pOS/include/kernel/pOS.h b/src/pOS/include/kernel/pOS.h
new file mode 100644
index 0000000..278b0a1
--- /dev/null
+++ b/src/pOS/include/kernel/pOS.h
@@ -0,0 +1,7 @@
+#ifndef _POS_H_
+#define _POS_H_
+
+#define DEBUG
+#define VERSION "meme"
+
+#endif
diff --git a/src/pOS/include/kernel/rtc.h b/src/pOS/include/kernel/rtc.h
new file mode 100644
index 0000000..c0aa71d
--- /dev/null
+++ b/src/pOS/include/kernel/rtc.h
@@ -0,0 +1,30 @@
+#ifndef _RTC_H_
+#define _RTC_H_
+
+#include <stdint.h>
+#include <kernel/time.h>
+#include <kernel/system.h>
+
+#define CMOS_PORT 0x70
+#define CMOS_DATA 0x71
+
+#define CMOS_READ_SECOND 0x00
+#define CMOS_READ_MINUTE 0x02
+#define CMOS_READ_HOUR 0x04
+#define CMOS_READ_DAY 0x07
+#define CMOS_READ_MONTH 0x08
+#define CMOS_READ_YEAR 0x09
+
+#define CURRENT_CENTURY 21
+#define CURRENT_MILLENNIUM 3
+
+class RTC
+{
+public:
+    static timedate get_date(void);
+private:
+    static int get_update_in_progress_flag(void);
+    static uint8_t read_cmos(uint8_t registr);
+};
+
+#endif
diff --git a/src/pOS/include/kernel/serial.h b/src/pOS/include/kernel/serial.h
new file mode 100644
index 0000000..75746c3
--- /dev/null
+++ b/src/pOS/include/kernel/serial.h
@@ -0,0 +1,24 @@
+#ifndef _SERIAL_H_
+#define _SERIAL_H_
+
+#include <kernel/system.h>
+
+#define COM1_PORT 0x3f8
+#define COM2_PORT 0x2f8
+#define COM3_PORT 0x3e8
+#define COM4_PORT 0x2e8
+
+class Serial
+{
+public:
+    static int init_serial(uint16_t port);
+    static int write_serial(uint8_t data, uint16_t port);
+    static uint8_t read_serial(uint16_t port);
+    static int serial_putch(char c);
+private:
+    static int is_transmit_empty(uint16_t port);
+    static int serial_received(uint16_t port);
+
+};
+
+#endif
diff --git a/src/pOS/include/kernel/system.h b/src/pOS/include/kernel/system.h
new file mode 100644
index 0000000..146ceed
--- /dev/null
+++ b/src/pOS/include/kernel/system.h
@@ -0,0 +1,15 @@
+#ifndef _SYSTEM_H_
+#define _SYSTEM_H_
+
+#include <stdint.h>
+
+class System
+{
+public:
+    static uint8_t inb(uint16_t port);
+    static void outb(uint16_t port, uint8_t data);
+
+    static int idle_loop(void);
+};
+
+#endif
diff --git a/src/pOS/include/kernel/time.h b/src/pOS/include/kernel/time.h
new file mode 100644
index 0000000..7038daf
--- /dev/null
+++ b/src/pOS/include/kernel/time.h
@@ -0,0 +1,43 @@
+#ifndef _TIME_H_
+#define _TIME_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct timedate
+{
+    uint8_t second;
+    uint8_t minute;
+    uint8_t hour;
+    uint8_t day;
+    uint8_t month;
+    uint8_t year;
+    uint8_t century;
+    uint8_t millennia;
+};
+
+#include <kernel/rtc.h>
+
+class Time
+{
+public:
+    static timedate get_date(void);
+    static uint8_t get_second(void);
+    static uint8_t get_minute(void);
+    static uint8_t get_hour(void);
+    static uint8_t get_day(void);
+    static uint8_t get_month(void);
+    static uint8_t get_year(void);
+    static uint8_t get_century(void);
+    static uint8_t get_millennium(void);
+    static const char* get_day_string(void);
+    static const char* get_day_string(int day);
+    static const char* get_month_string(void);
+    static const char* get_month_string(int month);
+    static const char* get_weekday(void);
+    static const char* get_weekday(timedate date);
+    static const char* get_date_formatted(void);
+};
+
+#endif
diff --git a/src/pOS/include/kernel/tty.h b/src/pOS/include/kernel/tty.h
new file mode 100644
index 0000000..23b46dc
--- /dev/null
+++ b/src/pOS/include/kernel/tty.h
@@ -0,0 +1,29 @@
+#ifndef _TTY_H_
+#define _TTY_H_
+
+#include <string.h>
+#include <kernel/vga.h>
+#include <kernel/system.h>
+
+class TTY
+{
+public:
+    static int tty_initialize(void);
+    static int tty_setcolor(uint8_t color);
+    static int tty_putc(char c);
+    static int tty_write(const char* data, size_t size);
+private:
+    static int tty_putentryat(unsigned char c, uint8_t color, size_t x, size_t y);
+    static int tty_update(void);
+    static int tty_scroll(void);
+    static int tty_cursor_updt(void);
+
+    static size_t tty_y;
+    static size_t tty_x;
+    static uint8_t tty_color;
+    static uint16_t* tty_buf;
+    static uint16_t tty_map[VGA::VGA_WIDTH][VGA::VGA_HEIGHT];
+};
+
+
+#endif
diff --git a/src/pOS/include/kernel/vga.h b/src/pOS/include/kernel/vga.h
new file mode 100644
index 0000000..ce21848
--- /dev/null
+++ b/src/pOS/include/kernel/vga.h
@@ -0,0 +1,44 @@
+#ifndef _VGA_H_
+#define _VGA_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+class VGA
+{
+public:
+     static constexpr int VGA_WIDTH = 80;
+     static constexpr int VGA_HEIGHT = 25;
+     static constexpr uint16_t* VGA_MEMORY = reinterpret_cast<uint16_t*>(0xb8000);
+
+     enum vga_colors {
+        VGA_COLOR_BLACK,
+        VGA_COLOR_BLUE,
+        VGA_COLOR_GREEN,
+        VGA_COLOR_CYAN,
+        VGA_COLOR_RED,
+        VGA_COLOR_MAGENTA,
+        VGA_COLOR_BROWN,
+        VGA_COLOR_LIGHT_GREY,
+        VGA_COLOR_DARK_GREY,
+        VGA_COLOR_LIGHT_BLUE,
+        VGA_COLOR_LIGHT_GREEN,
+        VGA_COLOR_LIGHT_CYAN,
+        VGA_COLOR_LIGHT_RED,
+        VGA_COLOR_LIGHT_MAGENTA,
+        VGA_COLOR_LIGHT_BROWN,
+        VGA_COLOR_WHITE,
+    };
+
+    static uint8_t vga_entry_color(enum vga_colors fg, enum vga_colors bg)
+    {
+        return fg | bg << 4;
+    }
+
+    static uint16_t vga_entry(unsigned char uc, uint8_t color)
+    {
+        return (uint16_t) uc | (uint16_t) color << 8;
+    }
+};
+
+#endif
diff --git a/src/pOS/include/libc/assert.h b/src/pOS/include/libc/assert.h
new file mode 100644
index 0000000..3eae3c5
--- /dev/null
+++ b/src/pOS/include/libc/assert.h
@@ -0,0 +1,14 @@
+#ifndef _ASSERT_H_
+#define _ASSERT_H_
+
+#include <stdio.h>
+
+#define ASSERT(EXPR) (void)((EXPR) || (_assert (#EXPR, __FILE__, __LINE__),0))
+
+static inline void _assert(const char* expr, const char* file, int line)
+{
+    printf("Assertion failed! (%s) - %s:%d\n", expr, file ,line);
+    /* TODO: Implement exit */
+}
+
+#endif
diff --git a/src/pOS/include/libc/math.h b/src/pOS/include/libc/math.h
new file mode 100644
index 0000000..76953fb
--- /dev/null
+++ b/src/pOS/include/libc/math.h
@@ -0,0 +1,8 @@
+#ifndef _MATH_H_
+#define _MATH_H_
+
+int min(int a, int b);
+int max(int a, int b);
+int pow(int num, int p);
+
+#endif
diff --git a/src/pOS/include/libc/printf_internal.h b/src/pOS/include/libc/printf_internal.h
new file mode 100644
index 0000000..c2ae2fd
--- /dev/null
+++ b/src/pOS/include/libc/printf_internal.h
@@ -0,0 +1,409 @@
+#ifndef _PRINTF_INTERNAL_H_
+#define _PRINTF_INTERNAL_H_
+
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+
+/* FROM SERENITYOS */
+
+static constexpr const char* printf_hex_digits_lower = "0123456789abcdef";
+static constexpr const char* printf_hex_digits_upper = "0123456789ABCDEF";
+
+template<typename PutChFunc, typename T>
+inline int print_hex(PutChFunc putch, char*& bufptr, T number, bool upper_case, bool alternate_form, bool left_pad, bool zero_pad, uint8_t field_width)
+{
+    int ret = 0;
+
+    int digits = 0;
+    for (T n = number; n > 0; n >>= 4)
+        ++digits;
+    if (digits == 0)
+        digits = 1;
+
+    if (left_pad) {
+        int stop_at = field_width - digits;
+        if (alternate_form)
+            stop_at -= 2;
+
+        while (ret < stop_at) {
+            putch(bufptr, ' ');
+            ++ret;
+        }
+    }
+
+    if (alternate_form) {
+        putch(bufptr, '0');
+        putch(bufptr, 'x');
+        ret += 2;
+        field_width += 2;
+    }
+
+    if (zero_pad) {
+        while (ret < field_width - digits) {
+            putch(bufptr, '0');
+            ++ret;
+        }
+    }
+
+    if (number == 0) {
+        putch(bufptr, '0');
+        ++ret;
+    } else {
+        uint8_t shift_count = digits * 4;
+        while (shift_count) {
+            shift_count -= 4;
+            putch(bufptr,
+                upper_case
+                    ? printf_hex_digits_upper[(number >> shift_count) & 0x0f]
+                    : printf_hex_digits_lower[(number >> shift_count) & 0x0f]);
+            ++ret;
+        }
+    }
+
+    return ret;
+}
+
+template<typename PutChFunc>
+inline int print_number(PutChFunc putch, char*& bufptr, uint32_t number, bool left_pad, bool zero_pad, uint32_t field_width)
+{
+    uint32_t divisor = 1000000000;
+    char ch;
+    char padding = 1;
+    char buf[16];
+    char* p = buf;
+
+    for (;;) {
+        ch = '0' + (number / divisor);
+        number %= divisor;
+        if (ch != '0')
+            padding = 0;
+        if (!padding || divisor == 1)
+            *(p++) = ch;
+        if (divisor == 1)
+            break;
+        divisor /= 10;
+    }
+
+    size_t numlen = p - buf;
+    if (!field_width || field_width < numlen)
+        field_width = numlen;
+    if (!left_pad) {
+        for (unsigned i = 0; i < field_width - numlen; ++i) {
+            putch(bufptr, zero_pad ? '0' : ' ');
+        }
+    }
+    for (unsigned i = 0; i < numlen; ++i) {
+        putch(bufptr, buf[i]);
+    }
+    if (left_pad) {
+        for (unsigned i = 0; i < field_width - numlen; ++i) {
+            putch(bufptr, ' ');
+        }
+    }
+
+    return field_width;
+}
+
+template<typename PutChFunc>
+inline int print_uint64_t(PutChFunc putch, char*& bufptr, uint64_t number, bool left_pad, bool zero_pad, uint32_t field_width)
+{
+    uint64_t divisor = 10000000000000000000LLU;
+    char ch;
+    char padding = 1;
+    char buf[16];
+    char* p = buf;
+
+    for (;;) {
+        ch = '0' + (number / divisor);
+        number %= divisor;
+        if (ch != '0')
+            padding = 0;
+        if (!padding || divisor == 1)
+            *(p++) = ch;
+        if (divisor == 1)
+            break;
+        divisor /= 10;
+    }
+
+    size_t numlen = p - buf;
+    if (!field_width || field_width < numlen)
+        field_width = numlen;
+    if (!left_pad) {
+        for (unsigned i = 0; i < field_width - numlen; ++i) {
+            putch(bufptr, zero_pad ? '0' : ' ');
+        }
+    }
+    for (unsigned i = 0; i < numlen; ++i) {
+        putch(bufptr, buf[i]);
+    }
+    if (left_pad) {
+        for (unsigned i = 0; i < field_width - numlen; ++i) {
+            putch(bufptr, ' ');
+        }
+    }
+
+    return field_width;
+}
+
+template<typename PutChFunc>
+inline int print_double(PutChFunc putch, char*& bufptr, double number, bool left_pad, bool zero_pad, uint32_t field_width, uint32_t fraction_length = 6)
+{
+    int length = 0;
+
+    if (number < 0) {
+        putch(bufptr, '-');
+        length++;
+        number = 0 - number;
+    }
+
+    length = print_uint64_t(putch, bufptr, (int64_t)number, left_pad, zero_pad, field_width);
+    putch(bufptr, '.');
+    length++;
+    double fraction = number - (int64_t)number;
+
+    for (uint32_t i = 0; i < fraction_length; ++i)
+        fraction = fraction * 10;
+
+    return length + print_uint64_t(putch, bufptr, (int64_t)fraction, false, true, fraction_length);
+}
+
+template<typename PutChFunc>
+inline int print_int64_t(PutChFunc putch, char*& bufptr, int64_t number, bool left_pad, bool zero_pad, uint32_t field_width)
+{
+    if (number < 0) {
+        putch(bufptr, '-');
+        return print_uint64_t(putch, bufptr, 0 - number, left_pad, zero_pad, field_width) + 1;
+    }
+    return print_uint64_t(putch, bufptr, number, left_pad, zero_pad, field_width);
+}
+
+template<typename PutChFunc>
+inline int print_octal_number(PutChFunc putch, char*& bufptr, uint32_t number, bool left_pad, bool zero_pad, uint32_t field_width)
+{
+    uint32_t divisor = 134217728;
+    char ch;
+    char padding = 1;
+    char buf[32];
+    char* p = buf;
+
+    for (;;) {
+        ch = '0' + (number / divisor);
+        number %= divisor;
+        if (ch != '0')
+            padding = 0;
+        if (!padding || divisor == 1)
+            *(p++) = ch;
+        if (divisor == 1)
+            break;
+        divisor /= 8;
+    }
+
+    size_t numlen = p - buf;
+    if (!field_width || field_width < numlen)
+        field_width = numlen;
+    if (!left_pad) {
+        for (unsigned i = 0; i < field_width - numlen; ++i) {
+            putch(bufptr, zero_pad ? '0' : ' ');
+        }
+    }
+    for (unsigned i = 0; i < numlen; ++i) {
+        putch(bufptr, buf[i]);
+    }
+    if (left_pad) {
+        for (unsigned i = 0; i < field_width - numlen; ++i) {
+            putch(bufptr, ' ');
+        }
+    }
+
+    return field_width;
+}
+
+template<typename PutChFunc>
+inline int print_string(PutChFunc putch, char*& bufptr, const char* str, size_t len, bool left_pad, size_t field_width, bool dot)
+{
+    if (!dot && (!field_width || field_width < len))
+        field_width = len;
+    size_t pad_amount = field_width > len ? field_width - len : 0;
+
+    if (!left_pad) {
+        for (size_t i = 0; i < pad_amount; ++i)
+            putch(bufptr, ' ');
+    }
+    for (int i = 0; i < min(len, field_width); ++i) {
+        putch(bufptr, str[i]);
+    }
+    if (left_pad) {
+        for (size_t i = 0; i < pad_amount; ++i)
+            putch(bufptr, ' ');
+    }
+    return field_width;
+}
+
+template<typename PutChFunc>
+inline int print_signed_number(PutChFunc putch, char*& bufptr, int number, bool left_pad, bool zero_pad, uint32_t field_width, bool always_sign)
+{
+    if (number < 0) {
+        putch(bufptr, '-');
+        return print_number(putch, bufptr, 0 - number, left_pad, zero_pad, field_width) + 1;
+    }
+    if (always_sign)
+        putch(bufptr, '+');
+    return print_number(putch, bufptr, number, left_pad, zero_pad, field_width);
+}
+
+template<typename PutChFunc>
+inline int printf_internal(PutChFunc putch, char* buffer, const char*& fmt, va_list ap)
+{
+    const char* p;
+
+    int ret = 0;
+    char* bufptr = buffer;
+
+    for (p = fmt; *p; ++p) {
+        bool left_pad = false;
+        bool zero_pad = false;
+        bool dot = false;
+        unsigned field_width = 0;
+        unsigned fraction_length = 0;
+        unsigned long_qualifiers = 0;
+        bool size_qualifier = false;
+        (void)size_qualifier;
+        bool alternate_form = 0;
+        bool always_sign = false;
+        if (*p == '%' && *(p + 1)) {
+        one_more:
+            ++p;
+            if (*p == '.') {
+                dot = true;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (*p == '-') {
+                left_pad = true;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (*p == '+') {
+                always_sign = true;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (!zero_pad && !field_width && *p == '0') {
+                zero_pad = true;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (*p >= '0' && *p <= '9') {
+                if (!dot) {
+                    field_width *= 10;
+                    field_width += *p - '0';
+                    if (*(p + 1))
+                        goto one_more;
+                } else {
+                    fraction_length *= 10;
+                    fraction_length += *p - '0';
+                    if (*(p + 1))
+                        goto one_more;
+                }
+            }
+            if (*p == '*') {
+                field_width = va_arg(ap, int);
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (*p == 'l') {
+                ++long_qualifiers;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (*p == 'z') {
+                size_qualifier = true;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            if (*p == '#') {
+                alternate_form = true;
+                if (*(p + 1))
+                    goto one_more;
+            }
+            switch (*p) {
+            case 's': {
+                const char* sp = va_arg(ap, const char*);
+                if (!sp)
+                    sp = "(null)";
+                ret += print_string(putch, bufptr, sp, strlen(sp), left_pad, field_width, dot);
+            } break;
+
+            case 'd':
+            case 'i':
+                if (long_qualifiers >= 2)
+                    ret += print_int64_t(putch, bufptr, va_arg(ap, int64_t), left_pad, zero_pad, field_width);
+                else
+                    ret += print_signed_number(putch, bufptr, va_arg(ap, int), left_pad, zero_pad, field_width, always_sign);
+                break;
+
+            case 'u':
+                if (long_qualifiers >= 2)
+                    ret += print_uint64_t(putch, bufptr, va_arg(ap, uint64_t), left_pad, zero_pad, field_width);
+                else
+                    ret += print_number(putch, bufptr, va_arg(ap, uint32_t), left_pad, zero_pad, field_width);
+                break;
+
+            case 'Q':
+                ret += print_uint64_t(putch, bufptr, va_arg(ap, uint64_t), left_pad, zero_pad, field_width);
+                break;
+
+            case 'q':
+                ret += print_hex(putch, bufptr, va_arg(ap, uint64_t), false, false, left_pad, zero_pad, 16);
+                break;
+
+            case 'o':
+                if (alternate_form) {
+                    putch(bufptr, '0');
+                    ++ret;
+                }
+                ret += print_octal_number(putch, bufptr, va_arg(ap, uint32_t), left_pad, zero_pad, field_width);
+                break;
+
+            case 'X':
+            case 'x':
+                ret += print_hex(putch, bufptr, va_arg(ap, uint32_t), *p == 'X', alternate_form, left_pad, zero_pad, field_width);
+                break;
+
+            case 'w':
+                ret += print_hex(putch, bufptr, va_arg(ap, int), false, alternate_form, false, true, 4);
+                break;
+
+            case 'b':
+                ret += print_hex(putch, bufptr, va_arg(ap, int), false, alternate_form, false, true, 2);
+                break;
+
+            case 'c': {
+                char c = va_arg(ap, int);
+                ret += print_string(putch, bufptr, &c, 1, left_pad, field_width, dot);
+            } break;
+
+            case '%':
+                putch(bufptr, '%');
+                ++ret;
+                break;
+
+            case 'P':
+            case 'p':
+                ret += print_hex(putch, bufptr, va_arg(ap, uint32_t), *p == 'P', true, false, true, 8);
+                break;
+
+            case 'n':
+                *va_arg(ap, int*) = ret;
+                break;
+            }
+        } else {
+            putch(bufptr, *p);
+            ++ret;
+        }
+    }
+    return ret;
+}
+
+#endif
diff --git a/src/pOS/include/libc/stddef.h b/src/pOS/include/libc/stddef.h
new file mode 100644
index 0000000..2f2cb80
--- /dev/null
+++ b/src/pOS/include/libc/stddef.h
@@ -0,0 +1,9 @@
+#ifndef _STDDEF_H_
+#define _STDDEF_H_
+
+#define NULL 0
+#define UNUSED_VARIABLE(x) (void)x
+
+typedef unsigned long long size_t;
+
+#endif
diff --git a/src/pOS/include/libc/stdint.h b/src/pOS/include/libc/stdint.h
new file mode 100644
index 0000000..0ba184a
--- /dev/null
+++ b/src/pOS/include/libc/stdint.h
@@ -0,0 +1,16 @@
+#ifndef _STDINT_H_
+#define _STDINT_H_
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+
+typedef signed long int32_t;
+typedef unsigned long uint32_t;
+
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+
+#endif
diff --git a/src/pOS/include/libc/stdio.h b/src/pOS/include/libc/stdio.h
new file mode 100644
index 0000000..844c817
--- /dev/null
+++ b/src/pOS/include/libc/stdio.h
@@ -0,0 +1,24 @@
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+#include <stdarg.h>
+#include <string.h>
+#include <kernel/tty.h>
+#include <printf_internal.h>
+#include <kernel/serial.h>
+
+#define EOF (-1)
+
+int printf(const char* format, ...);
+int sprintf(char* buf, const char* format, ...);
+int print(const char* str);
+int putc(const char c);
+
+class Debug
+{
+public:
+    static void set_serial_debug(bool state);
+};
+
+#endif
+
diff --git a/src/pOS/include/libc/stdlib.h b/src/pOS/include/libc/stdlib.h
new file mode 100644
index 0000000..d7e174e
--- /dev/null
+++ b/src/pOS/include/libc/stdlib.h
@@ -0,0 +1,11 @@
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <assert.h>
+
+int itoa(int i, char* buf, size_t len);
+int atoi(const char* str);
+
+#endif
diff --git a/src/pOS/include/libc/string.h b/src/pOS/include/libc/string.h
new file mode 100644
index 0000000..6983641
--- /dev/null
+++ b/src/pOS/include/libc/string.h
@@ -0,0 +1,12 @@
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+size_t strlen(const char* str);
+void* memset(void* buf, int value, size_t size);
+void* memcpy(void* dst, const void* src, size_t size);
+char* strncpy(char* dst, const char* src, size_t len);
+
+#endif
diff --git a/src/pOS/kernel/kernel.cpp b/src/pOS/kernel/kernel.cpp
new file mode 100644
index 0000000..9e2db30
--- /dev/null
+++ b/src/pOS/kernel/kernel.cpp
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <kernel/pOS.h>
+#include <kernel/time.h>
+#include <kernel/debug.h>
+#include <math.h>
+#include <assert.h>
+
+extern "C" int kmain(void)
+{
+    #ifdef DEBUG
+    Debug::set_serial_debug(true);
+    #endif
+    TTY::tty_initialize();
+
+    printf("Welcome to pOS v%s\n", VERSION);
+    dbgprintf("Hi host %d!\n", pow(3, 2));
+
+    printf("Current time: %s (%s-%d-%d%d)\n", Time::get_date_formatted(), Time::get_month_string(), Time::get_day(), Time::get_century() - 1, Time::get_year());
+
+    System::idle_loop();
+
+    ASSERT(false);
+
+	return 1;
+}