From 950f164a2eb851dbab0aacb44334f0b687d123e8 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 31 Jan 2021 23:24:42 +0200 Subject: libk: add its own makefile --- .gitignore | 1 + libk/makefile | 11 ++++++++ libk/stdlib.h | 14 ++++++++++ libk/stdlib/console.cc | 28 ++++++++++++++++++++ libk/string.cc | 26 ++++++++++++++++++ libk/string.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ libk/types.h | 30 +++++++++++++++++++++ makefile | 35 ++++++++++++++---------- readme.md | 5 +++- stdlib/stdlib.h | 14 ---------- stdlib/stdlib/console.cc | 28 -------------------- stdlib/string.cc | 26 ------------------ stdlib/string.h | 69 ------------------------------------------------ stdlib/types.h | 30 --------------------- 14 files changed, 204 insertions(+), 182 deletions(-) create mode 100644 libk/makefile create mode 100644 libk/stdlib.h create mode 100644 libk/stdlib/console.cc create mode 100644 libk/string.cc create mode 100644 libk/string.h create mode 100644 libk/types.h delete mode 100644 stdlib/stdlib.h delete mode 100644 stdlib/stdlib/console.cc delete mode 100644 stdlib/string.cc delete mode 100644 stdlib/string.h delete mode 100644 stdlib/types.h diff --git a/.gitignore b/.gitignore index 8deeab7..8bfb596 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.o +*.a *.bin diff --git a/libk/makefile b/libk/makefile new file mode 100644 index 0000000..faf5b79 --- /dev/null +++ b/libk/makefile @@ -0,0 +1,11 @@ + +CXX_OBJ := string.o stdlib/console.o + +libk.a: $(CXX_OBJ) + $(AR) rcs $@ $(CXX_OBJ) + +$(CXX_OBJ): %.o : %.cc + $(CXX) -target $(TARGET) $(CXX_FLAGS) -I$(CURDIR) -c $^ -o $@ + +clean: + rm libk.a $(CXX_OBJ) diff --git a/libk/stdlib.h b/libk/stdlib.h new file mode 100644 index 0000000..3e6619d --- /dev/null +++ b/libk/stdlib.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +class Console { +public: + virtual void write(const String &msg) = 0; +}; + +void console_set(Console *ptr); + +void printk(const String &msg); + +__attribute__((__noreturn__)) void abort(); diff --git a/libk/stdlib/console.cc b/libk/stdlib/console.cc new file mode 100644 index 0000000..dbc9b86 --- /dev/null +++ b/libk/stdlib/console.cc @@ -0,0 +1,28 @@ +#include "stdlib.h" + +static Console *global_console = nullptr; + +void console_set(Console *ptr) { + if (ptr != nullptr) { + global_console = ptr; + } +} + +void printk(const String &msg) { + if (global_console == nullptr) + return; + + global_console->write(msg); +} + +void abort() { + /* + * On gcc, a 'while(true) {}' will infinitely loop + * but clang will optimize it away on -O2 if it's empty + * therefore, add no-op + */ + while (true) { + asm volatile("nop"); + } + __builtin_unreachable(); +} diff --git a/libk/string.cc b/libk/string.cc new file mode 100644 index 0000000..5cd4bb2 --- /dev/null +++ b/libk/string.cc @@ -0,0 +1,26 @@ +#include "string.h" + +// TODO + +// int strcpy(char *dst, const char *stc); +// void strcat(void *dst, const void *src); +// char* strncpy(char *dest, const char *src, int length); +// int strncmp(const char *s1, const char *s2, int c); + +/* strcmp - compare two C-strings */ +constexpr int strcmp(const char *s1, const char *s2) +{ + const auto s1_len = strlen(s1); + for(size_t i = 0; i < s1_len; ++i) { + if(s1[i] == s2[i]) continue; + if(s1[i] > s2[i]) return 1; + if(s1[i] < s2[i]) return -1; + } + return 0; +} + +static_assert(strcmp("one", "one") == 0); +static_assert(strcmp("one", "two") < 0); +static_assert(strcmp("foo", "bar") > 0); + + diff --git a/libk/string.h b/libk/string.h new file mode 100644 index 0000000..deb6fde --- /dev/null +++ b/libk/string.h @@ -0,0 +1,69 @@ +#pragma once +#include "types.h" + +constexpr size_t strlen(const char *str) { + int len = 0; + while (str[len]) + ++len; + return len; +} + +/* reverse: reverse string s in place */ +constexpr void reverse(char s[]) { + int i, j; + char c; + + for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +/* itoa: convert n to characters in s */ +template constexpr void itoa(int n, char s[]) { + int i, sign; + + if ((sign = n) < 0) /* record sign */ + n = -n; /* make n positive */ + + i = 0; + do { /* generate digits in reverse order */ + s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ + } while ((n /= base) > 0); /* delete it */ + + if (sign < 0) + s[i++] = '-'; + + s[i] = '\0'; + + reverse(s); +} + +class String { +public: + class Iterator { + friend class String; + + public: + char next() { return p->buffer[pos++]; } + operator bool() const { return (pos < p->m_length); } + + private: + Iterator(const String *s) : p(s) {} + + size_t pos = 0; + const String *p; + }; + + friend class Iterator; + + String(const char *d) : buffer{d}, m_length{strlen(d)} {} + String(const char *d, size_t l) : buffer{d}, m_length{l} {} + + Iterator begin() const { return Iterator(this); } + +private: + const char *const buffer; + const size_t m_length; +}; diff --git a/libk/types.h b/libk/types.h new file mode 100644 index 0000000..0818342 --- /dev/null +++ b/libk/types.h @@ -0,0 +1,30 @@ +#pragma once + +typedef unsigned short size_t; +static_assert(sizeof(size_t) >= 2); + + +typedef unsigned char uint8_t; +static_assert(sizeof(uint8_t) == 1); + +typedef unsigned short uint16_t; +static_assert(sizeof(uint16_t) == 2); + +typedef unsigned int uint32_t; +static_assert(sizeof(uint32_t) == 4); + +//typedef unsigned long uint64_t; +//static_assert(sizeof(uint64_t) == 8); + + +typedef char int8_t; +static_assert(sizeof(int8_t) == 1); + +typedef short int16_t; +static_assert(sizeof(int16_t) == 2); + +typedef int int32_t; +static_assert(sizeof(int32_t) == 4); + +//typedef long int64_t; +//static_assert(sizeof(int64_t) == 8); diff --git a/makefile b/makefile index 82e3bba..10cfacf 100644 --- a/makefile +++ b/makefile @@ -3,39 +3,46 @@ # ?= only set if it doesn't have a value # != execute a shell script on the right-hand side and assign its result to the left-hand side -TARGET := i686-elf +export TARGET := i686-elf -NASM := nasm -CXX := clang++ -CXXFLAGS := -std=c++20 -ffreestanding -nostdinc -fno-exceptions -fno-rtti -Wall -Wextra -O2 -INCLUDE := stdlib - -OBJ := kernel.o vga.o stdlib/string.o stdlib/stdlib/console.o +export AR := llvm-ar +export NASM := nasm +export LD := ld.lld +export CXX := clang++ +export CXX_FLAGS := -std=c++20 -ffreestanding -nostdinc -fno-exceptions -fno-rtti -Wall -Wextra -O2 +CXX_INCLUDE := libk +CXX_OBJ := kernel.o vga.o # $@ is target # $< is first dependency # $^ is all dependencies -default: boot.o $(OBJ) - ld.lld -T linker.ld -o myos.bin boot.o $(OBJ) +default: myos.bin + +myos.bin: boot.o $(CXX_OBJ) libk/libk.a + $(LD) -T linker.ld -o myos.bin boot.o $(CXX_OBJ) -Llibk -lk boot.o: boot.asm $(NASM) -felf32 -o $@ $^ -$(OBJ): %.o : %.cc - $(CXX) -target $(TARGET) $(CXXFLAGS) -I$(INCLUDE) -c $^ -o $@ +$(CXX_OBJ): %.o : %.cc + $(CXX) -target $(TARGET) $(CXX_FLAGS) -I$(CXX_INCLUDE) -c $^ -o $@ + +libk/libk.a: + $(MAKE) -C libk libk.a -iso: +iso: myos.bin mkdir -p isodir/boot/grub cp myos.bin isodir/boot/myos.bin cp grub.cfg isodir/boot/grub/grub.cfg grub-mkrescue -o myos.iso isodir -run: +run: myos.bin qemu-system-i386 -kernel myos.bin clean: - rm boot.o $(OBJ) myos.bin + rm boot.o $(CXX_OBJ) myos.bin + $(MAKE) -C libk clean clean-iso: rm -rf isodir diff --git a/readme.md b/readme.md index 5e5bbdc..72aed4c 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,10 @@ ## Compiling - gnu make -- llvm/clang++ +- llvm/clang (llvm-ar, clang++, ld.lld) - nasm - grub - qemu + +## running +- make run diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h deleted file mode 100644 index 3e6619d..0000000 --- a/stdlib/stdlib.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -class Console { -public: - virtual void write(const String &msg) = 0; -}; - -void console_set(Console *ptr); - -void printk(const String &msg); - -__attribute__((__noreturn__)) void abort(); diff --git a/stdlib/stdlib/console.cc b/stdlib/stdlib/console.cc deleted file mode 100644 index dbc9b86..0000000 --- a/stdlib/stdlib/console.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include "stdlib.h" - -static Console *global_console = nullptr; - -void console_set(Console *ptr) { - if (ptr != nullptr) { - global_console = ptr; - } -} - -void printk(const String &msg) { - if (global_console == nullptr) - return; - - global_console->write(msg); -} - -void abort() { - /* - * On gcc, a 'while(true) {}' will infinitely loop - * but clang will optimize it away on -O2 if it's empty - * therefore, add no-op - */ - while (true) { - asm volatile("nop"); - } - __builtin_unreachable(); -} diff --git a/stdlib/string.cc b/stdlib/string.cc deleted file mode 100644 index 5cd4bb2..0000000 --- a/stdlib/string.cc +++ /dev/null @@ -1,26 +0,0 @@ -#include "string.h" - -// TODO - -// int strcpy(char *dst, const char *stc); -// void strcat(void *dst, const void *src); -// char* strncpy(char *dest, const char *src, int length); -// int strncmp(const char *s1, const char *s2, int c); - -/* strcmp - compare two C-strings */ -constexpr int strcmp(const char *s1, const char *s2) -{ - const auto s1_len = strlen(s1); - for(size_t i = 0; i < s1_len; ++i) { - if(s1[i] == s2[i]) continue; - if(s1[i] > s2[i]) return 1; - if(s1[i] < s2[i]) return -1; - } - return 0; -} - -static_assert(strcmp("one", "one") == 0); -static_assert(strcmp("one", "two") < 0); -static_assert(strcmp("foo", "bar") > 0); - - diff --git a/stdlib/string.h b/stdlib/string.h deleted file mode 100644 index deb6fde..0000000 --- a/stdlib/string.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include "types.h" - -constexpr size_t strlen(const char *str) { - int len = 0; - while (str[len]) - ++len; - return len; -} - -/* reverse: reverse string s in place */ -constexpr void reverse(char s[]) { - int i, j; - char c; - - for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { - c = s[i]; - s[i] = s[j]; - s[j] = c; - } -} - -/* itoa: convert n to characters in s */ -template constexpr void itoa(int n, char s[]) { - int i, sign; - - if ((sign = n) < 0) /* record sign */ - n = -n; /* make n positive */ - - i = 0; - do { /* generate digits in reverse order */ - s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ - } while ((n /= base) > 0); /* delete it */ - - if (sign < 0) - s[i++] = '-'; - - s[i] = '\0'; - - reverse(s); -} - -class String { -public: - class Iterator { - friend class String; - - public: - char next() { return p->buffer[pos++]; } - operator bool() const { return (pos < p->m_length); } - - private: - Iterator(const String *s) : p(s) {} - - size_t pos = 0; - const String *p; - }; - - friend class Iterator; - - String(const char *d) : buffer{d}, m_length{strlen(d)} {} - String(const char *d, size_t l) : buffer{d}, m_length{l} {} - - Iterator begin() const { return Iterator(this); } - -private: - const char *const buffer; - const size_t m_length; -}; diff --git a/stdlib/types.h b/stdlib/types.h deleted file mode 100644 index 0818342..0000000 --- a/stdlib/types.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -typedef unsigned short size_t; -static_assert(sizeof(size_t) >= 2); - - -typedef unsigned char uint8_t; -static_assert(sizeof(uint8_t) == 1); - -typedef unsigned short uint16_t; -static_assert(sizeof(uint16_t) == 2); - -typedef unsigned int uint32_t; -static_assert(sizeof(uint32_t) == 4); - -//typedef unsigned long uint64_t; -//static_assert(sizeof(uint64_t) == 8); - - -typedef char int8_t; -static_assert(sizeof(int8_t) == 1); - -typedef short int16_t; -static_assert(sizeof(int16_t) == 2); - -typedef int int32_t; -static_assert(sizeof(int32_t) == 4); - -//typedef long int64_t; -//static_assert(sizeof(int64_t) == 8); -- cgit v1.2.1