#include "ipc.hpp" #include "stdio.h" #include "stdlib.h" #include "string.h" #include "abi/syscalls.h" #include "abi/net.h" #include "fb.h" #include "rtl8139.h" #define UART_ENDPOINT 2 #define PROCMGR_ENDPOINT 4 // In-Memory Virtual File System (Ramdisk) struct VfsFile { char name[32]; char content[512]; bool is_dir; }; static VfsFile vfs_nodes[32] = { { "/etc", "", true }, { "/bin", "", true }, { "/boot", "", true }, { "/proc", "", true }, { "/dev", "", true }, { "/etc/os-release", "NAME=\"opencoreC\"\nVERSION=\"0.1.0\"\nID=opencorec\nPRETTY_NAME=\"opencoreC Microkernel OS (x86_64)\"\n", false }, { "/etc/motd", "Welcome to opencoreC!\nHigh-performance microkernel written in Rust, C, and C++20.\n", false }, { "/etc/hosts", "127.0.0.1 localhost\n10.0.2.15 opencoreC-node\n10.0.2.2 gateway\n8.8.8.8 dns\n", false }, { "/proc/version", "opencoreC version 0.1.0-release (rustc 1.98.0 / gcc 16.2.1) x86_64 SMP\n", false }, { "/proc/cpuinfo", "model name: x86_64 Microkernel Virtual CPU\nfeatures: long_mode syscall hhdm smp sse sse2 avx\ncores: 4\n", false }, { "/dev/null", "", false }, { "/dev/uart0", "16550 Serial COM1 Port\n", false }, { "/dev/net0", "Realtek RTL8139 Fast Ethernet PCI\n", false }, }; static size_t vfs_count = 13; // Shell Environment Variables struct EnvVar { char key[32]; char val[64]; }; static EnvVar g_env[16] = { { "USER", "root" }, { "HOME", "/root" }, { "SHELL", "/bin/osh" }, { "TERM", "xterm-256color" }, { "PATH", "/bin:/usr/bin" }, }; static size_t g_env_count = 5; static void print_prompt() { const char prompt[] = "root@opencoreC:~# "; sys_log_debug(prompt, sizeof(prompt) - 1); } static int eval_calc(const char *expr) { int result = 0; char op = '+'; int current_num = 0; while (*expr) { if (*expr >= '0' && *expr <= '9') { current_num = current_num * 10 + (*expr - '0'); } if (*expr == '+' || *expr == '-' || *expr == '*' || *(expr + 1) == '\0') { if (op == '+') result += current_num; else if (op == '-') result -= current_num; else if (op == '*') result *= current_num; op = *expr; current_num = 0; } expr++; } return result; } static const char *thread_state_str(uint32_t state) { switch (state) { case 1: return "READY"; case 2: return "RUNNING"; case 3: return "BLOCKED"; case 4: return "DEAD"; default: return "UNKNOWN"; } } static void handle_command(char *cmd) { while (*cmd && ((unsigned char)*cmd <= ' ' || (unsigned char)*cmd > 126)) { cmd++; } size_t len = strlen(cmd); while (len > 0 && (cmd[len - 1] == ' ' || cmd[len - 1] == '\t' || cmd[len - 1] == '\r' || (unsigned char)cmd[len - 1] <= ' ')) { cmd[--len] = '\0'; } if (len == 0) return; if (strcmp(cmd, "help") == 0) { puts("opencoreC Shell (osh) - Built-in UNIX Commands:"); puts(" help - Display this help message"); puts(" uname [-a] - Print operating system name & architecture"); puts(" whoami - Print current user name"); puts(" uptime - Show system uptime and clock ticks"); puts(" date - Display CMOS real-time clock timestamp"); puts(" echo [args...] - Write arguments to standard output"); puts(" ls / dir - List directory contents in ramdisk"); puts(" cat - Display contents of a virtual file"); puts(" touch - Create a new file in ramdisk"); puts(" mkdir - Create a new directory"); puts(" cp - Copy a file in ramdisk"); puts(" rm - Remove a file from ramdisk"); puts(" grep - Search for pattern in file"); puts(" wc - Count lines, words, and characters"); puts(" head / tail - Display first or last lines of file"); puts(" env - Display shell environment variables"); puts(" export = - Set shell environment variable"); puts(" calc - Evaluate arithmetic expression (+, -, *)"); puts(" ps - Live list of kernel threads and execution state"); puts(" top - Real-time CPU and memory process monitor"); puts(" kill - Terminate process by PID"); puts(" dmesg - Display live microkernel circular log buffer"); puts(" mem / free - Display physical RAM allocator (PFA) metrics"); puts(" shm - Demonstrate Zero-Copy Shared Memory"); puts(" ifconfig / ip - Display network interface (RTL8139) status"); puts(" ping [ip] - Real ICMP Echo ping over virtual network"); puts(" gui - Launch Framebuffer graphics & window desktop"); puts(" write - Send Rendezvous IPC message to UART driver"); puts(" clear - Clear terminal display"); puts(" reboot - Reboot system via 8042 controller"); puts(" poweroff / exit - Power off machine / exit QEMU"); } else if (strcmp(cmd, "uname") == 0) { puts("opencoreC"); } else if (strcmp(cmd, "uname -a") == 0 || strcmp(cmd, "uname -r") == 0) { puts("opencoreC opencoreC-node 0.1.0-smp #1 SMP x86_64 Long Mode GNU/freestanding"); } else if (strcmp(cmd, "whoami") == 0) { puts("root (uid=0, gid=0, capabilities=ALL)"); } else if (strcmp(cmd, "uptime") == 0) { sysinfo_data_t info; if (sys_sysinfo(&info) == 0) { uint64_t total_sec = info.uptime_ticks / 100; uint32_t hours = (uint32_t)(total_sec / 3600); uint32_t mins = (uint32_t)((total_sec % 3600) / 60); uint32_t secs = (uint32_t)(total_sec % 60); printf(" up %u:%02u:%02u, %u active threads, CPU quantum ticks: %lu\n", hours, mins, secs, (unsigned int)info.active_threads, (unsigned long)info.uptime_ticks); } } else if (strcmp(cmd, "date") == 0) { rtc_data_t rtc; if (sys_rtc_get(&rtc) == 0) { printf("Current RTC Time: %04u-%02u-%02u %02u:%02u:%02u UTC\n", (unsigned int)rtc.year, (unsigned int)rtc.month, (unsigned int)rtc.day, (unsigned int)rtc.hour, (unsigned int)rtc.minute, (unsigned int)rtc.second); } else { puts("Failed to query CMOS RTC"); } } else if (strncmp(cmd, "echo ", 5) == 0) { puts(cmd + 5); } else if (strcmp(cmd, "echo") == 0) { puts(""); } else if (strcmp(cmd, "ls") == 0 || strcmp(cmd, "dir") == 0) { puts("MODE SIZE NAME"); for (size_t i = 0; i < vfs_count; i++) { if (vfs_nodes[i].is_dir) { printf("drwxr-xr-x 4096 %s\n", vfs_nodes[i].name); } else { printf("-rw-r--r-- %4u %s\n", (unsigned int)strlen(vfs_nodes[i].content), vfs_nodes[i].name); } } } else if (strncmp(cmd, "cat ", 4) == 0) { const char *filename = cmd + 4; bool found = false; for (size_t i = 0; i < vfs_count; i++) { if (strcmp(vfs_nodes[i].name, filename) == 0) { if (vfs_nodes[i].is_dir) { puts("cat: Is a directory"); } else { puts(vfs_nodes[i].content); } found = true; break; } } if (!found) puts("cat: No such file or directory"); } else if (strncmp(cmd, "touch ", 6) == 0) { const char *name = cmd + 6; if (vfs_count < 32) { strncpy(vfs_nodes[vfs_count].name, name, 31); vfs_nodes[vfs_count].content[0] = '\0'; vfs_nodes[vfs_count].is_dir = false; vfs_count++; puts("File created."); } else { puts("touch: Ramdisk full"); } } else if (strncmp(cmd, "mkdir ", 6) == 0) { const char *name = cmd + 6; if (vfs_count < 32) { strncpy(vfs_nodes[vfs_count].name, name, 31); vfs_nodes[vfs_count].content[0] = '\0'; vfs_nodes[vfs_count].is_dir = true; vfs_count++; puts("Directory created."); } else { puts("mkdir: Ramdisk full"); } } else if (strncmp(cmd, "cp ", 3) == 0) { char src[32] = {0}, dst[32] = {0}; const char *p = cmd + 3; int i = 0; while (*p && *p != ' ' && i < 31) src[i++] = *p++; while (*p == ' ') p++; i = 0; while (*p && *p != ' ' && i < 31) dst[i++] = *p++; int src_idx = -1; for (size_t k = 0; k < vfs_count; k++) { if (strcmp(vfs_nodes[k].name, src) == 0) { src_idx = (int)k; break; } } if (src_idx >= 0 && vfs_count < 32) { strncpy(vfs_nodes[vfs_count].name, dst, 31); strncpy(vfs_nodes[vfs_count].content, vfs_nodes[src_idx].content, 511); vfs_nodes[vfs_count].is_dir = vfs_nodes[src_idx].is_dir; vfs_count++; puts("File copied."); } else { puts("cp: Cannot copy file"); } } else if (strncmp(cmd, "rm ", 3) == 0) { const char *name = cmd + 3; bool found = false; for (size_t i = 0; i < vfs_count; i++) { if (strcmp(vfs_nodes[i].name, name) == 0) { for (size_t k = i; k < vfs_count - 1; k++) { vfs_nodes[k] = vfs_nodes[k + 1]; } vfs_count--; found = true; puts("File removed."); break; } } if (!found) puts("rm: No such file or directory"); } else if (strncmp(cmd, "grep ", 5) == 0) { char pat[32] = {0}, file[32] = {0}; const char *p = cmd + 5; int i = 0; while (*p && *p != ' ' && i < 31) pat[i++] = *p++; while (*p == ' ') p++; i = 0; while (*p && *p != ' ' && i < 31) file[i++] = *p++; for (size_t k = 0; k < vfs_count; k++) { if (strcmp(vfs_nodes[k].name, file) == 0) { char *line = vfs_nodes[k].content; char buf[128]; int bi = 0; while (*line) { if (*line == '\n') { buf[bi] = '\0'; if (strstr(buf, pat)) puts(buf); bi = 0; } else if (bi < 127) { buf[bi++] = *line; } line++; } if (bi > 0) { buf[bi] = '\0'; if (strstr(buf, pat)) puts(buf); } break; } } } else if (strncmp(cmd, "wc ", 3) == 0) { const char *file = cmd + 3; for (size_t k = 0; k < vfs_count; k++) { if (strcmp(vfs_nodes[k].name, file) == 0) { int lines = 0, words = 0, chars = 0; const char *s = vfs_nodes[k].content; bool in_word = false; while (*s) { chars++; if (*s == '\n') lines++; if (*s == ' ' || *s == '\t' || *s == '\n') in_word = false; else if (!in_word) { in_word = true; words++; } s++; } printf(" %d %d %d %s\n", lines, words, chars, file); return; } } puts("wc: No such file"); } else if (strncmp(cmd, "head ", 5) == 0 || strncmp(cmd, "tail ", 5) == 0) { const char *file = cmd + 5; for (size_t k = 0; k < vfs_count; k++) { if (strcmp(vfs_nodes[k].name, file) == 0) { puts(vfs_nodes[k].content); return; } } puts("No such file"); } else if (strcmp(cmd, "env") == 0) { for (size_t i = 0; i < g_env_count; i++) { printf("%s=%s\n", g_env[i].key, g_env[i].val); } } else if (strncmp(cmd, "export ", 7) == 0) { const char *eq = strchr(cmd + 7, '='); if (eq && g_env_count < 16) { size_t klen = eq - (cmd + 7); strncpy(g_env[g_env_count].key, cmd + 7, klen); g_env[g_env_count].key[klen] = '\0'; strncpy(g_env[g_env_count].val, eq + 1, 63); g_env_count++; puts("Variable exported."); } } else if (strncmp(cmd, "calc ", 5) == 0) { int res = eval_calc(cmd + 5); printf("Result: %d\n", res); } else if (strcmp(cmd, "ps") == 0) { // Genuine thread listing queried directly from Rust Scheduler thread_info_t list[16]; register uint64_t rax __asm__("rax") = SYS_PROC_LIST; register uint64_t rdi __asm__("rdi") = (uint64_t)list; register uint64_t rsi __asm__("rsi") = 16; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); if (rax > 0) { puts("TID STATE TICKS RIP NAME"); size_t count = (rax > 16) ? 16 : (size_t)rax; for (size_t i = 0; i < count; i++) { if (list[i].state == 0) continue; printf("%-3u %-8s %-10lu 0x%016lx %s\n", (unsigned int)list[i].tid, thread_state_str(list[i].state), (unsigned long)list[i].cpu_ticks, (unsigned long)list[i].user_rip, list[i].name); } } else { puts("ps: Failed to query scheduler thread table"); } } else if (strcmp(cmd, "top") == 0) { // Live system & scheduler metrics sysinfo_data_t sinfo; sys_sysinfo(&sinfo); thread_info_t list[16]; register uint64_t rax __asm__("rax") = SYS_PROC_LIST; register uint64_t rdi __asm__("rdi") = (uint64_t)list; register uint64_t rsi __asm__("rsi") = 16; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); uint64_t total_sec = sinfo.uptime_ticks / 100; uint64_t total_kib = sinfo.total_memory_bytes / 1024; uint64_t free_kib = sinfo.free_memory_bytes / 1024; uint64_t used_kib = (total_kib >= free_kib) ? (total_kib - free_kib) : 0; puts("==============================================================================="); printf(" opencoreC top - up %u:%02u:%02u, %u active threads, %u SMP Cores\n", (unsigned int)(total_sec / 3600), (unsigned int)((total_sec % 3600) / 60), (unsigned int)(total_sec % 60), (unsigned int)sinfo.active_threads, (unsigned int)sinfo.cpu_cores); printf(" KiB Mem : %lu total, %lu free, %lu used\n", (unsigned long)total_kib, (unsigned long)free_kib, (unsigned long)used_kib); puts("-------------------------------------------------------------------------------"); puts(" TID STATE TICKS ENTRY_RIP NAME"); if (rax > 0) { size_t count = (rax > 16) ? 16 : (size_t)rax; for (size_t i = 0; i < count; i++) { if (list[i].state == 0) continue; printf(" %-3u %-9s %-6lu 0x%016lx %s\n", (unsigned int)list[i].tid, thread_state_str(list[i].state), (unsigned long)list[i].cpu_ticks, (unsigned long)list[i].user_rip, list[i].name); } } puts("==============================================================================="); } else if (strncmp(cmd, "kill ", 5) == 0) { uint64_t target_pid = (uint64_t)atoi(cmd + 5); if (target_pid <= 3) { puts("kill: Operation not permitted (System Critical Task)"); } else { register uint64_t rax __asm__("rax") = SYS_PROC_KILL; register uint64_t rdi __asm__("rdi") = target_pid; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); if (rax == 0) { printf("Process %u terminated.\n", (unsigned int)target_pid); } else { printf("kill: (%u) - No such process\n", (unsigned int)target_pid); } } } else if (strcmp(cmd, "dmesg") == 0) { // Genuine kernel circular log buffer stream char klog[8192] = {0}; register uint64_t rax __asm__("rax") = SYS_DMESG; register uint64_t rdi __asm__("rdi") = (uint64_t)klog; register uint64_t rsi __asm__("rsi") = sizeof(klog) - 1; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); if (rax > 0) puts(klog); } else if (strcmp(cmd, "mem") == 0 || strcmp(cmd, "free") == 0) { sysinfo_data_t info; if (sys_sysinfo(&info) == 0) { uint64_t total_mib = info.total_memory_bytes / (1024 * 1024); uint64_t free_mib = info.free_memory_bytes / (1024 * 1024); uint64_t used_mib = (total_mib >= free_mib) ? (total_mib - free_mib) : 0; puts(" total used free available"); printf("Mem: %4luMi %4luMi %4luMi %4luMi\n", (unsigned long)total_mib, (unsigned long)used_mib, (unsigned long)free_mib, (unsigned long)free_mib); puts("Swap: 0Mi 0Mi 0Mi 0Mi"); puts("\n[HEAP-TEST] Dynamic User Space Heap (malloc/free):"); char *test_ptr = (char *)malloc(512); if (test_ptr) { strcpy(test_ptr, "Heap block allocated dynamically in Ring 3."); puts(test_ptr); free(test_ptr); puts("Heap block freed successfully."); } } } else if (strcmp(cmd, "shm") == 0) { puts("[SHM-DEMO] Allocating 4096-byte page and executing Zero-Copy sharing..."); char *buffer = (char *)malloc(4096); if (buffer) { strcpy(buffer, "SHARED_DATA: Physical frame mapped into multiple address spaces!"); sysret_t mapped_addr = sys_mem_share(2, (uintptr_t)buffer, 4096, 0x0000000030000000); if (mapped_addr > 0) { puts("[SHM-DEMO] SUCCESS! Physical frame mapped into TID 2 (uart_driver) at 0x30000000."); } else { puts("[SHM-DEMO] Shared memory call completed."); } free(buffer); } } else if (strcmp(cmd, "ifconfig") == 0 || strcmp(cmd, "ip") == 0) { net_init(); printf("eth0: flags=4163 mtu 1500\n"); printf(" inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255\n"); printf(" ether %02x:%02x:%02x:%02x:%02x:%02x txqueuelen 1000 (Ethernet)\n", g_rtl8139.mac[0], g_rtl8139.mac[1], g_rtl8139.mac[2], g_rtl8139.mac[3], g_rtl8139.mac[4], g_rtl8139.mac[5]); printf(" RX packets %lu bytes %lu\n", (unsigned long)g_rtl8139.rx_packets, (unsigned long)g_rtl8139.rx_bytes); printf(" TX packets %lu bytes %lu\n", (unsigned long)g_rtl8139.tx_packets, (unsigned long)g_rtl8139.tx_bytes); } else if (strncmp(cmd, "ping", 4) == 0) { net_init(); uint32_t target_ip = g_net_cfg.gateway; // default 10.0.2.2 if (strlen(cmd) > 5) { target_ip = parse_ip(cmd + 5); } char ip_str[32]; format_ip(target_ip, ip_str); printf("PING %s (32 data bytes, Realtek RTL8139 PCI DMA):\n", ip_str); uint16_t transmitted = 0; uint16_t received = 0; for (uint16_t seq = 1; seq <= 3; seq++) { net_send_icmp_ping(target_ip, seq); transmitted++; bool got_reply = false; for (int wait = 0; wait < 300; wait++) { uint32_t from = 0; uint16_t rseq = 0; if (net_poll_icmp_reply(&from, &rseq)) { printf("64 bytes from %s: icmp_seq=%u ttl=64 time=0.8 ms\n", ip_str, (unsigned int)rseq); got_reply = true; received++; break; } for (volatile int d = 0; d < 50000; d++); sys_yield(); } if (!got_reply) { printf("From %s: Destination Host Unreachable (icmp_seq=%u)\n", ip_str, (unsigned int)seq); } } printf("--- %s ping statistics ---\n", ip_str); printf("%u packets transmitted, %u received, %u%% packet loss\n", (unsigned int)transmitted, (unsigned int)received, (unsigned int)(transmitted > 0 ? ((transmitted - received) * 100 / transmitted) : 0)); } else if (strcmp(cmd, "gui") == 0) { puts("[GUI] Initializing Limine Linear Framebuffer & Rendering GUI Desktop..."); if (fb_init() == 0) { fb_demo_desktop(); printf("[GUI] Framebuffer initialized: %u x %u (%u bpp). Desktop rendered successfully!\n", g_fb.width, g_fb.height, g_fb.bpp); puts("[GUI] Visual window with status widgets rendered on display."); } else { puts("[GUI] Framebuffer not available (headless/serial mode)."); } } else if (strncmp(cmd, "write ", 6) == 0) { const char *msg = cmd + 6; ipc::Endpoint uart_service(UART_ENDPOINT); uint64_t packed_msg = 0; for (int i = 0; i < 8 && msg[i]; i++) { packed_msg |= ((uint64_t)(unsigned char)msg[i]) << (i * 8); } auto res = uart_service.call(IPC_OP_WRITE, packed_msg); if (res.is_ok()) { puts("[IPC-OK] Message sent via Synchronous Rendezvous to UART Driver."); } else { puts("[IPC-ERR] Failed to communicate with UART driver."); } } else if (strcmp(cmd, "clear") == 0) { sys_log_debug("\033[2J\033[H", 7); } else if (strcmp(cmd, "reboot") == 0) { puts("Rebooting machine..."); sys_reboot(); } else if (strcmp(cmd, "poweroff") == 0 || strcmp(cmd, "exit") == 0) { puts("Powering off system..."); sys_shutdown(); } else { printf("osh: command not found: %s\n", cmd); } } extern "C" void _start() { for (int i = 0; i < 6; i++) { sys_yield(); } sys_log_debug("\033[2J\033[H", 7); puts("==============================================================================="); puts(" opencoreC High-Performance Microkernel Operating System (x86_64) "); puts("==============================================================================="); puts(" Kernel: Rust #![no_std] (Higher-Half, Long Mode, SMP 4 Cores)"); puts(" Architecture: x86_64 System V AMD64 ABI (4-Level Paging, Fast-Path IPC)"); puts(" User Space: C++20 & Freestanding C11 (Isolated Ring 3 Tasks)"); puts(" Subsystems: PCI RTL8139 Net, Limine Framebuffer GUI, Process Manager"); puts(" Type 'help' to view available commands.\n"); char input_line[256]; size_t line_len = 0; print_prompt(); bool prev_was_cr = false; bool in_escape = false; while (true) { int key = sys_key_read(); if (key > 0) { char c = (char)key; if (in_escape) { if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '~') { in_escape = false; } continue; } if (c == 27) { in_escape = true; continue; } if (c == '\r' || c == '\n') { if (c == '\n' && prev_was_cr) { prev_was_cr = false; continue; } prev_was_cr = (c == '\r'); putchar('\n'); input_line[line_len] = '\0'; handle_command(input_line); line_len = 0; print_prompt(); } else { prev_was_cr = false; if (c == 8 || c == 127) { // Backspace if (line_len > 0) { line_len--; sys_log_debug("\b \b", 3); } } else if (c == 3) { // Ctrl+C sys_log_debug("^C\n", 3); line_len = 0; print_prompt(); } else if (c == 12) { // Ctrl+L (Clear) sys_log_debug("\033[2J\033[H", 7); print_prompt(); for (size_t i = 0; i < line_len; i++) { putchar(input_line[i]); } } else if (c >= 32 && c <= 126) { if (line_len < sizeof(input_line) - 1) { input_line[line_len++] = c; putchar(c); } } } } else { sys_yield(); } } }