diff --git a/Makefile b/Makefile index cb28362..102f460 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,16 @@ +.PHONY: quark +quark: build-dir kernel + +include config/.conf include scripts/toolchain.mk - -BUILD_DIR?=build/ - -quark: build-dir $(BUILD_DIR)/quark +include scripts/kernel.mk +include scripts/run.mk .PHONY: build-dir build-dir: @mkdir -p $(BUILD_DIR) + @echo -e $(ARROW) "Created build directory" + +.PHONY: clean +clean: + @rm -rf $(BUILD_DIR)/** diff --git a/config/.conf b/config/.conf new file mode 100644 index 0000000..9f43b93 --- /dev/null +++ b/config/.conf @@ -0,0 +1,20 @@ +# CONFIG # + +BUILD_DIR ?= $(abspath build/) + +TARGET = i686-elf +TARGET_ASM = nasm +TARGET_ASMFLAGS = +TARGET_CFLAGS = -std=c99 -g +TARGET_CC = $(TARGET)-gcc +TARGET_CXX = $(TARGET)-g++ +TARGET_LD = $(TARGET)-gcc +TARGET_LINKFLAGS = +TARGET_LIBS = + +BINUTILS_VERSION = 2.37 +BINUTILS_URL = https://ftp.gnu.org/gnu/binutils/binutils-$(BINUTILS_VERSION).tar.xz +GCC_VERSION = 11.1.0 +GCC_URL = https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.gz + +ARROW = "\x1b[32m-->\x1b[0m" diff --git a/config/toolchain.conf b/config/toolchain.conf deleted file mode 100644 index db9d102..0000000 --- a/config/toolchain.conf +++ /dev/null @@ -1,15 +0,0 @@ -# TOOLCHAIN CONFIGURATION FILE - -export TARGET = i686-elf -export TARGET_ASM = nasm -export TARGET_ASMFLAGS = -export TARGET_CFLAGS = -std=c99 -g -export TARGET_CC = $(TARGET)-gcc -export TARGET_CXX = $(TARGET)-g++ -export TARGET_LD = $(TARGET)-gcc -export TARGET_LINKFLAGS = -export TARGET_LIBS = -BINUTILS_VERSION = 2.37 -BINUTILS_URL = https://ftp.gnu.org/gnu/binutils/binutils-$(BINUTILS_VERSION).tar.xz -GCC_VERSION = 11.1.0 -GCC_URL = https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.gz diff --git a/scripts/kernel.ld b/scripts/kernel.ld new file mode 100644 index 0000000..6640fdd --- /dev/null +++ b/scripts/kernel.ld @@ -0,0 +1,25 @@ +ENTRY(_start) +phys = 0x00100000; + +SECTIONS{ + .text phys : AT(phys){ + code = .; + *(.text) + *(.rodata) + . = ALIGN(4096); + } + + .data : AT(phys + (data - code)){ + data = .; + *(.data) + . = ALIGN(4096); + } + + .bss : AT(phys + (bss - code)){ + bss = .; + *(.bss) + . = ALIGN(4096); + } + + end = .; +} diff --git a/scripts/kernel.mk b/scripts/kernel.mk new file mode 100644 index 0000000..163b71c --- /dev/null +++ b/scripts/kernel.mk @@ -0,0 +1,23 @@ +.PHONY: kernel +kernel: $(BUILD_DIR)/kernel.bin + +HEADERS_C = $(shell find src/kernel -type f -name "*.h") +SOURCES_C = $(shell find src/kernel -type f -name "*.c") +OBJECTS_C = $(patsubst src/kernel/%.c, $(BUILD_DIR)/kernel/c/%.obj, $(SOURCES_C)) +HEADERS_ASM = $(shell find src/kernel -type f -name "*.inc") +SOURCES_ASM = $(shell find src/kernel -type f -name "*.asm") +OBJECTS_ASM = $(patsubst src/kernel/%.asm, $(BUILD_DIR)/kernel/asm/%.obj, $(SOURCES_ASM)) + +$(BUILD_DIR)/kernel.bin: $(OBJECTS_ASM) $(OBJECTS_C) + @$(TARGET_LD) $(TARGET_LINKFLAGS) -T scripts/kernel.ld -nostdlib -Wl,-Map=$(BUILD_DIR)/kernel.map -o $@ $^ $(TARGET_LIBS) -lgcc + @echo -e $(ARROW) "Created $(basename $@)" + +$(BUILD_DIR)/kernel/c/%.obj: src/kernel/%.c $(HEADERS_C) + @mkdir -p $(@D) + @$(TARGET_CC) $(TARGET_CFLAGS) -ffreestanding -nostdlib -c -o $@ $< + @echo -e $(ARROW) "Compiled $<" + +$(BUILD_DIR)/kernel/asm/%.obj: src/kernel/%.asm $(HEADERS_ASM) + @mkdir -p $(@D) + @$(TARGET_ASM) $(TARGET_ASMFLAGS) -f elf -o $@ $< + @echo -e $(ARROW) "Assembled $<" diff --git a/scripts/run.mk b/scripts/run.mk new file mode 100644 index 0000000..904cb18 --- /dev/null +++ b/scripts/run.mk @@ -0,0 +1,8 @@ +.PHONY: run +run: quark run-qemu + +.PHONY: run-qemu +run-qemu: + @echo -e $(ARROW) "Running on qemu..." + @qemu-system-i386 -kernel $(BUILD_DIR)/kernel.bin + @echo -e $(ARROW) "Finished run" diff --git a/scripts/toolchain.mk b/scripts/toolchain.mk index 31aa2d8..26b6828 100644 --- a/scripts/toolchain.mk +++ b/scripts/toolchain.mk @@ -1,5 +1,3 @@ -include config/toolchain.conf - TOOLCHAIN_PREFIX = $(abspath toolchain/$(TARGET)) export PATH := $(TOOLCHAIN_PREFIX)/bin:$(PATH) diff --git a/src/kernel/arch/i686/io.asm b/src/kernel/arch/i686/io.asm new file mode 100644 index 0000000..e31e1fe --- /dev/null +++ b/src/kernel/arch/i686/io.asm @@ -0,0 +1,31 @@ +global i686_inb +i686_inb: + [bits 32] + mov dx, [esp + 4] + xor eax, eax + in al, dx + ret + +global i686_outb +i686_outb: + [bits 32] + mov dx, [esp + 4] + mov al, [esp + 8] + out dx, al + ret + +global i686_inw +i686_inw: + [bits 32] + mov dx, [esp + 4] + xor eax, eax + in ax, dx + ret + +global i686_outw +i686_outw: + [bits 32] + mov dx, [esp + 4] + mov ax, [esp + 8] + out dx, ax + ret diff --git a/src/kernel/arch/i686/io.h b/src/kernel/arch/i686/io.h new file mode 100644 index 0000000..9e919e7 --- /dev/null +++ b/src/kernel/arch/i686/io.h @@ -0,0 +1,6 @@ +#include + +uint8_t __attribute__((cdecl)) i686_inb(uint16_t port); +void __attribute__((cdecl)) i686_outb(uint16_t port, uint8_t value); +uint16_t __attribute__((cdecl)) i686_inw(uint16_t port); +void __attribute__((cdecl)) i686_outw(uint16_t port, uint16_t value); diff --git a/src/kernel/entry.asm b/src/kernel/entry.asm new file mode 100644 index 0000000..1ac368e --- /dev/null +++ b/src/kernel/entry.asm @@ -0,0 +1,34 @@ +[bits 32] +extern kmain +extern i686_outw +global _start + +_start: + mov esp, _sys_stack + jmp call_kmain + +; Multiboot header +align 4 +mboot: + ; Some macros + MULTIBOOT_PAGE_ALIGN equ 1<<0 + MULTIBOOT_MEMORY_INFO equ 1<<1 + MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 + MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO + MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) + + ; The actual header + dd MULTIBOOT_HEADER_MAGIC + dd MULTIBOOT_HEADER_FLAGS + dd MULTIBOOT_CHECKSUM + +call_kmain: + call kmain + push 0x2000 + push 0x604 + call i686_outw + jmp $ + +section .bss + resb 8192 ; For the stack +_sys_stack: diff --git a/src/kernel/main.c b/src/kernel/main.c new file mode 100644 index 0000000..52099ad --- /dev/null +++ b/src/kernel/main.c @@ -0,0 +1,7 @@ +#include +#include "arch/i686/io.h" + +void __attribute__((cdecl)) kmain(uint64_t magic, uint64_t addr){ + char *mem = (char *)0xB8000; // Screen memory address (when on text mode) + for(int i = 0; 1; i++) mem[i] = 88; // Fill screen with Blue 'X' characters over pink background +}