furix
cute os
commit 3bff3f25
| author | dragsbruh <dragsbruh@protonmail.com> |
|---|---|
| date | 2026-09-26 20:53:31 +0530 |
| committer | dragsbruh <dragsbruh@protonmail.com> (2026-09-26 20:53:31 +0530) |
| tree | 7dc7399762b9d2fdfaedf81cef8b1e69dfa86db5 |
| parent |
feat: init repo
+352 -0
.gitignore added +5 -0
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5ddc3f232da01badbd7cc67b5eecdea9b2843e44 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build + +# editor stuff +.ignore +compile_flags.txt
Makefile added +30 -0
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..67049e7ecb0c0b6a115d06b904539d95c3825a26 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +ARCH ?= x86_64 + +CFLAGS := \ + -std=c99 -Wall -Werror -Wextra -pedantic-errors -MMD -MP -g \ + -ffreestanding -fno-builtin -nostdlib -nostdinc -Iinclude + +LDFLAGS := \ + -ffreestanding -nostdlib + +KERNEL_SRC := \ + kernel/kernel.c + +BUILD := build/obj +BUILD_BOOT := build/boot/$(ARCH) + +KERNEL_ELF := $(BUILD_BOOT)/kernel.elf + +.PHONY: all +all: $(KERNEL_ELF) + +.PHONY: clean +clean: + rm -rf build/ + +.PHONY: compile_flags.txt +compile_flags.txt: + @echo $(CFLAGS) | tr ' ' '\n' | tee $@ + +include arch/$(ARCH)/Makefile +include boot/$(ARCH)/Makefile
arch/x86_64/Makefile added +34 -0
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9d25e79ee43490b9f8034a1df1c77cfe0f18b669 --- /dev/null +++ b/arch/x86_64/Makefile @@ -0,0 +1,34 @@ +ifndef KERNEL_SRC +$(error KERNEL_SRC undefined) +endif + +ifndef KERNEL_ELF +$(error KERNEL_ELF undefined) +endif + +ifndef BUILD +$(error BUILD undefined) +endif + +CC := x86_64-elf-gcc + +CFLAGS += \ + -mno-red-zone -mgeneral-regs-only \ + -Iarch/x86_64/include + +LDFLAGS += \ + -Tarch/x86_64/linker.ld + +ARCH_SRC := \ + arch/x86_64/entry.S + +SRC := $(KERNEL_SRC) $(ARCH_SRC) +OBJ := $(patsubst %,$(BUILD)/%.o,$(SRC)) + +$(KERNEL_ELF): $(OBJ) + @mkdir -p $(dir $@) + $(CC) $(LDFLAGS) -o $@ $^ + +$(BUILD)/%.o: % + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -o $@ -c $<
arch/x86_64/entry.S added +177 -0
diff --git a/arch/x86_64/entry.S b/arch/x86_64/entry.S new file mode 100644 index 0000000000000000000000000000000000000000..4c272669b12268577c8d8a563ccd1e8e5a66f853 --- /dev/null +++ b/arch/x86_64/entry.S @@ -0,0 +1,177 @@ +.section .text + +.set PAGE_PRESENT, 1 << 0 +.set PAGE_WRITE, 1 << 1 +.set PAGE_SIZE, 1 << 7 + +.code32 +.global _start +_start: + mov $stack_top, %esp + + mov %ebx, mb_info_ptr + + # clear bss + + mov $__bss_start, %ecx + jmp .bss_zero_check +.bss_zero_loop: + movl $0, (%ecx) + add $4, %ecx +.bss_zero_check: + cmp $__bss_end, %ecx + jb .bss_zero_loop + + # fail if not loaded by multiboot2 + + cmp $MB_BOOTLOADER_MAGIC, %eax + jne .boot_failure + + # map first gb to page_table_l2 + + mov $0, %ecx +.page_loop: + mov %ecx, %eax + shl $21, %eax + + or $(PAGE_PRESENT | PAGE_WRITE | PAGE_SIZE), %eax + mov %eax, page_table_l2(,%ecx,8) + + inc %ecx + cmp $512, %ecx + jne .page_loop + + # the rest of the levels + + mov $page_table_l2, %eax + or $(PAGE_PRESENT | PAGE_WRITE), %eax + mov %eax, page_table_l3 + + mov $page_table_l3, %eax + or $(PAGE_PRESENT | PAGE_WRITE), %eax + mov %eax, page_table_l4 + + # page table addr to CR3 + + mov $page_table_l4, %eax + mov %eax, %cr3 + + # enable PAE (CR4.PAE) + + mov %cr4, %eax + or $(1 << 5), %eax + mov %eax, %cr4 + + # enable long mode (EFER.LME) + + mov $0xc0000080, %ecx + rdmsr + or $(1 << 8), %eax + wrmsr + + # enable paging (CR0.PG) + + mov %cr0, %eax + or $(1 << 31), %eax + mov %eax, %cr0 + + # enable GDT and jump to long mode + + lgdt gdt64_ptr + ljmp $0x08, $long_main + +.boot_failure: + # TODO: more failure cases liek idk cpu doesnt support long mode + + movb $'e', 0xb8000 + movb $' ', 0xb8001 # green + + cli +.halt32: + hlt + jmp .halt32 + +.code64 +long_main: + mov $stack_top, %rsp + + mov $0, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + + call kernel_main + + cli +.halt64: + hlt + jmp .halt64 + +.section .rodata + +mb_info_ptr: + .space 4 + +.set GDT_FL_LONG, 1 << 53 +.set GDT_ACC_RDWR, 1 << 41 +.set GDT_ACC_EXEC, 1 << 43 +.set GDT_ACC_NOTSYS, 1 << 44 +.set GDT_ACC_PRESENT, 1 << 47 + +gdt64: + .quad 0 + .quad GDT_ACC_PRESENT | GDT_ACC_NOTSYS | GDT_ACC_RDWR | GDT_ACC_EXEC | GDT_FL_LONG + .quad GDT_ACC_PRESENT | GDT_ACC_NOTSYS | GDT_ACC_RDWR +gdt64_ptr: + .word . - gdt64 - 1 + .quad gdt64 + +.section .bss + +.align 4096 +page_table_l4: + .space 4096 +page_table_l3: + .space 4096 +page_table_l2: + .space 4096 + +.align 16 +stack_bottom: + .space 1024 * 16 +stack_top: + +.section .multiboot, "a" + +.set MB_BOOTLOADER_MAGIC, 0x36d76289 + +.set MB_MAGIC, 0xE85250D6 +.set MB_ARCH, 0 +.set MB_LENGTH, (multiboot_hdr_end - multiboot_hdr) +.set MB_CHECKSUM, -(MB_LENGTH + MB_ARCH + MB_MAGIC) + +.align 8 +multiboot_hdr: + .long MB_MAGIC + .long MB_ARCH + .long MB_LENGTH + .long MB_CHECKSUM +multiboot_hdr_end: + +.set MB_TAG_END, 0 +.set MB_TAG_INFO_REQ, 1 + +.set MB_INFO_MMAP, 6 + +.align 8 + .word MB_TAG_INFO_REQ + .word 0 + .long 8 + 4 + .long MB_INFO_MMAP + +.align 8 + .word MB_TAG_END + .word 0 + .long 8
arch/x86_64/linker.ld added +44 -0
diff --git a/arch/x86_64/linker.ld b/arch/x86_64/linker.ld new file mode 100644 index 0000000000000000000000000000000000000000..073426c50bb4f0e02d088f1d259a1034c9450b93 --- /dev/null +++ b/arch/x86_64/linker.ld @@ -0,0 +1,44 @@ +ENTRY(_start) + +SECTIONS +{ + . = 1M; + + __kernel_start = ALIGN (4K); + + .multiboot ALIGN (4K) : + { + KEEP(*(.multiboot)) + } + + .text ALIGN (4K) : + { + *(.text) + *(.text.*) + } + + .rodata ALIGN (4K) : + { + *(.rodata) + *(.rodata.*) + } + + .data ALIGN (4K) : + { + *(.data) + *(.data.*) + } + + .bss ALIGN (4K) (NOLOAD) : + { + __bss_start = ALIGN(4); + + *(.bss) + *(.bss.*) + *(COMMON) + + __bss_end = ALIGN(4); + } + + __kernel_end = ALIGN(4K); +}
boot/x86_64/Makefile added +27 -0
diff --git a/boot/x86_64/Makefile b/boot/x86_64/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..dbca3973b86090475c078a410046d4b60370dd3c --- /dev/null +++ b/boot/x86_64/Makefile @@ -0,0 +1,27 @@ +ifndef KERNEL_ELF +$(error KERNEL_ELF undefined) +endif + +ifndef BUILD_BOOT +$(error BUILD_BOOT undefined) +endif + +QEMU := qemu-system-x86_64 +QEMUFLAGS := -m 64M -no-reboot -no-shutdown -d int + +GRUB_CFG := boot/x86_64/grub.cfg + +TARGET_ISO := $(BUILD_BOOT)/image.iso +TARGET_DIR := $(BUILD_BOOT)/isodir + +.PHONY: qemu +qemu: clean $(TARGET_ISO) + $(QEMU) $(QEMUFLAGS) -cdrom $(TARGET_ISO) + +$(TARGET_ISO): $(KERNEL_ELF) + @mkdir -p $(TARGET_DIR)/boot/grub/ + + @cp $(GRUB_CFG) $(TARGET_DIR)/boot/grub/grub.cfg + @cp $(KERNEL_ELF) $(TARGET_DIR)/boot/kernel.elf + + grub-mkrescue -o $(TARGET_ISO) $(TARGET_DIR) 2> /dev/null
boot/x86_64/grub.cfg added +6 -0
diff --git a/boot/x86_64/grub.cfg b/boot/x86_64/grub.cfg new file mode 100644 index 0000000000000000000000000000000000000000..5cf0935ef69f36876586b60f36df304144a3957c --- /dev/null +++ b/boot/x86_64/grub.cfg @@ -0,0 +1,6 @@ +timeout=0 + +menuentry "furix" { + multiboot2 /boot/kernel.elf + boot +}
include/types.h added +15 -0
diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..f66a7be58d535da4f92799edd4e97fb342f1cdaa --- /dev/null +++ b/include/types.h @@ -0,0 +1,15 @@ +#pragma once + +typedef __UINT64_TYPE__ uint64_t; +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT8_TYPE__ uint8_t; + +typedef __INT64_TYPE__ int64_t; +typedef __INT32_TYPE__ int32_t; +typedef __INT16_TYPE__ int16_t; +typedef __INT8_TYPE__ int8_t; + +typedef _Bool bool; +#define true 1 +#define false 0
kernel/kernel.c added +14 -0
diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000000000000000000000000000000000000..57af06c3bf8fb81378a2b946c4c8f73ad6a89a5e --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,14 @@ +#include <types.h> + +typedef struct { + uint8_t chr; + uint8_t attr; +} vgachar_t; + +volatile vgachar_t *display = (vgachar_t *)0xb8000; + +void kernel_main(void) { + char meow[] = "meow :3 hello world!"; + for (uint64_t i = 0; i < sizeof(meow); i++) + display[i] = (vgachar_t){.chr = meow[i], .attr = ' '}; +}