serial Kernel panic
This commit is contained in:
@@ -53,6 +53,38 @@ void idt_init()
|
|||||||
DEBUG("IDT initialized");
|
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)
|
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||||
{
|
{
|
||||||
switch(context->vector_number)
|
switch(context->vector_number)
|
||||||
@@ -100,7 +132,8 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
|||||||
DEBUG("General Protection Fault!");
|
DEBUG("General Protection Fault!");
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
DEBUG("Page Fault!");
|
// Better debugging for page faults...
|
||||||
|
page_fault_handler(context);
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
DEBUG("Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)");
|
DEBUG("Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)");
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ because this shitty implementation will be replaced one day by Flanterm
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
|
#include "mem/misc/utils.h"
|
||||||
|
|
||||||
extern struct boot_context boot_ctx;
|
extern struct boot_context boot_ctx;
|
||||||
|
|
||||||
@@ -35,6 +36,8 @@ unsigned char* fb;
|
|||||||
|
|
||||||
struct limine_framebuffer* framebuffer;
|
struct limine_framebuffer* framebuffer;
|
||||||
|
|
||||||
|
uint8_t lines_length[MAX_LINES];
|
||||||
|
|
||||||
int term_init()
|
int term_init()
|
||||||
{
|
{
|
||||||
// Get framebuffer address from Limine struct
|
// 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)
|
void putchar(char c)
|
||||||
{
|
{
|
||||||
|
if ((c == '\n') && ((cursor.y+1)*FONT_HEIGHT >= framebuffer->height))
|
||||||
|
{
|
||||||
|
term_scroll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
|
lines_length[cursor.y] = cursor.x;
|
||||||
cursor.x = 0;
|
cursor.x = 0;
|
||||||
cursor.y++;
|
cursor.y++;
|
||||||
return;
|
return;
|
||||||
@@ -110,7 +154,8 @@ void putchar(char c)
|
|||||||
if (cursor.x == 0)
|
if (cursor.x == 0)
|
||||||
{
|
{
|
||||||
cursor.y--;
|
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 {
|
else {
|
||||||
cursor.x--;
|
cursor.x--;
|
||||||
@@ -128,6 +173,11 @@ void putchar(char c)
|
|||||||
cursor.y++;
|
cursor.y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((cursor.y+1)*FONT_HEIGHT >= framebuffer->height)
|
||||||
|
{
|
||||||
|
term_scroll();
|
||||||
|
}
|
||||||
|
|
||||||
int px = cursor.x * FONT_WIDTH;
|
int px = cursor.x * FONT_WIDTH;
|
||||||
int py = cursor.y * FONT_HEIGHT;
|
int py = cursor.y * FONT_HEIGHT;
|
||||||
draw_char(c, px, py, WHITE, BLACK);
|
draw_char(c, px, py, WHITE, BLACK);
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ enum TermColors
|
|||||||
WHITE = 0xffffff
|
WHITE = 0xffffff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_LINES 256
|
||||||
|
|
||||||
#define PSF1_FONT_MAGIC 0x0436
|
#define PSF1_FONT_MAGIC 0x0436
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -16,11 +16,15 @@ enum ErrorCodes
|
|||||||
|
|
||||||
#include "io/serial/serial.h"
|
#include "io/serial/serial.h"
|
||||||
#include "io/term/printf.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 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__);
|
// printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
void panic(struct cpu_status_t* ctx);
|
||||||
void hcf();
|
void hcf();
|
||||||
#define assert(check) do { if(!(check)) hcf(); } while(0)
|
#define assert(check) do { if(!(check)) hcf(); } while(0)
|
||||||
|
|
||||||
|
|||||||
16
src/kmain.c
16
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";
|
const char* splash = "pepperOS version "PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\n";
|
||||||
|
|
||||||
struct boot_context boot_ctx;
|
struct boot_context boot_ctx;
|
||||||
@@ -108,5 +118,11 @@ void kmain()
|
|||||||
term_init();
|
term_init();
|
||||||
kputs(splash);
|
kputs(splash);
|
||||||
|
|
||||||
|
for (int i=0; i<50; i++)
|
||||||
|
{
|
||||||
|
printf("testing, attention please %d\n", i);
|
||||||
|
timer_wait(1000);
|
||||||
|
}
|
||||||
|
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,17 @@ void pit_init()
|
|||||||
outb(0x40, (divisor >> 8) & 0xFF);
|
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()
|
void timer_init()
|
||||||
{
|
{
|
||||||
// Remapping the PIC, because at startup it conflicts with
|
// Remapping the PIC, because at startup it conflicts with
|
||||||
|
|||||||
@@ -2,5 +2,6 @@
|
|||||||
#define TIMER_H
|
#define TIMER_H
|
||||||
|
|
||||||
void timer_init();
|
void timer_init();
|
||||||
|
void timer_wait(unsigned int wait_ticks);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user