diff --git a/Makefile b/Makefile index 98823ff..c71d52a 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ CC := i686-elf-gcc LD := i686-elf-ld AS := nasm -CFLAGS := -g -std=c17 -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ - -Os -nostdinc -mgeneral-regs-only -m32 -march=i386 -Wall -Iinclude/c +CCFLAGS := -g -std=c17 -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ + -Os -nostdinc -mgeneral-regs-only -m32 -march=i386 -Wall LDFLAGS := -z notext -melf_i386 -nostdlib ASFLAGS := @@ -12,61 +12,78 @@ include make.config SRC := ./src BIN := ./bin +LIBK_INC := ./include +LIBC_INC := ./include/libc +LIBC_DIR := ./libc +LIBK_DIR := ./libk + C_FILES := calc edit FONTS := testfont term16n +BOOTLOADER := $(BIN)/stage1.bin $(BIN)/stage2.bin $(BIN)/stage3.bin +KERNEL := $(BIN)/kernel.bin +LIBC := $(BIN)/libc.o +# TODO: LIBK := $(BIN)/libk.o +ISO := kern.iso + .PHONY: os clean run # Main compilation target -os: $(BIN) bootloader kernel $(C_FILES) $(FONTS) - @cc ./makedisk.c -o ./makedisk - @./makedisk # TODO: List of files +os: $(ISO) +$(ISO): $(BIN) $(BOOTLOADER) $(KERNEL) $(C_FILES) $(FONTS) + cc ./makedisk.c -o ./makedisk + ./makedisk # TODO: List of files @echo "\nDone!\n" $(BIN): - @[ -d $(BIN) ] || mkdir $(BIN) - @rm -rf $(BIN)/* + [ -d $(BIN) ] || mkdir $(BIN) + rm -rf $(BIN)/* # Bootloader: This target is responsible for creating stage?.bin (1,2,3) -bootloader: $(SRC)/stage1.asm $(SRC)/stage2.asm +$(BOOTLOADER): $(SRC)/stage1.asm $(SRC)/stage2.asm $(SRC)/stage3.c $(LIBC) @echo "Assembling $(SRC)/stage1.asm..." - @$(AS) -fbin -o $(BIN)/stage1.bin $(SRC)/stage1.asm $(ASFLAGS) + $(AS) -fbin -o $(BIN)/stage1.bin $(SRC)/stage1.asm $(ASFLAGS) @echo "Assembling $(SRC)/stage2.asm..." - @$(AS) -fbin -o $(BIN)/stage2.bin $(SRC)/stage2.asm $(ASFLAGS) + $(AS) -fbin -o $(BIN)/stage2.bin $(SRC)/stage2.asm $(ASFLAGS) @echo "Compiling $(SRC)/stage3.c..." - @$(CC) $(CFLAGS) -Iinclude -o $(BIN)/stage3.o -c $(SRC)/stage3.c - @$(LD) $(LDFLAGS) -T$(SRC)/stage3.ld --oformat binary -o $(BIN)/stage3.bin $(BIN)/stage3.o - @rm $(BIN)/stage3.o + $(CC) $(CCFLAGS) -I$(LIBK_INC) -I$(LIBC_INC) -o $(BIN)/stage3.o -c $(SRC)/stage3.c + $(LD) $(LDFLAGS) -T$(SRC)/stage3.ld --oformat binary -o $(BIN)/stage3.bin $(BIN)/stage3.o $(LIBC) + rm $(BIN)/stage3.o # Kernel: This target is responsible for creating kernel.bin -kernel: $(SRC)/kernel.c +$(KERNEL): $(SRC)/kernel.c $(LIBC) #TODO: $(LIBK) @echo "Compiling $(SRC)/kernel.c..." - @$(CC) $(CFLAGS) -Iinclude -o $(BIN)/kernel.o -c $(SRC)/kernel.c - @$(LD) $(LDFLAGS) -T$(SRC)/kernel.ld --oformat binary -o $(BIN)/kernel.bin $(BIN)/kernel.o - @rm $(BIN)/kernel.o + $(CC) $(CCFLAGS) -I$(LIBK_INC) -I$(LIBC_INC) -o $(BIN)/kernel.o -c $(SRC)/kernel.c + $(LD) $(LDFLAGS) -T$(SRC)/kernel.ld --oformat binary -o $(BIN)/kernel.bin $(BIN)/kernel.o $(LIBC) #TODO: LIBK + rm $(BIN)/kernel.o # This target compiles *.c (except kernel.c) -$(C_FILES): +$(C_FILES): $(LIBC) @echo "Compiling $(SRC)/$@.c..." - @$(CC) $(CFLAGS) -o $(BIN)/$@.o -c $(SRC)/$@.c - @$(LD) $(LDFLAGS) -T$(SRC)/$@.ld --oformat binary -o $(BIN)/$@.bin $(BIN)/$@.o - @rm $(BIN)/$@.o + $(CC) $(CCFLAGS) -I$(LIBC_INC) -o $(BIN)/$@.o -c $(SRC)/$@.c + $(LD) $(LDFLAGS) -T$(SRC)/$@.ld --oformat binary -o $(BIN)/$@.bin $(BIN)/$@.o $(LIBC) + rm $(BIN)/$@.o -# This target builds all fonts inside src/fonts +$(LIBC): $(LIBC_DIR)/**.c + @echo "Compiling $(LIBC)..." + mkdir -p $(BIN)/libc + for f in libc/*.c; do $(CC) $(CCFLAGS) -I$(LIBC_INC) -o $(BIN)/$$f.o -c $$f; done + $(LD) $(LDFLAGS) -r -o $(LIBC) $(BIN)/libc/**.o + +# This target retrieves all fonts inside src/fonts $(FONTS): - @cp $(SRC)/fonts/$@.fnt $(BIN)/$@.fnt + cp $(SRC)/fonts/$@.fnt $(BIN)/$@.fnt # Run QEMU run: qemu-system-x86_64\ - -drive format=raw,file="./kern.iso",index=0,media=disk\ + -drive format=raw,file=$(ISO),index=0,media=disk\ -m 256M -accel tcg -monitor stdio\ -rtc base=localtime,clock=host,driftfix=slew\ -audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 # Clean all build files clean: - @rm -rf $(BIN) - @#rm -f kern.iso - @rm -f makedisk + rm -rf $(BIN) + rm -f makedisk diff --git a/include/libc/color.h b/include/libc/color.h new file mode 100644 index 0000000..b303c8f --- /dev/null +++ b/include/libc/color.h @@ -0,0 +1,15 @@ +#ifndef COLOR_H +#define COLOR_H + +#define BLACK 0x00000000 // 0 +#define RED 0x00ff0000 // 1 +#define GREEN 0x0000ff00 // 2 +#define YELLOW 0x00ffff00 // 3 +#define BLUE 0x000000ff // 4 +#define MAGENTA 0x00ff00ff // 5 +#define CYAN 0x0000ffff // 6 +#define WHITE 0x00ffffff // 7 + +uint32_t codeToColor(uint8_t code); + +#endif diff --git a/include/c/math.h b/include/libc/math.h similarity index 100% rename from include/c/math.h rename to include/libc/math.h diff --git a/include/c/stdarg.h b/include/libc/stdarg.h similarity index 100% rename from include/c/stdarg.h rename to include/libc/stdarg.h diff --git a/include/c/stdbool.h b/include/libc/stdbool.h similarity index 100% rename from include/c/stdbool.h rename to include/libc/stdbool.h diff --git a/include/c/stddef.h b/include/libc/stddef.h similarity index 100% rename from include/c/stddef.h rename to include/libc/stddef.h diff --git a/include/c/stdint.h b/include/libc/stdint.h similarity index 100% rename from include/c/stdint.h rename to include/libc/stdint.h diff --git a/include/libc/stdio.h b/include/libc/stdio.h new file mode 100644 index 0000000..82315dd --- /dev/null +++ b/include/libc/stdio.h @@ -0,0 +1,41 @@ +#ifndef STDIO_H +#define STDIO_H + +#include + +// Nobody should have to interface with the internals of this structure +typedef struct _iobuf { // 24B + unsigned char* _ptr; // File buffer base + unsigned int _size; // Size of buffer + int _offset; // Offset into file + unsigned short _flag; // Open flags + int _file; // File descriptor + + char __reserved[6]; +} FILE; + +// Standard file pointers +extern FILE* stdin; +extern FILE* stdout; +extern FILE* stderr; + +/* File IO */ +FILE* fopen(const char* filename, const char* mode); +int fclose(FILE* stream); +size_t fread(void* ptr, size_t size, size_t count, FILE* stream); +size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream); +int fseek(FILE* stream, long int origin, int offset); +long int ftell(FILE* stream); + +/* Terminal IO */ +int printf(const char* fmt, ...); +int sprintf(char* str, const char* fmt, ...); +int snprintf(char* str, size_t n, const char* fmt, ...); +int fprintf(FILE* stream, const char* fmt, ...); +void putc(char c); +char getc(); +void print(const char* str); +void clear(); +void reads(char* str); + +#endif diff --git a/include/libc/stdlib.h b/include/libc/stdlib.h new file mode 100644 index 0000000..f02dfed --- /dev/null +++ b/include/libc/stdlib.h @@ -0,0 +1,10 @@ +#ifndef STDLIB_H +#define STDLIB_H + +#include +#include + +void* malloc(const uint32_t size); +void free(const void* ptr); + +#endif diff --git a/include/libc/string.h b/include/libc/string.h new file mode 100644 index 0000000..0bd6b49 --- /dev/null +++ b/include/libc/string.h @@ -0,0 +1,23 @@ +#ifndef STRING_H +#define STRING_H + +#include + +void* memcpy(void* src, void* dst, uint32_t length); +void* memcpy32(void* src, void* dst, uint32_t length); +void* memset(void* dst, uint8_t value, uint32_t length); + +char* itoa(uint32_t val, uint8_t base); +uint32_t atoi(const char* str); +int isSpace(char c); +char* strcpy(char* str1, const char* str2); +char* strncpy(char* str1, const char* str2, size_t n); +char* strcat(char* str1, const char* str2); +char* strncat(char* str1, const char* str2, size_t n); +char* strchr(const char* str, char c); +char* strrchr(const char* str, char c); +int strcmp(const char* str1, const char* str2); +int strncmp(const char* str1, const char* str2, size_t n); +uint32_t strlen(const char* str); + +#endif diff --git a/include/libc/syscall.h b/include/libc/syscall.h new file mode 100644 index 0000000..317bc43 --- /dev/null +++ b/include/libc/syscall.h @@ -0,0 +1,38 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +#include + +#define MAX_SYSCALLS 9 + +typedef enum { + SYS_RESERVED, + SYS_SLEEP, + SYS_READ, + SYS_WRITE, + SYS_OPEN, + SYS_CLOSE, + SYS_MALLOC, + SYS_FREE, + SYS_SEEK, +} SYSCALL_NUMBERS; + +typedef enum { + O_CREAT = 0x01, // Create if does not exist + O_RDONLY = 0x02, // Read only + O_WRONLY = 0x04, // Write only + O_RDWR = 0x08, // Read and write + O_APPEND = 0x10, // Always writes at the end (appends) + O_TRUNC = 0x20, // Truncate file size and position to 0 on Open + O_BIN = 0x40, // Read bytes, not text +} OFLAGS; + +int syscall(int nr, int arg0, int arg1, int arg2); + +/* Syscall wrappers */ +int read(int fd, void* ptr, size_t count); +int write(int fd, const void* ptr, size_t count); +int open(const char* path, int oflag); +int close(int fd); + +#endif diff --git a/include/libc/time.h b/include/libc/time.h new file mode 100644 index 0000000..cfeb5a4 --- /dev/null +++ b/include/libc/time.h @@ -0,0 +1,8 @@ +#ifndef TIME_H +#define TIME_H + +#include + +void sleep(uint32_t ms); + +#endif diff --git a/kern.iso b/kern.iso index 094b8a7..5f7c6d2 100644 Binary files a/kern.iso and b/kern.iso differ diff --git a/include/c/_fileio.h b/libc/_fileio.c similarity index 73% rename from include/c/_fileio.h rename to libc/_fileio.c index 9a9cde8..faa2ac1 100644 --- a/include/c/_fileio.h +++ b/libc/_fileio.c @@ -1,25 +1,8 @@ -#ifndef _FILEIO_H -#define _FILEIO_H - +#include #include #include #include -// Nobody should have to interface with the internals of this structure -typedef struct _iobuf { // 24B - unsigned char* _ptr; // File buffer base - unsigned int _size; // Size of buffer - int _offset; // Offset into file - unsigned short _flag; // Open flags - int _file; // File descriptor - - char __reserved[6]; -} FILE; - -FILE* stdin; -FILE* stdout; -FILE* stderr; - FILE* fopen(const char* filename, const char* mode) { int oflag = O_RDWR | O_CREAT | O_BIN; // TODO! @@ -79,5 +62,3 @@ long int ftell(FILE* stream) { return -1; } -#endif - diff --git a/include/c/_printf.h b/libc/_printf.c similarity index 96% rename from include/c/_printf.h rename to libc/_printf.c index cd3457f..de4d8f9 100644 --- a/include/c/_printf.h +++ b/libc/_printf.c @@ -1,14 +1,11 @@ -#ifndef _PRINTF_H -#define _PRINTF_H - +#include #include #include #include #include #include -#include <_fileio.h> -// Warning: returns a allocated buffer, must be freed! +// Warning: returns an allocated buffer, must be freed! char* _format(const char* fmt, va_list args) { static char* buffer; size_t len = 0; @@ -126,5 +123,3 @@ int printf(const char* fmt, ...) { return len; } -#endif - diff --git a/include/c/color.h b/libc/color.c similarity index 53% rename from include/c/color.h rename to libc/color.c index f366336..b2eabf0 100644 --- a/include/c/color.h +++ b/libc/color.c @@ -1,14 +1,5 @@ -#ifndef COLOR_H -#define COLOR_H - -#define BLACK 0x00000000 // 0 -#define RED 0x00ff0000 // 1 -#define GREEN 0x0000ff00 // 2 -#define YELLOW 0x00ffff00 // 3 -#define BLUE 0x000000ff // 4 -#define MAGENTA 0x00ff00ff // 5 -#define CYAN 0x0000ffff // 6 -#define WHITE 0x00ffffff // 7 +#include +#include uint32_t codeToColor(uint8_t code) { switch (code) { @@ -24,4 +15,3 @@ uint32_t codeToColor(uint8_t code) { } } -#endif diff --git a/libc/math.c b/libc/math.c new file mode 100644 index 0000000..e23694d --- /dev/null +++ b/libc/math.c @@ -0,0 +1,16 @@ +#ifndef MATH_H +#define MATH_H + +// Constants +#define PI 3.141592653589 // Should be good enough +#define E 2.718281828459 + +// Macros +#define abs(x) ( (x) > 0 ? (x) : -(x) ) +#define sign(x) ( (x) == 0 ? 0 : ((x) < 0 ? -1 : 1 ) ) + +#define floor(x) ( (int)(x) ) // C floors floats when converting to ints +#define round(x) ( (int)((x) + 0.5) ) // Normal rounding +#define ceil(x) ( (int)((x) + 1) ) // Always rounds up + +#endif diff --git a/libc/stdarg.c b/libc/stdarg.c new file mode 100644 index 0000000..c5f3ec8 --- /dev/null +++ b/libc/stdarg.c @@ -0,0 +1,10 @@ +#ifndef STDARG_H +#define STDARG_H + +typedef char* va_list; +#define va_start(ap, paramn) (void)((ap) = (char*)(&(paramn) + 1)) +#define va_end(ap) (void)((ap) = 0) +#define va_arg(ap, type) (((type*)((ap) = ((ap) + sizeof(type))))[-1]) + +#endif + diff --git a/libc/stdbool.c b/libc/stdbool.c new file mode 100644 index 0000000..98349dc --- /dev/null +++ b/libc/stdbool.c @@ -0,0 +1,8 @@ +#ifndef BOOL_H +#define BOOL_H + +#define bool _Bool +#define true 1 +#define false 0 + +#endif diff --git a/libc/stddef.c b/libc/stddef.c new file mode 100644 index 0000000..fbe6e30 --- /dev/null +++ b/libc/stddef.c @@ -0,0 +1,9 @@ +#ifndef STDDEF_H +#define STDDEF_H + +#define NULL ((void*)0) + +typedef unsigned int size_t; +typedef signed int ssize_t; + +#endif diff --git a/libc/stdint.c b/libc/stdint.c new file mode 100644 index 0000000..acc4ea0 --- /dev/null +++ b/libc/stdint.c @@ -0,0 +1,20 @@ +#ifndef STDINT_H +#define STDINT_H + +#include + +// Signed ints +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long long int64_t; + +// Unsigned ints +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +// TODO: floats + +#endif diff --git a/include/c/stdio.h b/libc/stdio.c similarity index 83% rename from include/c/stdio.h rename to libc/stdio.c index 08255b1..6995f74 100644 --- a/include/c/stdio.h +++ b/libc/stdio.c @@ -1,20 +1,12 @@ -#ifndef STDIO_H -#define STDIO_H - +#include #include #include #include #include -/* Declarations */ -void putc(char); -char getc(); - -int printf(const char*, ...); - -/* STDIO Include */ -#include <_fileio.h> -#include <_printf.h> +FILE* stdin; +FILE* stdout; +FILE* stderr; void putc(char c) { // write(stdout, &c, 1); TODO: This doesn't work and we need to use a static variable @@ -59,4 +51,3 @@ void reads(char* buffer) { buffer[len] = '\0'; // Null terminate } -#endif diff --git a/include/c/stdlib.h b/libc/stdlib.c similarity index 82% rename from include/c/stdlib.h rename to libc/stdlib.c index e8bc904..5c623ea 100644 --- a/include/c/stdlib.h +++ b/libc/stdlib.c @@ -1,8 +1,6 @@ -#ifndef STDLIB_H -#define STDLIB_H - #include #include +#include void* malloc(const uint32_t size) { return (void*)syscall(SYS_MALLOC, size, 0, 0); @@ -12,4 +10,3 @@ void free(const void* ptr) { syscall(SYS_FREE, (int)ptr, 0, 0); } -#endif diff --git a/include/c/string.h b/libc/string.c similarity index 92% rename from include/c/string.h rename to libc/string.c index a3b25e0..ea6a71b 100644 --- a/include/c/string.h +++ b/libc/string.c @@ -1,12 +1,6 @@ -#ifndef STRING_H -#define STRING_H - +#include #include -void* memcpy(void* src, void* dst, uint32_t length); -void* memcpy32(void* src, void* dst, uint32_t length); -void* memset(void* dst, uint8_t value, uint32_t length); - // Source: http://www.strudel.org.uk/itoa/ char* itoa(uint32_t val, uint8_t base) { static char buf[32] = { 0 }; @@ -84,7 +78,7 @@ char* strchr(const char* str, char c) { return (*s == c) ? (char*)s : NULL; } -// char* strrchr(const char* str, char c); +char* strrchr(const char* str, char c) { return NULL; } // TODO int strcmp(const char* str1, const char* str2) { while (*str1 != '\0' && *str1 == *str2) { @@ -140,4 +134,3 @@ void* memset(void* dst, uint8_t value, uint32_t length) { return dst; } -#endif diff --git a/include/c/syscall.h b/libc/syscall.c similarity index 54% rename from include/c/syscall.h rename to libc/syscall.c index 2070b58..ef8ee20 100644 --- a/include/c/syscall.h +++ b/libc/syscall.c @@ -1,32 +1,8 @@ -#ifndef SYSCALL_H -#define SYSCALL_H - +#include #include #define MAX_SYSCALLS 9 -typedef enum { - SYS_RESERVED, - SYS_SLEEP, - SYS_READ, - SYS_WRITE, - SYS_OPEN, - SYS_CLOSE, - SYS_MALLOC, - SYS_FREE, - SYS_SEEK, -} SYSCALL_NUMBERS; - -typedef enum { - O_CREAT = 0x01, // Create if does not exist - O_RDONLY = 0x02, // Read only - O_WRONLY = 0x04, // Write only - O_RDWR = 0x08, // Read and write - O_APPEND = 0x10, // Always writes at the end (appends) - O_TRUNC = 0x20, // Truncate file size and position to 0 on Open - O_BIN = 0x40, // Read bytes, not text -} OFLAGS; - int syscall(int nr, int arg0, int arg1, int arg2) { int ret = 0; __asm__ volatile ("int $0x80" : "=a"(ret) : "a"(nr), "b"(arg0), "c"(arg1), "d"(arg2)); @@ -54,4 +30,3 @@ int close(int fd) { return syscall(SYS_CLOSE, fd, 0, 0); } -#endif diff --git a/include/c/time.h b/libc/time.c similarity index 72% rename from include/c/time.h rename to libc/time.c index 7842c93..ede1bf4 100644 --- a/include/c/time.h +++ b/libc/time.c @@ -1,11 +1,7 @@ -#ifndef TIME_H -#define TIME_H - +#include #include #include void sleep(uint32_t ms) { syscall(SYS_SLEEP, ms, 0, 0); } - -#endif diff --git a/src/kernel.c b/src/kernel.c index daa0d5c..fe8e4f0 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -93,6 +93,7 @@ void main() { // Run Interactive Shell Program // TODO: Make it in another file while (1) { + printf("\e[6M\x7f\x80\n"); printf("\e[6M\e[8N%s \e[2M%s \e[8M", cwd, PROMPT); char input[256]; char* inputPtr = input; diff --git a/src/stage3.c b/src/stage3.c index c26beb0..65b40a5 100644 --- a/src/stage3.c +++ b/src/stage3.c @@ -6,6 +6,7 @@ #include #include #include +#include void bigError();