serial Kernel panic

This commit is contained in:
2026-01-10 09:45:20 +01:00
parent 0f72987bc1
commit 12ab12f1b2
7 changed files with 119 additions and 2 deletions

View File

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

View File

@@ -9,6 +9,7 @@ because this shitty implementation will be replaced one day by Flanterm
#include <stddef.h>
#include <kernel.h>
#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);

View File

@@ -11,6 +11,8 @@ enum TermColors
WHITE = 0xffffff
};
#define MAX_LINES 256
#define PSF1_FONT_MAGIC 0x0436
typedef struct

View File

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

View File

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

View File

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

View File

@@ -2,5 +2,6 @@
#define TIMER_H
void timer_init();
void timer_wait(unsigned int wait_ticks);
#endif