diff --git a/README.md b/README.md index f6fbc5b..fa0230d 100755 --- a/README.md +++ b/README.md @@ -3,11 +3,12 @@ The Soaplin kernel is a new Unix-like operating system kernel. ## Features * x86_64 support (kinda) -* Memory management (VMM/PMM) +* Memory management (VMM/PMM/VMA/kmalloc) * Simple pre-emptive scheduler * Ring 3 (user mode) support * ELF loader * ACPI +* Symetric Multiprocessing (It runs code, but the scheduler is running on 1 processor.) ## In the works * Virtual File System @@ -17,7 +18,7 @@ The Soaplin kernel is a new Unix-like operating system kernel. * RTC support * EXT2 driver * FAT32 driver -* CPIO-based init ram disk +* TAR-based init ram disk * Video driver for Bochs graphics adapter, and the VMware display adapter. ## Known bugs @@ -26,12 +27,13 @@ The Soaplin kernel is a new Unix-like operating system kernel. ## Building To build Soaplin, you must ensure you have these: * The Netwide Assembler (nasm) -* A compiler (In the future, a custom toolchain would be built.) -* A linker +* A compiler (both GCC & Clang works!) (In the future, a custom toolchain would be built.) +* A linker (both GNU LD & LLVM linker works too!) Clone the repo, and run "make" in it! ## Acknowledgements Thanks to all these people :heart: +* Limine contributors: The Limine bootloader, used for kicking up Soaplin * Kevin Alavik (kevinalavik): VMAs implementation * Astrido (asterd-og): IOAPIC/LAPIC (from ZanOS) \ No newline at end of file diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index 7350da5..84475d5 100755 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -58,7 +58,9 @@ override CFLAGS += \ -fno-stack-check \ -fno-PIC \ -ffunction-sections \ - -fdata-sections + -fdata-sections \ + -fno-omit-frame-pointer \ + -fno-optimize-sibling-calls # Internal C preprocessor flags that should not be changed by the user. override CPPFLAGS := \ diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c index 34e7df3..0839c78 100644 --- a/kernel/src/arch/x86_64/syscall.c +++ b/kernel/src/arch/x86_64/syscall.c @@ -10,7 +10,7 @@ void __x86_64_syscall_init() { wrmsr(IA32_EFER, efer); uint64_t star = 0; star |= ((uint64_t)0x28 << 32); // kernel cs - star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) + star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x40, 24 for SS=0x38) wrmsr(IA32_STAR, star); wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); wrmsr(IA32_CSTAR, 0x0); diff --git a/kernel/src/main.c b/kernel/src/main.c index e1dde83..c4c4935 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -57,7 +57,11 @@ struct flanterm_context *ft_ctx; char kstack[8192]; -void kmain(void) { +void test3() { *((uint8_t*)0x0) = (uint8_t)0xFF; } +void test2() { test3();} +void test1() { test2(); } + +void __kmain(void) { if (framebuffer_request.response != NULL) { struct limine_framebuffer *framebuffer = @@ -97,6 +101,7 @@ void kmain(void) { syscall_init(); sched_init(); + test1(); // vfs_init(); @@ -105,6 +110,7 @@ void kmain(void) { program_t *p = elf_load(module_request.response->modules[0]->address, 1); + sched_process *proc = sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS); @@ -112,6 +118,5 @@ void kmain(void) { pit_enable(); while (1) - ; - ; + ;; } diff --git a/kernel/src/premain.asm b/kernel/src/premain.asm new file mode 100644 index 0000000..b06f99b --- /dev/null +++ b/kernel/src/premain.asm @@ -0,0 +1,10 @@ +bits 64 +section .text + global kmain + extern __kmain + extern kstack + +kmain: + mov rsp, kstack+0x2000 ; supposons 16 KiB de stack + xor rbp, rbp ; Set %ebp to NULL + call __kmain \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c index b4d8274..1a82fd8 100644 --- a/kernel/src/sys/errhnd/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -1,3 +1,4 @@ +#include "sys/errhnd/panic.h" #include "arch/x86_64/idt.h" #include "lib/spinlock.h" #include @@ -59,7 +60,9 @@ static void __panic_display_page_fault(registers_t *regs) { uint64_t cr2; asm volatile("mov %%cr2, %0" : "=r"(cr2)); - log("Page Fault Details:\n"); + log("-- PAGE FAULT DETAILS --\n"); + log("This appears to be a page fault.\n"); + log("\n"); log("Faulting Address (CR2): 0x%lx\n", cr2); log("Error Code: %d\n", regs->err_code); log("Flags:\n"); @@ -83,6 +86,7 @@ static void __panic_display_page_fault(registers_t *regs) { if (regs->err_code & (1 << 4)) log(" - Instruction Fetch\n"); + log("\n"); } static void __panic_display_regs(registers_t *regs) { @@ -96,11 +100,60 @@ static void __panic_display_regs(registers_t *regs) { regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no, regs->err_code); log("RSP: %p\n", regs->rsp); + log("\n"); if (regs->int_no == 14) // If it's a page fault __panic_display_page_fault(regs); } +static void __panic_display_bt(registers_t *regs) { + if (regs->cs == 0x43 || regs->cs == 0x3B) { + log("The backtrace can't be dumped from a userspace process.\n"); + return; // Don't try to backtrace userspace + } + + log("-- BACKTRACE --\n"); + + // First print the current instruction pointer from the interrupt frame + if (regs->rip) { + log("* %p (current)\n", regs->rip); + } + + uint64_t *frame = (uint64_t*)regs->rbp; + if (!frame || (uint64_t)frame < 0xffffffff80000000) { + log("No further stack frames available\n"); + return; + } + + // Frame format in x86_64: + // [rbp] -> previous rbp + // [rbp+8] -> return address + int depth = 0; + while (frame && depth < 16) { // Limit depth to avoid infinite loops + // Validate both frame and return address pointers + uint64_t *ret_addr_ptr = frame + 1; + if ((uint64_t)ret_addr_ptr < 0xffffffff80000000) { + break; + } + + uint64_t ret_addr = *ret_addr_ptr; + if (ret_addr < 0xffffffff80000000 || ret_addr > 0xfffffffffffff000) { + break; + } + + log("* %p\n", ret_addr); + + uint64_t next_rbp = *frame; + if (next_rbp < 0xffffffff80000000 || next_rbp > 0xfffffffffffff000) { + break; + } + + frame = (uint64_t*)next_rbp; + depth++; + } + log("\n"); +} + void __panic_display_ascii_art() { log(" _ __ _ ___ _ \n"); log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n"); @@ -145,6 +198,8 @@ void panic_ctx(char *msg, registers_t *regs) { else log("No register context provided.\n"); + __panic_display_bt(regs); + log("System halted: Please restart your computer manually.\n"); asm("cli"); diff --git a/kernel/src/sys/errhnd/panic.h b/kernel/src/sys/errhnd/panic.h index 147263b..4794b32 100644 --- a/kernel/src/sys/errhnd/panic.h +++ b/kernel/src/sys/errhnd/panic.h @@ -1,5 +1,11 @@ #pragma once #include "arch/x86_64/idt.h" + +typedef struct __panic_backtrace { + struct Idt_StackFrame* rbp; + uint64_t rip; +} __attribute__((packed)) panic_backtrace_t; + void panic(char *msg); void panic_ctx(char *msg, registers_t *regs); \ No newline at end of file