/* * kernel.c – Kernel entry point and interactive shell loop. * * kmain() is called by the UEFI loader (main.c) after the ELF kernel * has been mapped into memory. It initialises subsystems (IDT, memory, * tasks), prints a welcome banner, and enters an interactive read- * eval-print loop that dispatches typed commands via commands.c. * * While waiting for keyboard input, the shell yields to the cooperative * scheduler so that background tasks can make progress. */ #include #include "boot_info.h" #include "commands.h" #include "idt.h" #include "memory.h" #include "task.h" /* Null-safe print helper used throughout the kernel. */ #define SAFE_PRINT(Boot, ...) \ do { \ if ((Boot) != NULL && (Boot)->print != NULL) { \ (Boot)->print(__VA_ARGS__); \ } \ } while (0) /* ================================================================ * Kernel entry point * ================================================================ */ void kmain(BootInfo *Boot) { EFI_INPUT_KEY Key; EFI_STATUS Status; UINTN read_errors = 0; if (Boot == NULL) { return; } if (Boot->clear_screen != NULL) { Status = Boot->clear_screen(); if (EFI_ERROR(Status)) { SAFE_PRINT(Boot, L"clear_screen failed: %r\n\r", Status); } } if (Boot->set_attribute != NULL) { Status = Boot->set_attribute(EFI_TEXT_ATTR(EFI_LIGHTGREEN, EFI_BLACK)); if (EFI_ERROR(Status)) { SAFE_PRINT(Boot, L"set_attribute failed: %r\n\r", Status); } } /* ---- Subsystem initialisation ---- */ idt_init(Boot); memory_init(Boot); task_init(Boot); /* ---- Welcome banner ---- */ SAFE_PRINT(Boot, L" Welcome to Simple UEFI Operating System!\n\r"); SAFE_PRINT(Boot, L"================================================\n\r"); SAFE_PRINT(Boot, L"\n\r"); SAFE_PRINT(Boot, L"System Information:\n\r"); if (Boot->SystemTable != NULL) { SAFE_PRINT(Boot, L" UEFI Firmware Vendor: %s\n\r", Boot->SystemTable->FirmwareVendor); SAFE_PRINT(Boot, L" UEFI Firmware Revision: %d.%d\n\r", Boot->SystemTable->FirmwareRevision >> 16, Boot->SystemTable->FirmwareRevision & 0xFFFF); } else { SAFE_PRINT(Boot, L" UEFI System Table: Unavailable\n\r"); } SAFE_PRINT(Boot, L"\n\r"); SAFE_PRINT(Boot, L"Available Services:\n\r"); SAFE_PRINT(Boot, L" - Console Input/Output: %s\n\r", (Boot->read_key != NULL && Boot->print != NULL) ? L"Active" : L"Unavailable"); SAFE_PRINT(Boot, L" - Runtime Services: %s\n\r", (Boot->SystemTable != NULL && Boot->SystemTable->RuntimeServices != NULL) ? L"Active" : L"Unavailable"); SAFE_PRINT(Boot, L" - Boot Services: %s\n\r", (Boot->SystemTable != NULL && Boot->SystemTable->BootServices != NULL) ? L"Active" : L"Unavailable"); SAFE_PRINT(Boot, L"\n\r"); SAFE_PRINT(Boot, L"Type 'help' for a list of commands.\n\r\n\r"); /* ---- Interactive shell loop ---- */ CHAR16 line[128]; UINTN len = 0; SAFE_PRINT(Boot, L"-> "); while (TRUE) { /* Try non-blocking read first; yield to other tasks while idle */ if (Boot->try_read_key != NULL) { Status = Boot->try_read_key(&Key); if (Status == EFI_NOT_READY) { task_yield(); continue; } } else if (Boot->read_key != NULL) { Status = Boot->read_key(&Key); } else { SAFE_PRINT(Boot, L"Console input unavailable.\n\r"); break; } if (EFI_ERROR(Status)) { read_errors++; if (read_errors == 1 || (read_errors % 64) == 0) { SAFE_PRINT(Boot, L"read_key failed: %r\n\r", Status); } continue; } read_errors = 0; if (Key.UnicodeChar == L'\r' || Key.UnicodeChar == L'\n') { /* Enter pressed: execute the buffered command */ line[len] = L'\0'; SAFE_PRINT(Boot, L"\n\r"); execute_command(Boot, line); /* Reset for next command */ len = 0; SAFE_PRINT(Boot, L"-> "); } else if (Key.ScanCode == 0x08 || Key.UnicodeChar == L'\b' || Key.UnicodeChar == 0x7F) { /* Backspace */ if (len > 0) { len--; SAFE_PRINT(Boot, L"\b \b"); } } else if (Key.UnicodeChar >= 32 && Key.UnicodeChar < 127) { /* Printable ASCII */ if (len < (sizeof(line) / sizeof(line[0]) - 1)) { line[len++] = Key.UnicodeChar; SAFE_PRINT(Boot, L"%c", Key.UnicodeChar); } } } }