diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 70bf59ca..18553a08 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,5 +1,13 @@ set(SOURCES src/main.cpp + src/string.cpp + src/arch/Serial.cpp +) + +set(SOURCES + ${SOURCES} + src/arch/x86_64/IO.cpp + src/arch/x86_64/Serial.cpp ) add_compile_options(-Os) @@ -20,6 +28,7 @@ add_link_options(-lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mno-red-zone add_executable(moon ${SOURCES}) target_include_directories(moon PUBLIC ${LUNA_ROOT}/luna) +target_include_directories(moon PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src) target_link_options(moon PRIVATE LINKER:-T ${CMAKE_CURRENT_LIST_DIR}/moon.ld -nostdlib -nodefaultlibs) diff --git a/kernel/src/arch/Serial.cpp b/kernel/src/arch/Serial.cpp new file mode 100644 index 00000000..958557f6 --- /dev/null +++ b/kernel/src/arch/Serial.cpp @@ -0,0 +1,20 @@ +#include "arch/Serial.h" + +namespace Serial +{ + void write(const char* str, size_t size) + { + while (size--) putchar(*str++); + } + + void print(const char* str) + { + while (*str) putchar(*str++); + } + + void println(const char* str) + { + print(str); + putchar('\n'); + } +} \ No newline at end of file diff --git a/kernel/src/arch/Serial.h b/kernel/src/arch/Serial.h new file mode 100644 index 00000000..031aaac0 --- /dev/null +++ b/kernel/src/arch/Serial.h @@ -0,0 +1,10 @@ +#pragma once +#include + +namespace Serial +{ + void putchar(u8 c); + void write(const char* str, size_t size); + void print(const char* str); + void println(const char* str); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/IO.cpp b/kernel/src/arch/x86_64/IO.cpp new file mode 100644 index 00000000..8afa0a08 --- /dev/null +++ b/kernel/src/arch/x86_64/IO.cpp @@ -0,0 +1,40 @@ +#include "arch/x86_64/IO.h" + +namespace IO +{ + u8 inb(u16 port) + { + u8 result; + asm volatile("inb %1, %0" : "=a"(result) : "Nd"(port)); + return result; + } + + void outb(u16 port, u8 value) + { + asm volatile("outb %0, %1" : : "a"(value), "Nd"(port)); + } + + u16 inw(u16 port) + { + u16 result; + asm volatile("inw %1, %0" : "=a"(result) : "Nd"(port)); + return result; + } + + void outw(u16 port, u16 value) + { + asm volatile("outw %0, %1" : : "a"(value), "Nd"(port)); + } + + u32 inl(u16 port) + { + u32 result; + asm volatile("inl %1, %0" : "=a"(result) : "Nd"(port)); + return result; + } + + void outl(u16 port, u32 value) + { + asm volatile("outl %0, %1" : : "a"(value), "Nd"(port)); + } +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/IO.h b/kernel/src/arch/x86_64/IO.h new file mode 100644 index 00000000..05c6acf9 --- /dev/null +++ b/kernel/src/arch/x86_64/IO.h @@ -0,0 +1,13 @@ +#pragma once +#include + +namespace IO +{ + u8 inb(u16 port); + u16 inw(u16 port); + u32 inl(u16 port); + + void outb(u16 port, u8 value); + void outw(u16 port, u16 value); + void outl(u16 port, u32 value); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/Serial.cpp b/kernel/src/arch/x86_64/Serial.cpp new file mode 100644 index 00000000..3dc26ec4 --- /dev/null +++ b/kernel/src/arch/x86_64/Serial.cpp @@ -0,0 +1,15 @@ +#include "arch/Serial.h" +#include "arch/x86_64/IO.h" + +#define COM1 0x3f8 + +static void serial_wait() +{ + while (!(IO::inb(COM1 + 5) & 0x20)) { asm volatile("pause"); } +} + +void Serial::putchar(u8 c) +{ + serial_wait(); + IO::outb(COM1, c); +} \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index abf41426..3b529072 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,7 +1,9 @@ -#include +#include "arch/Serial.h" extern "C" void _start() { + Serial::println("Hello, world!"); + for (;;) ; } \ No newline at end of file diff --git a/kernel/src/string.cpp b/kernel/src/string.cpp new file mode 100644 index 00000000..68167cd2 --- /dev/null +++ b/kernel/src/string.cpp @@ -0,0 +1,5 @@ +extern "C" +{ +#define _LUNA_IMPLEMENTATION +#include +} \ No newline at end of file diff --git a/luna/String.h b/luna/String.h new file mode 100644 index 00000000..bba602be --- /dev/null +++ b/luna/String.h @@ -0,0 +1,65 @@ +#pragma once +#include + +void* memcpy(void* dest, const void* src, size_t n) +#ifdef _LUNA_IMPLEMENTATION +{ + for (size_t i = 0; i < n; ++i) { *((u8*)dest + i) = *((const u8*)src + i); } + return dest; +} +#else + ; +#endif + +void* memset(void* buf, int c, size_t n) +#ifdef _LUNA_IMPLEMENTATION +{ + for (size_t i = 0; i < n; ++i) { *((u8*)buf + i) = (u8)c; } + return buf; +} +#else + ; +#endif + +int memcmp(const void* a, const void* b, size_t n) +#ifdef _LUNA_IMPLEMENTATION +{ + if (!n) return 0; + const u8* ap = (const u8*)a; + const u8* bp = (const u8*)b; + while (--n && *ap == *bp) + { + ap++; + bp++; + } + return *ap - *bp; +} +#else + ; +#endif + +void* memmove(void* dest, const void* src, size_t n) +#ifdef _LUNA_IMPLEMENTATION +{ + if (dest == src) return dest; + if (dest > src) + for (long i = n - 1; i >= 0; i++) { *((u8*)dest + i) = *((const u8*)src + i); } + else + for (long i = 0; i < (long)n; i++) { *((u8*)dest + i) = *((const u8*)src + i); } + return dest; +} +#else + ; +#endif + +size_t strlen(const char* str) +#ifdef _LUNA_IMPLEMENTATION +{ + const char* i = str; + for (; *i; ++i) + ; + return (i - str); +} +#else + ; +#endif \ No newline at end of file diff --git a/luna/Types.h b/luna/Types.h index d2dc477b..c45e4448 100644 --- a/luna/Types.h +++ b/luna/Types.h @@ -1,3 +1,4 @@ +#include #include typedef uint8_t u8;