From 99b7c81385e205027c52cff2026c95d410c5ae91 Mon Sep 17 00:00:00 2001 From: RarDog Date: Wed, 2 Sep 2026 16:00:56 +0300 Subject: [PATCH] test: direct zero-overhead echo console for Ring 3 sh --- servers/sh/src/main.rs | 238 ++++------------------------------------- 1 file changed, 19 insertions(+), 219 deletions(-) diff --git a/servers/sh/src/main.rs b/servers/sh/src/main.rs index 8d57e5c..b2415f6 100644 --- a/servers/sh/src/main.rs +++ b/servers/sh/src/main.rs @@ -1,240 +1,40 @@ -//! # sh — Userspace Interactive Shell (Ring 3, PID 3). +//! # sh — Direct Interactive Console (Ring 3, PID 3). //! -//! Полноценный пользовательский командный процессор, работающий полностью в Ring 3 -//! поверх VFS и системных вызовов opencoreRS. +//! Максимально простая консоль без сложной логики: читает символ и сразу выводит его. #![no_std] #![no_main] use core::panic::PanicInfo; -const PROMPT: &str = "\x1b[1;32muser\x1b[0m@\x1b[1;36mopencoreRS\x1b[0m\x1b[33m:~\x1b[0m$ "; -const MAX_LINE: usize = 256; - #[no_mangle] pub extern "C" fn _start() -> ! { - ipc_client::log("[sh] Userspace Interactive Shell started (Ring 3, PID 3)"); - ipc_client::log("[sh] Connected to TTY terminal"); - - ipc_client::println(""); - ipc_client::println("\x1b[1;36m╔═══════════════════════════════════════════════════════╗\x1b[0m"); - ipc_client::println("\x1b[1;36m║ opencoreRS v0.1.0 — Userspace Unix Shell (Ring 3) ║\x1b[0m"); - ipc_client::println("\x1b[1;36m╚═══════════════════════════════════════════════════════╝\x1b[0m"); - ipc_client::println(" Running in \x1b[1;32mRing 3 (Userspace PID 3)\x1b[0m with VFS & IPC"); - ipc_client::println(" Type \x1b[1m'help'\x1b[0m to see available commands.\r\n"); + ipc_client::print_str("\r\n"); + ipc_client::print_str("==============================================\r\n"); + ipc_client::print_str(" opencoreRS Simple Direct Console (Ring 3)\r\n"); + ipc_client::print_str(" Type characters on your keyboard:\r\n"); + ipc_client::print_str("==============================================\r\n\r\n> "); loop { - ipc_client::print_str(PROMPT); - - let mut buf = [0u8; MAX_LINE]; - let len = read_line(&mut buf); - - if len == 0 { - continue; - } - - let line = match core::str::from_utf8(&buf[..len]) { - Ok(s) => s.trim(), - Err(_) => continue, - }; - - if line.is_empty() { - continue; - } - - dispatch_command(line); - } -} - -/// Чтение строки из терминала в Ring 3 с поддержкой Backspace, Enter, Ctrl-L. -fn read_line(buf: &mut [u8]) -> usize { - let mut len = 0usize; - - loop { - // Опрашиваем символы пакетами перед уступкой кванта времени - for _ in 0..200 { - match ipc_client::read_char() { - Some(b'\r') | Some(b'\n') => { - ipc_client::print_str("\r\n"); - return len; - } - Some(0x08) | Some(0x7F) => { - if len > 0 { - len -= 1; - ipc_client::print_str("\x08 \x08"); - } - } - Some(0x0C) => { - // Ctrl-L: Clear screen - ipc_client::print_str("\x1b[2J\x1b[H"); - ipc_client::print_str(PROMPT); - if let Ok(s) = core::str::from_utf8(&buf[..len]) { - ipc_client::print_str(s); - } - } - Some(b) if b >= 0x20 && b < 0x7F => { - if len < buf.len() - 1 { - buf[len] = b; - len += 1; - let slice = [b]; - if let Ok(s) = core::str::from_utf8(&slice) { - ipc_client::print_str(s); - } - } - } - _ => {} - } - } - - ipc_client::yield_cpu(); - } -} - -/// Диспетчер команд Userspace Shell (Ring 3). -fn dispatch_command(cmdline: &str) { - let mut parts = cmdline.split_ascii_whitespace(); - let cmd = match parts.next() { - Some(c) => c, - None => return, - }; - let args: &[&str] = &[]; - let arg1 = parts.next().unwrap_or(""); - - match cmd { - "help" | "?" => { - ipc_client::println("\x1b[1;36mopencoreRS Ring 3 Shell — Built-in Commands\x1b[0m"); - ipc_client::println("\x1b[90m─────────────────────────────────────────────\x1b[0m"); - ipc_client::println(" \x1b[1;33mhelp, ?\x1b[0m Show this help menu"); - ipc_client::println(" \x1b[1;33muname [-a]\x1b[0m Display OS, kernel and architecture"); - ipc_client::println(" \x1b[1;33mls [path]\x1b[0m List VFS directory (/proc, /dev, /etc)"); - ipc_client::println(" \x1b[1;33mcat \x1b[0m Display contents of a file"); - ipc_client::println(" \x1b[1;33mecho \x1b[0m Print text to terminal"); - ipc_client::println(" \x1b[1;33mcpuinfo\x1b[0m Display CPUID vendor, model & features"); - ipc_client::println(" \x1b[1;33mlspci\x1b[0m Scan and list PCI hardware devices"); - ipc_client::println(" \x1b[1;33mifconfig, net\x1b[0m Network interface configuration & stats"); - ipc_client::println(" \x1b[1;33mping [ip]\x1b[0m Send ICMP Echo Request"); - ipc_client::println(" \x1b[1;33mclear, cls\x1b[0m Clear terminal screen"); - ipc_client::println(" \x1b[1;33mexit\x1b[0m Exit userspace shell"); - ipc_client::println(""); - } - "uname" => { - ipc_client::println("opencoreRS 0.1.0 x86_64 microkernel SMP (Ring 3 Shell)"); - } - "echo" => { - let mut first = true; - for p in cmdline.split_ascii_whitespace().skip(1) { - if !first { - ipc_client::print_str(" "); - } - ipc_client::print_str(p); - first = false; - } - ipc_client::println(""); - } - "ls" => { - let path = if arg1.is_empty() { "/" } else { arg1 }; - match path { - "/" => { - ipc_client::println("\x1b[1;34mbin dev etc proc sys\x1b[0m"); - } - "/proc" => { - ipc_client::println("\x1b[32mcpuinfo version meminfo tasks\x1b[0m"); - } - "/etc" => { - ipc_client::println("\x1b[32mhostname os-release resolv.conf\x1b[0m"); - } - "/dev" => { - ipc_client::println("\x1b[33mnull zero tty eth0 sda\x1b[0m"); - } - "/bin" => { - ipc_client::println("\x1b[1;32minit vfs sh ls cat echo ping\x1b[0m"); - } - _ => { - ipc_client::print_str("ls: cannot access '"); - ipc_client::print_str(path); - ipc_client::println("': No such file or directory"); + if let Some(ch) = ipc_client::read_char() { + if ch == b'\r' || ch == b'\n' { + ipc_client::print_str("\r\n> "); + } else if ch == 0x08 || ch == 0x7F { + ipc_client::print_str("\x08 \x08"); + } else { + let slice = [ch]; + if let Ok(s) = core::str::from_utf8(&slice) { + ipc_client::print_str(s); } } - } - "cat" => { - if arg1.is_empty() { - ipc_client::println("cat: missing file operand"); - return; - } - match arg1 { - "/proc/version" => { - ipc_client::println("opencoreRS kernel v0.1.0 (x86_64-unknown-none) Rust Microkernel"); - } - "/proc/cpuinfo" => { - ipc_client::println("vendor_id\t: Intel / AMD (Detected via CPUID)"); - ipc_client::println("model name\t: x86_64 Microkernel Core"); - ipc_client::println("flags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge sse sse2 avx"); - } - "/proc/meminfo" => { - ipc_client::println("MemTotal:\t248832 kB"); - ipc_client::println("MemFree:\t245760 kB"); - ipc_client::println("Buffers:\t 1024 kB"); - } - "/etc/hostname" => { - ipc_client::println("opencoreRS"); - } - "/etc/os-release" => { - ipc_client::println("NAME=\"opencoreRS\""); - ipc_client::println("VERSION=\"0.1.0-microkernel\""); - ipc_client::println("ID=opencore"); - ipc_client::println("PRETTY_NAME=\"opencoreRS Microkernel OS\""); - } - _ => { - ipc_client::print_str("cat: "); - ipc_client::print_str(arg1); - ipc_client::println(": No such file or directory"); - } - } - } - "cpuinfo" => { - ipc_client::println("\x1b[1;36mHardware CPU Information (Ring 3 query)\x1b[0m"); - ipc_client::println("\x1b[90m─────────────────────────────────────────────\x1b[0m"); - ipc_client::println(" \x1b[1;33mVendor :\x1b[0m Intel / AMD Processor"); - ipc_client::println(" \x1b[1;33mArchitecture:\x1b[0m x86_64 (64-bit Long Mode)"); - ipc_client::println(" \x1b[1;33mFeatures :\x1b[0m APIC, SSE, AVX, RDRAND, SMP Multi-Core\r\n"); - } - "lspci" => { - ipc_client::println("\x1b[1;36mPCI Bus Device Enumeration (Ring 3 query)\x1b[0m"); - ipc_client::println("\x1b[90m─────────────────────────────────────────────\x1b[0m"); - ipc_client::println(" \x1b[1;33m00:00.0\x1b[0m [8086:29c0] \x1b[1mHost Bridge\x1b[0m (Intel Corporation)"); - ipc_client::println(" \x1b[1;33m00:01.0\x1b[0m [1234:1111] \x1b[1mVGA Controller\x1b[0m (QEMU / Bochs Device)"); - ipc_client::println(" \x1b[1;33m00:02.0\x1b[0m [8086:100e] \x1b[1mEthernet Controller\x1b[0m (Intel E1000 Gigabit)"); - ipc_client::println(" \x1b[1;33m00:03.0\x1b[0m [8086:2922] \x1b[1mSATA / AHCI Controller\x1b[0m (Intel Corporation)"); - ipc_client::println(" \x1b[1;33m00:1f.0\x1b[0m [8086:2918] \x1b[1mISA Bridge\x1b[0m (Intel Corporation)\r\n"); - } - "ifconfig" | "net" => { - ipc_client::println("\x1b[1;36mNetwork Interface Configuration (eth0)\x1b[0m"); - ipc_client::println("\x1b[90m─────────────────────────────────────────────\x1b[0m"); - ipc_client::println(" \x1b[1;33mInterface :\x1b[0m eth0 (Intel E1000 Gigabit)"); - ipc_client::println(" \x1b[1;33mMAC Address:\x1b[0m 52:54:00:12:34:56"); - ipc_client::println(" \x1b[1;33mIPv4 :\x1b[0m 10.0.2.15 / 24"); - ipc_client::println(" \x1b[1;33mGateway :\x1b[0m 10.0.2.2\r\n"); - } - "ping" => { - ipc_client::println("PING 10.0.2.2 (10.0.2.2): 64 data bytes (ICMP Echo sent via kernel netstack)"); - ipc_client::println("64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.42 ms"); - } - "clear" | "cls" => { - ipc_client::print_str("\x1b[2J\x1b[H"); - } - "exit" => { - ipc_client::println("[sh] Exiting userspace shell..."); - ipc_client::exit(0); - } - _ => { - ipc_client::print_str("\x1b[31msh: command not found: \x1b[0m"); - ipc_client::println(cmd); + } else { + ipc_client::yield_cpu(); } } } #[panic_handler] fn panic(_info: &PanicInfo) -> ! { - ipc_client::log("[sh] Panic in userspace shell!"); + ipc_client::log("[sh] Panic in simple shell!"); ipc_client::exit(1); }