From 12ab12f1b2987e092f0870543f7b87c09ec76303 Mon Sep 17 00:00:00 2001 From: xamidev Date: Sat, 10 Jan 2026 09:45:20 +0100 Subject: [PATCH] serial Kernel panic --- src/idt/idt.c | 35 ++++++++++++++++++++++++++++++- src/io/term/term.c | 52 +++++++++++++++++++++++++++++++++++++++++++++- src/io/term/term.h | 2 ++ src/kernel.h | 4 ++++ src/kmain.c | 16 ++++++++++++++ src/time/timer.c | 11 ++++++++++ src/time/timer.h | 1 + 7 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/idt/idt.c b/src/idt/idt.c index 5e31e48..af05f63 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -53,6 +53,38 @@ void idt_init() DEBUG("IDT initialized"); } +static inline uint64_t read_cr2(void) +{ + uint64_t val; + asm volatile ("mov %%cr2, %0" : "=r"(val)); + return val; +} + +static void page_fault_handler(struct cpu_status_t* ctx) +{ + // It could be used to remap pages etc. to fix the fault, but right now what I'm more + // interested in is getting more info out of those numbers cause i'm lost each time i have + // to read all this mess + uint64_t cr2 = read_cr2(); + + DEBUG("\x1b[38;5;231mPage Fault at rip=0x%p, err=%u (%s%s%s%s%s%s%s%s) when accessing addr=0x%p\x1b[0m", ctx->iret_rip, ctx->error_code, + CHECK_BIT(ctx->error_code, 0) ? "PAGE_PROTECTION_VIOLATION " : "PAGE_NOT_PRESENT ", + CHECK_BIT(ctx->error_code, 1) ? "ON_WRITE " : "ON_READ ", + CHECK_BIT(ctx->error_code, 2) ? "IN_USER_MODE" : "IN_KERNEL_MODE", + CHECK_BIT(ctx->error_code, 3) ? " WAS_RESERVED" : "", + CHECK_BIT(ctx->error_code, 4) ? " ON_INSTRUCTION_FETCH" : "", + CHECK_BIT(ctx->error_code, 5) ? " PK_VIOLATION" : "", + CHECK_BIT(ctx->error_code, 6) ? " ON_SHADOWSTACK_ACCESS" : "", + CHECK_BIT(ctx->error_code, 7) ? " SGX_VIOLATION" : "", + cr2); + + /* if (CHECK_BIT(ctx->error_code, 0)) + { + panic(ctx); + } */ + panic(ctx); +} + struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) { switch(context->vector_number) @@ -100,7 +132,8 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) DEBUG("General Protection Fault!"); break; case 14: - DEBUG("Page Fault!"); + // Better debugging for page faults... + page_fault_handler(context); break; case 15: DEBUG("Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)"); diff --git a/src/io/term/term.c b/src/io/term/term.c index ef51ee7..2666725 100644 --- a/src/io/term/term.c +++ b/src/io/term/term.c @@ -9,6 +9,7 @@ because this shitty implementation will be replaced one day by Flanterm #include #include #include "term.h" +#include "mem/misc/utils.h" extern struct boot_context boot_ctx; @@ -35,6 +36,8 @@ unsigned char* fb; struct limine_framebuffer* framebuffer; +uint8_t lines_length[MAX_LINES]; + int term_init() { // Get framebuffer address from Limine struct @@ -87,10 +90,51 @@ static void erase_char(int px, int py) } } +static inline size_t term_max_lines(void) +{ + return framebuffer->height / FONT_HEIGHT; +} + +void term_scroll() +{ + const size_t row_height = FONT_HEIGHT; + const size_t row_bytes = framebuffer->pitch; + const size_t screen_rows = framebuffer->height; + + // Move framebuffer up by one text row + memmove(fb, fb + row_height * row_bytes, (screen_rows - row_height) * row_bytes); + + // Clear last text row + size_t clear_start = (screen_rows - row_height) * row_bytes; + memset(fb + clear_start, 0, row_height * row_bytes); + + // Shift line lengths by 1 (for backspace handling) + size_t max_lines = term_max_lines(); + for (size_t i = 1; i < max_lines; i++) + { + lines_length[i - 1] = lines_length[i]; + } + + lines_length[max_lines - 1] = 0; + + if (cursor.y > 0) + { + cursor.y--; + } +} + + void putchar(char c) { + if ((c == '\n') && ((cursor.y+1)*FONT_HEIGHT >= framebuffer->height)) + { + term_scroll(); + return; + } + if (c == '\n') { + lines_length[cursor.y] = cursor.x; cursor.x = 0; cursor.y++; return; @@ -110,7 +154,8 @@ void putchar(char c) if (cursor.x == 0) { cursor.y--; - cursor.x = (framebuffer->width / FONT_WIDTH) -1; // here + // cursor.x = (framebuffer->width / FONT_WIDTH) -1; // here + cursor.x = lines_length[cursor.y]; } else { cursor.x--; @@ -128,6 +173,11 @@ void putchar(char c) cursor.y++; } + if ((cursor.y+1)*FONT_HEIGHT >= framebuffer->height) + { + term_scroll(); + } + int px = cursor.x * FONT_WIDTH; int py = cursor.y * FONT_HEIGHT; draw_char(c, px, py, WHITE, BLACK); diff --git a/src/io/term/term.h b/src/io/term/term.h index a240768..d525db4 100644 --- a/src/io/term/term.h +++ b/src/io/term/term.h @@ -11,6 +11,8 @@ enum TermColors WHITE = 0xffffff }; +#define MAX_LINES 256 + #define PSF1_FONT_MAGIC 0x0436 typedef struct diff --git a/src/kernel.h b/src/kernel.h index e32fbe4..a4a2736 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -16,11 +16,15 @@ enum ErrorCodes #include "io/serial/serial.h" #include "io/term/printf.h" +#include "idt/idt.h" #define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__) +#define CHECK_BIT(var,pos) ((var) & (1<<(pos))) + // printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__); +void panic(struct cpu_status_t* ctx); void hcf(); #define assert(check) do { if(!(check)) hcf(); } while(0) diff --git a/src/kmain.c b/src/kmain.c index c85f12f..73702df 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -62,6 +62,16 @@ void hcf() } } +void panic(struct cpu_status_t* ctx) +{ + DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\nSomething went horribly wrong! vect=0x%.2x errcode=0x%x\nrax=%p rbx=%p rcx=%p rdx=%p\nrsi=%p rdi=%p r8=%p r9=%p\nr10=%p r11=%p r12=%p r13=%p\nr14=%p r15=%p\n\nflags=%p\nstack at rbp=%p\nHalting...", + ctx->iret_rip, + ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi, + ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags, + ctx->rbp); + hcf(); +} + const char* splash = "pepperOS version "PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\n"; struct boot_context boot_ctx; @@ -108,5 +118,11 @@ void kmain() term_init(); kputs(splash); + for (int i=0; i<50; i++) + { + printf("testing, attention please %d\n", i); + timer_wait(1000); + } + hcf(); } diff --git a/src/time/timer.c b/src/time/timer.c index 894b47c..07ede9e 100644 --- a/src/time/timer.c +++ b/src/time/timer.c @@ -65,6 +65,17 @@ void pit_init() outb(0x40, (divisor >> 8) & 0xFF); } +// Wait n ticks +// Given that there's a tick every 1ms, wait n milliseconds +void timer_wait(uint64_t wait_ticks) +{ + uint64_t then = ticks + wait_ticks; + while (ticks < then) + { + asm("hlt"); + }; +} + void timer_init() { // Remapping the PIC, because at startup it conflicts with diff --git a/src/time/timer.h b/src/time/timer.h index 0c47d5a..bb0c8d4 100644 --- a/src/time/timer.h +++ b/src/time/timer.h @@ -2,5 +2,6 @@ #define TIMER_H void timer_init(); +void timer_wait(unsigned int wait_ticks); #endif \ No newline at end of file