forked from PoliEcho-holding-org/kern
Added register dump to panic() and colors to printk()
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <kernel.h>
|
||||
|
||||
#define EXCEPTION_COUNT 32
|
||||
#define ISR_COUNT 16
|
||||
|
||||
// Interrupt frame (ie. what's on the stack on interrupt)
|
||||
|
||||
@@ -73,15 +73,16 @@ int vprintk(const char* fmt, va_list ap);
|
||||
#define pr_alert(fmt, ...) printk(KERN_ALERT fmt, ##__VA_ARGS__)
|
||||
#define pr_crit(fmt, ...) printk(KERN_CRIT fmt, ##__VA_ARGS__)
|
||||
#define pr_error(fmt, ...) printk(KERN_ERROR fmt, ##__VA_ARGS__)
|
||||
#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__)
|
||||
#define pr_warn(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__)
|
||||
#define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__)
|
||||
#define pr_info(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__)
|
||||
#define pr_debug(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
|
||||
|
||||
#define PANIC_MSG_BUFSZ 1024
|
||||
|
||||
void panic(const char* fmt, ...) __noreturn __cold __printf(1, 2);
|
||||
void vpanic(const char* fmt, va_list ap)__noreturn __cold;
|
||||
struct isr_int_frame;
|
||||
void panic(struct isr_int_frame* regs, const char* fmt, ...) __noreturn __cold __printf(2, 3);
|
||||
void vpanic(struct isr_int_frame* regs, const char *fmt, va_list ap) __noreturn __cold;
|
||||
|
||||
extern uintptr_t __kernel_start, __kernel_text_start, __kernel_rodata_start, __kernel_data_start;
|
||||
extern uintptr_t __kernel_end, __kernel_text_end, __kernel_rodata_end, __kernel_data_end;
|
||||
|
||||
@@ -30,7 +30,7 @@ static struct limine_executable_file_request lim_exe_req =
|
||||
struct bootloader bootloader = { 0 };
|
||||
|
||||
int boot_init(void) {
|
||||
if (LIMINE_BASE_REVISION_SUPPORTED(lim_base_revision) == false) panic("Unsupported Limine base revision.");
|
||||
if (LIMINE_BASE_REVISION_SUPPORTED(lim_base_revision) == false) panic(NULL, "Unsupported Limine base revision.");
|
||||
|
||||
struct limine_paging_mode_response* lim_paging_res = lim_paging_req.response;
|
||||
struct limine_executable_address_response* lim_kaddr_res = lim_kaddr_req.response;
|
||||
@@ -39,7 +39,7 @@ int boot_init(void) {
|
||||
struct limine_framebuffer_response* lim_fbuf_res = lim_fbuf_req.response;
|
||||
struct limine_executable_file_response* lim_exe_res = lim_exe_req.response;
|
||||
|
||||
if (lim_paging_res->mode != LIMINE_PAGING_MODE_X86_64_4LVL) panic("Expected 4 level paging.");
|
||||
if (lim_paging_res->mode != LIMINE_PAGING_MODE_X86_64_4LVL) panic(NULL, "Expected 4 level paging.");
|
||||
bootloader.hhdm_offset = lim_hhdm_res->offset;
|
||||
bootloader.kernel_phys_base = lim_kaddr_res->physical_base;
|
||||
bootloader.kernel_virt_base = lim_kaddr_res->virtual_base;
|
||||
|
||||
+14
-13
@@ -5,6 +5,7 @@
|
||||
#include <idt.h>
|
||||
#include <isr.h>
|
||||
|
||||
isr_handler_ptr exception_handlers[EXCEPTION_COUNT];
|
||||
isr_handler_ptr irq_handlers[ISR_COUNT];
|
||||
|
||||
const char* exceptions[] = {
|
||||
@@ -62,6 +63,7 @@ void pic_remap(void) {
|
||||
}
|
||||
|
||||
int isr_init(void) {
|
||||
memset(exception_handlers, 0, sizeof(exception_handlers));
|
||||
memset(irq_handlers, 0, sizeof(irq_handlers));
|
||||
|
||||
idt_init();
|
||||
@@ -98,25 +100,24 @@ void isr_handle_interrupt(size_t rsp) {
|
||||
struct isr_int_frame* iframe = (void*)rsp;
|
||||
|
||||
if (iframe->interrupt < 32) {
|
||||
pr_emerg("Register Dump:\n");
|
||||
pr_emerg("\tRAX: %016lx RBX: %016lx RCX: %016lx\n", iframe->rax, iframe->rbx, iframe->rcx);
|
||||
pr_emerg("\tRDX: %016lx RSI: %016lx RDI: %016lx\n", iframe->rdx, iframe->rsi, iframe->rdi);
|
||||
pr_emerg("\tR08: %016lx R09: %016lx R10: %016lx\n", iframe->r8, iframe->r9, iframe->r10);
|
||||
pr_emerg("\tR11: %016lx R12: %016lx R13: %016lx\n", iframe->r11, iframe->r12, iframe->r13);
|
||||
pr_emerg("\tR14: %016lx R15: %016lx DS/ES: %016lx\n", iframe->r14, iframe->r15, iframe->ds);
|
||||
pr_emerg("\tRBP: %016lx RSP: %016lx SS: %016lx\n", iframe->rbp, iframe->user_rsp, iframe->user_ss);
|
||||
pr_emerg("\tRIP: %016lx RFLAGS: %016lx CS: %016lx\n", iframe->rip, iframe->rflags, iframe->cs);
|
||||
if (exception_handlers[iframe->interrupt]) {
|
||||
exception_handlers[iframe->interrupt](iframe);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iframe->error) pr_emerg("Error code: 0x%lx\n", iframe->error);
|
||||
panic(exceptions[iframe->interrupt]);
|
||||
panic(iframe, "Unhandled %s exception, err 0x%lx", exceptions[iframe->interrupt], iframe->error);
|
||||
} else if (iframe->interrupt >= 32 && iframe->interrupt < 48) {
|
||||
// ISRs 32-47 - Hardware interrupts
|
||||
uint8_t irq = iframe->interrupt - 32;
|
||||
isr_send_eoi(irq);
|
||||
|
||||
if (irq_handlers[irq]) irq_handlers[irq](iframe);
|
||||
} else if (iframe->interrupt == 128) {
|
||||
else pr_warn("Unhandled IRQ #%d\n", irq);
|
||||
|
||||
isr_send_eoi(irq);
|
||||
} else if (iframe->interrupt == 0x80) {
|
||||
// ISR 128 - System call
|
||||
pr_notice("SYSCALL!\n");
|
||||
} else {
|
||||
pr_warn("Unknown interrupt vector: %lu", iframe->interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -13,10 +13,10 @@ void _start(void) {
|
||||
int err = 0;
|
||||
|
||||
// Serial console for debugging
|
||||
if ((err = serial_init(COM1)) < 0) panic("Failed to initialize Serial driver. (%d)", err);
|
||||
if ((err = serial_init(COM1)) < 0) panic(NULL, "Failed to initialize Serial driver. (%d)", err);
|
||||
|
||||
// Load structures from bootloader
|
||||
if ((err = boot_init()) < 0) panic("Failed to parse bootloader structures. (%d)", err);
|
||||
if ((err = boot_init()) < 0) panic(NULL, "Failed to parse bootloader structures. (%d)", err);
|
||||
|
||||
// CPUID thingy :p
|
||||
uint32_t eax = 0;
|
||||
@@ -25,12 +25,12 @@ void _start(void) {
|
||||
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
||||
|
||||
// System init
|
||||
if ((err = gdt_init()) < 0) panic("Failed to initalize GDT. (%d)", err);
|
||||
if ((err = isr_init()) < 0) panic("Failed to initalize ISRs. (%d)", err);
|
||||
if ((err = gdt_init()) < 0) panic(NULL, "Failed to initalize GDT. (%d)", err);
|
||||
if ((err = isr_init()) < 0) panic(NULL, "Failed to initalize ISRs. (%d)", err);
|
||||
|
||||
// Memory management
|
||||
if ((err = pmm_init()) < 0) panic("Failed to initalize Physical Memory Manager. (%d)", err);
|
||||
if ((err = pag_init()) < 0) panic("Failed to initalize Paging. (%d)", err);
|
||||
if ((err = pmm_init()) < 0) panic(NULL, "Failed to initalize Physical Memory Manager. (%d)", err);
|
||||
if ((err = pag_init()) < 0) panic(NULL, "Failed to initalize Paging. (%d)", err);
|
||||
|
||||
// The most important function in the world.
|
||||
splash();
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ int pag_init(void) {
|
||||
case LIMINE_MEMMAP_FRAMEBUFFER: flags = PTE_FLAG_WRITE | PTE_FLAG_PWT; break;
|
||||
case LIMINE_MEMMAP_RESERVED_MAPPED: flags = 0; break;
|
||||
default:
|
||||
pr_warning(
|
||||
pr_warn(
|
||||
"[pag] %p - %p: Unknown memmap type %lu. Will remain unmapped.\n",
|
||||
(void*)entry->base, (void*)entry->base + entry->length, entry->type
|
||||
);
|
||||
|
||||
+21
-6
@@ -2,10 +2,25 @@
|
||||
#include <kernel.h>
|
||||
#include <stdarg.h>
|
||||
#include <system.h>
|
||||
#include <isr.h>
|
||||
#include <pmm.h>
|
||||
|
||||
static int crashing = 0;
|
||||
|
||||
void panic_regs_dump(struct isr_int_frame* regs) {
|
||||
if (regs == NULL) return;
|
||||
|
||||
pr_emerg("Register Dump:\n");
|
||||
pr_emerg("\tRAX: %016lx RBX: %016lx RCX: %016lx\n", regs->rax, regs->rbx, regs->rcx);
|
||||
pr_emerg("\tRDX: %016lx RSI: %016lx RDI: %016lx\n", regs->rdx, regs->rsi, regs->rdi);
|
||||
pr_emerg("\tR08: %016lx R09: %016lx R10: %016lx\n", regs->r8, regs->r9, regs->r10);
|
||||
pr_emerg("\tR11: %016lx R12: %016lx R13: %016lx\n", regs->r11, regs->r12, regs->r13);
|
||||
pr_emerg("\tR14: %016lx R15: %016lx DS/ES: %016lx\n", regs->r14, regs->r15, regs->ds);
|
||||
pr_emerg("\tRBP: %016lx RSP: %016lx SS: %016lx\n", regs->rbp, regs->user_rsp, regs->user_ss);
|
||||
pr_emerg("\tRIP: %016lx RFLAGS: %016lx CS: %016lx\n", regs->rip, regs->rflags, regs->cs);
|
||||
pr_emerg("\n");
|
||||
}
|
||||
|
||||
void panic_call_trace(void) {
|
||||
uintptr_t* rbp;
|
||||
__asm__ volatile ("movq %%rbp, %0" : "=r"(rbp));
|
||||
@@ -22,16 +37,17 @@ void panic_call_trace(void) {
|
||||
|
||||
rbp = (uintptr_t*)*rbp;
|
||||
}
|
||||
pr_emerg("\n");
|
||||
}
|
||||
|
||||
void panic(const char *fmt, ...) {
|
||||
void panic(struct isr_int_frame* regs, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vpanic(fmt, ap);
|
||||
vpanic(regs, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void vpanic(const char *fmt, va_list ap) {
|
||||
void vpanic(struct isr_int_frame* regs, const char *fmt, va_list ap) {
|
||||
static char buf[PANIC_MSG_BUFSZ];
|
||||
size_t len;
|
||||
|
||||
@@ -44,11 +60,10 @@ void vpanic(const char *fmt, va_list ap) {
|
||||
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
|
||||
|
||||
pr_emerg("--- [ Kernel panic: %s ] ---\n\n", buf);
|
||||
|
||||
pr_emerg("%lu / %lu pages free.\n\n", pmm_free_pages, pmm_total_pages);
|
||||
panic_regs_dump(regs);
|
||||
panic_call_trace();
|
||||
|
||||
pr_emerg("\n--- [ End kernel panic: %s ] ---\n", buf);
|
||||
pr_emerg("--- [ End kernel panic: %s ] ---\n", buf);
|
||||
|
||||
// We can add some kind of LED blink or smth later :)
|
||||
for (;;) __asm__ volatile ("hlt");
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ void* pmm_alloc() {
|
||||
if (pmm_head == NULL) return ERR_PTR(-ENOMEM);
|
||||
|
||||
uint64_t* addr = pmm_head;
|
||||
if ((uintptr_t)addr % PAGE_SIZE != 0) panic("pmm_head corrupted.");
|
||||
if ((uintptr_t)addr % PAGE_SIZE != 0) panic(NULL, "pmm_head corrupted.");
|
||||
pmm_head = (uint64_t*)(*addr);
|
||||
pmm_free_pages--;
|
||||
|
||||
|
||||
+15
-1
@@ -22,7 +22,21 @@ int vprintk(const char* fmt, va_list ap) {
|
||||
|
||||
if (loglevel > console_loglevel) return 0;
|
||||
|
||||
// Loglevel colors
|
||||
switch (loglevel) {
|
||||
case LOGLEVEL_EMERG: debugf("\x1b[1;31m"); break; // bold red
|
||||
case LOGLEVEL_ALERT: debugf("\x1b[1;31m"); break; // bold red
|
||||
case LOGLEVEL_CRIT: debugf("\x1b[31m"); break; // red
|
||||
case LOGLEVEL_ERROR: debugf("\x1b[31m"); break; // red
|
||||
case LOGLEVEL_WARNING: debugf("\x1b[33m"); break; // yellow
|
||||
case LOGLEVEL_NOTICE: debugf("\x1b[34m"); break; // green
|
||||
case LOGLEVEL_INFO: debugf("\x1b[37m"); break; // white
|
||||
case LOGLEVEL_DEBUG: debugf("\x1b[2;32m"); break; // green
|
||||
}
|
||||
|
||||
// TODO: debugf("[%4d.%6d] ", seconds, milliseconds);
|
||||
return vdebugf(fmt, ap);
|
||||
int ret = vdebugf(fmt, ap);
|
||||
debugf("\x1b[0m");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -10,6 +10,6 @@
|
||||
|
||||
uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
|
||||
__noreturn void __stack_chk_fail(void) {
|
||||
panic("Stack smashing detected!");
|
||||
panic(NULL, "Stack smashing detected!");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user