From 3853a1ace395d7824faf4d2ac3a2e923d711d24f Mon Sep 17 00:00:00 2001 From: xamidev Date: Sun, 28 Dec 2025 12:15:32 +0100 Subject: [PATCH] Efficient DEBUG logging system with __FILE__ and fctprintf --- src/idt/idt.c | 51 +++++++++++++++++++++--------------------- src/io/kbd/ps2.c | 9 ++++---- src/io/serial/serial.c | 10 +++++---- src/io/serial/serial.h | 3 ++- src/io/term/term.c | 1 + src/kernel.h | 6 +++++ src/kmain.c | 10 ++++----- src/mem/gdt/gdt.c | 3 ++- src/time/timer.c | 2 ++ 9 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/idt/idt.c b/src/idt/idt.c index 5f2cb74..f293bee 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -3,6 +3,7 @@ #include #include "../io/serial/serial.h" #include "../io/kbd/ps2.h" +#include struct interrupt_descriptor idt[256]; struct idtr idt_reg; @@ -49,7 +50,7 @@ void idt_init() idt_set_entry(i, vector_0_handler + (i*16), 0); } idt_load(&idt); - serial_kputs("kernel: idt: Initialized IDT!\n"); + DEBUG("IDT initialized"); } struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) @@ -57,74 +58,74 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) switch(context->vector_number) { case 0: - serial_kputs("kernel: idt: Divide Error!\n"); + DEBUG("Divide Error!"); break; case 1: - serial_kputs("kernel: idt: Debug Exception!\n"); + DEBUG("Debug Exception!"); break; case 2: - serial_kputs("kernel: idt: NMI Interrupt!\n"); + DEBUG("NMI Interrupt!"); break; case 3: - serial_kputs("kernel: idt: Breakpoint Interrupt!\n"); + DEBUG("Breakpoint Interrupt!"); break; case 4: - serial_kputs("kernel: idt: Overflow Trap!\n"); + DEBUG("Overflow Trap!"); break; case 5: - serial_kputs("kernel: idt: BOUND Range Exceeded!\n"); + DEBUG("BOUND Range Exceeded!"); break; case 6: - serial_kputs("kernel: idt: Invalid Opcode!\n"); + DEBUG("Invalid Opcode!"); break; case 7: - serial_kputs("kernel: idt: Device Not Available!\n"); + DEBUG("Device Not Available!"); break; case 8: - serial_kputs("kernel: idt: Double Fault!\n"); + DEBUG("Double Fault!"); break; case 9: - serial_kputs("kernel: idt: Coprocessor Segment Overrun!\n"); + DEBUG("Coprocessor Segment Overrun!"); break; case 10: - serial_kputs("kernel: idt: Invalid TSS!\n"); + DEBUG("Invalid TSS!"); break; case 11: - serial_kputs("kernel: idt: Segment Not Present!\n"); + DEBUG("Segment Not Present!"); break; case 12: - serial_kputs("kernel: idt: Stack-Segment Fault!\n"); + DEBUG("Stack-Segment Fault!"); break; case 13: - serial_kputs("kernel: idt: General Protection Fault!\n"); + DEBUG("General Protection Fault!"); break; case 14: - serial_kputs("kernel: idt: Page Fault!\n"); + DEBUG("Page Fault!"); break; case 15: - serial_kputs("kernel: idt: Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)\n"); + DEBUG("Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)"); break; case 16: - serial_kputs("kernel: idt: x87 Floating-Point Error!\n"); + DEBUG("x87 Floating-Point Error!"); break; case 17: - serial_kputs("kernel: idt: Alignment Check Fault!\n"); + DEBUG("Alignment Check Fault!"); break; case 18: - serial_kputs("kernel: idt: Machine Check!\n"); + DEBUG("Machine Check!"); break; case 19: - serial_kputs("kernel: idt: SIMD Floating-Point Exception!\n"); + DEBUG("SIMD Floating-Point Exception!"); break; case 20: - serial_kputs("kernel: idt: Virtualization Exception!\n"); + DEBUG("Virtualization Exception!"); break; case 21: - serial_kputs("kernel: idt: Control Protection Exception!\n"); + DEBUG("Control Protection Exception!"); break; case 32: - //serial_kputs("Tick!"); + DEBUG("Tick!"); ticks++; // Send an EOI so that we can continue having interrupts outb(0x20, 0x20); @@ -135,7 +136,7 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) break; default: - serial_kputs("kernel: idt: Unexpected interrupt\n"); + DEBUG("Unexpected interrupt"); break; } diff --git a/src/io/kbd/ps2.c b/src/io/kbd/ps2.c index 3a7c835..314d197 100644 --- a/src/io/kbd/ps2.c +++ b/src/io/kbd/ps2.c @@ -1,10 +1,10 @@ // PS/2 Keyboard support #include "../serial/serial.h" -#include "../term/printf.h" #include "ps2.h" #include #include "../term/term.h" +#include // The key status bitfield will be used to see if ALT, CONTROL, or SHIFT is pressed uint8_t key_status = 0b00000000; @@ -206,7 +206,7 @@ void keyboard_handler() } } - serial_kputs("key pressed!\n"); + skputs("key pressed!\n"); } // End of Interrupt (to master PIC) @@ -230,7 +230,8 @@ void keyboard_init(unsigned char layout) break; default: - serial_kputs("Unsupported layout."); - break; + skputs("Unsupported layout."); + return; } + DEBUG("PS/2 Keyboard initialized"); } \ No newline at end of file diff --git a/src/io/serial/serial.c b/src/io/serial/serial.c index 85a3f37..c70af76 100644 --- a/src/io/serial/serial.c +++ b/src/io/serial/serial.c @@ -36,7 +36,7 @@ int serial_init() // Set normal operation mode outb(PORT + 4, 0x0F); - serial_kputs("\n\nkernel: serial: Serial initialization OK!\n"); + DEBUG("serial initialized"); return 0; } @@ -45,18 +45,20 @@ static int is_transmit_empty() return inb(PORT + 5) & 0x20; } -void write_serial(char c) +// Serial kernel putchar +void skputc(char c) { while (!is_transmit_empty()); // wait for free spot outb(PORT, c); } -void serial_kputs(const char* str) +// Serial kernel putstring +void skputs(const char* str) { unsigned int i=0; while (str[i]) { - write_serial(str[i]); + skputc(str[i]); i++; } } \ No newline at end of file diff --git a/src/io/serial/serial.h b/src/io/serial/serial.h index 698fc0d..6144ce8 100644 --- a/src/io/serial/serial.h +++ b/src/io/serial/serial.h @@ -5,6 +5,7 @@ void outb(int port, unsigned char data); unsigned char inb(int port); int serial_init(); -void serial_kputs(const char* str); +void skputs(const char* str); +void skputc(char c); #endif \ No newline at end of file diff --git a/src/io/term/term.c b/src/io/term/term.c index 3686cd2..3a697e6 100644 --- a/src/io/term/term.c +++ b/src/io/term/term.c @@ -35,6 +35,7 @@ int term_init() if (framebuffer) { fb = framebuffer->address; + DEBUG("terminal initialized"); return 0; } return -ENOMEM; diff --git a/src/kernel.h b/src/kernel.h index 1ded436..09ebb67 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -10,4 +10,10 @@ enum ErrorCodes #define CLEAR_INTERRUPTS __asm__ volatile("cli") #define SET_INTERRUPTS __asm__ volatile("sti") +#include "io/serial/serial.h" +#include "io/term/printf.h" + +#define DEBUG(log) \ + fctprintf((void*)&skputc, 0, "debug: [%s]: %s\n", __FILE__, log) + #endif diff --git a/src/kmain.c b/src/kmain.c index 0b1d920..883bf23 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -48,9 +48,8 @@ void kmain() // Get the first framebuffer from the response framebuffer = framebuffer_request.response->framebuffers[0]; - if (term_init()) hcf(); - - if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!"); + term_init(); + serial_init(); CLEAR_INTERRUPTS; gdt_init(); @@ -61,8 +60,9 @@ void kmain() keyboard_init(FR); // Draw something - printf("%s, %s!", "Hello", "world"); + printf("%s, %s!\n", "Hello", "world"); - //printf("%d", 4/0); + // Yoohoooooo! + DEBUG("kernel initialized successfully! hanging..."); hcf(); } diff --git a/src/mem/gdt/gdt.c b/src/mem/gdt/gdt.c index 01d183c..052f18f 100644 --- a/src/mem/gdt/gdt.c +++ b/src/mem/gdt/gdt.c @@ -1,6 +1,7 @@ #include "gdt.h" #include #include "../../io/serial/serial.h" +#include // Descriptors are 8-byte wide (64bits) // So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc.. @@ -78,5 +79,5 @@ void gdt_init() gdt_load(); gdt_flush(); - serial_kputs("kernel: gdt: Initialized GDT!\n"); + DEBUG("GDT initialized"); } \ No newline at end of file diff --git a/src/time/timer.c b/src/time/timer.c index a436572..b6b56d6 100644 --- a/src/time/timer.c +++ b/src/time/timer.c @@ -1,5 +1,6 @@ #include #include "../io/serial/serial.h" +#include /* For now, the timer module will be using the PIC. @@ -72,4 +73,5 @@ void timer_init() pic_remap(); pic_enable(); pit_init(); + DEBUG("PIT initialized"); } \ No newline at end of file