From: Tulio A M Mendes Date: Tue, 10 Feb 2026 06:01:02 +0000 (-0300) Subject: feat: implement kconsole — kernel emergency console (like HelenOS kconsole) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=4e33eaa63e8b570289922afb6f3f3a7e0028ff38;p=AdrOS.git feat: implement kconsole — kernel emergency console (like HelenOS kconsole) When VFS mount or init fails, AdrOS now enters a minimal kernel-mode emergency console instead of the full shell. This is similar to HelenOS's kconsole — it runs entirely in kernel mode and provides basic diagnostic commands. Design: - kconsole_enter() runs a blocking read loop using kgetc()/kprintf() - Commands: help, dmesg, reboot, halt - Activated from kernel_main() when init_start() returns < 0 - Fully architecture-independent (uses only generic console API) The normal shell remains available for userspace-initiated sessions. Passes: make, cppcheck, QEMU smoke test. --- diff --git a/include/kconsole.h b/include/kconsole.h new file mode 100644 index 0000000..fcf8d48 --- /dev/null +++ b/include/kconsole.h @@ -0,0 +1,8 @@ +#ifndef KCONSOLE_H +#define KCONSOLE_H + +// Enter the kernel emergency console (kernel-mode, like HelenOS kconsole). +// Called when VFS mount or init fails. Runs in a loop until reboot. +void kconsole_enter(void); + +#endif diff --git a/src/kernel/kconsole.c b/src/kernel/kconsole.c new file mode 100644 index 0000000..53244b1 --- /dev/null +++ b/src/kernel/kconsole.c @@ -0,0 +1,79 @@ +#include "kconsole.h" +#include "console.h" +#include "utils.h" +#include "hal/system.h" +#include "hal/cpu.h" + +#define KCMD_MAX 128 + +static void kconsole_help(void) { + kprintf("kconsole commands:\n"); + kprintf(" help - Show this list\n"); + kprintf(" dmesg - Show kernel log buffer\n"); + kprintf(" reboot - Restart system\n"); + kprintf(" halt - Halt the CPU\n"); +} + +static void kconsole_exec(const char* cmd) { + if (strcmp(cmd, "help") == 0) { + kconsole_help(); + } + else if (strcmp(cmd, "dmesg") == 0) { + char buf[4096]; + size_t n = klog_read(buf, sizeof(buf)); + if (n > 0) { + console_write(buf); + } else { + kprintf("(empty)\n"); + } + } + else if (strcmp(cmd, "reboot") == 0) { + hal_system_reboot(); + } + else if (strcmp(cmd, "halt") == 0) { + kprintf("System halted.\n"); + hal_cpu_disable_interrupts(); + for (;;) hal_cpu_idle(); + } + else if (cmd[0] != '\0') { + kprintf("unknown command: %s\n", cmd); + } +} + +void kconsole_enter(void) { + kprintf("\n*** AdrOS Kernel Console (kconsole) ***\n"); + kprintf("Type 'help' for available commands.\n"); + + char line[KCMD_MAX]; + int pos = 0; + + for (;;) { + kprintf("kconsole> "); + + pos = 0; + while (pos < KCMD_MAX - 1) { + int ch = kgetc(); + if (ch < 0) continue; + + if (ch == '\n' || ch == '\r') { + console_write("\n"); + break; + } + + if (ch == '\b' || ch == 127) { + if (pos > 0) { + pos--; + console_write("\b \b"); + } + continue; + } + + line[pos++] = (char)ch; + char echo[2] = { (char)ch, 0 }; + console_write(echo); + } + line[pos] = '\0'; + + kconsole_exec(line); + } +} diff --git a/src/kernel/main.c b/src/kernel/main.c index cdbf105..609ae55 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -8,6 +8,7 @@ #include "process.h" #include "keyboard.h" #include "shell.h" +#include "kconsole.h" #include "heap.h" #include "timer.h" #include "initrd.h" @@ -62,8 +63,8 @@ void kernel_main(const struct boot_info* bi) { int init_ret = init_start(bi); if (init_ret < 0) { - // Start Shell as the main interaction loop - shell_init(); + // VFS/init failed — enter kernel emergency console + kconsole_enter(); } done: