kernel: try some shit to get the compiler to put a backtrace

This commit is contained in:
RaphProductions 2025-05-16 15:58:51 +02:00
parent ca489e986a
commit cfc9159ad9
7 changed files with 90 additions and 10 deletions

View file

@ -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)

View file

@ -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 := \

View file

@ -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);

View file

@ -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)
;
;
;;
}

10
kernel/src/premain.asm Normal file
View file

@ -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

View file

@ -1,3 +1,4 @@
#include "sys/errhnd/panic.h"
#include "arch/x86_64/idt.h"
#include "lib/spinlock.h"
#include <mm/memop.h>
@ -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");

View file

@ -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);