feat(sh,gui): universalize binary execution, dynamic VFS, and hardware reporting

- Eliminate hardcoded program names (e.g. hello.opc) in shell hints, help, and VFS
- Automatically resolve and execute any binary by name (e.g. typing 'hello' or '<prog>')
- Dynamically populate VFS /bin from kernel module discovery (sys_module_list)
- Support path filtering in ls (e.g. 'ls /bin', 'ls /etc')
- Dynamically detect real CPU brand string via CPUID (leaf 0x80000002..0x80000004)
- Dynamically format network addresses in shell and GUI instead of hardcoded 10.0.2.15
This commit is contained in:
RarDog
2026-09-03 10:50:40 +03:00
parent de772a2de0
commit c18717539c
2 changed files with 267 additions and 44 deletions
+128 -16
View File
@@ -26,15 +26,36 @@ static VfsFile vfs_nodes[64] = {
{ "/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 },
{ "/etc/hosts", "127.0.0.1 localhost\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 },
{ "/proc/cpuinfo", "model name: x86_64 Microkernel Virtual CPU\nfeatures: long_mode syscall hhdm smp sse sse2 avx\n", false },
{ "/dev/null", "", false },
{ "/dev/uart0", "16550 Serial COM1 Port\n", false },
{ "/dev/net0", "Realtek RTL8139 Fast Ethernet PCI\n", false },
{ "/boot/hello.opc", "OpenCore Native Executable Binary (.OPC v1.0)\n", false },
{ "/dev/net0", "PCI Fast Ethernet Network Adapter\n", false },
};
static size_t vfs_count = 14;
static size_t vfs_count = 13;
static void vfs_init_modules() {
char buf[512] = {0};
int len = sys_module_list(buf, sizeof(buf) - 1);
if (len > 0) {
char *p = buf;
while (*p && vfs_count < 60) {
char mod[64] = {0};
int mi = 0;
while (*p && *p != ' ' && mi < 63) {
mod[mi++] = *p++;
}
while (*p == ' ') p++;
if (mi > 0) {
snprintf(vfs_nodes[vfs_count].name, sizeof(vfs_nodes[vfs_count].name), "/bin/%s", mod);
snprintf(vfs_nodes[vfs_count].content, sizeof(vfs_nodes[vfs_count].content), "Executable binary: %s\n", mod);
vfs_nodes[vfs_count].is_dir = false;
vfs_count++;
}
}
}
}
// Shell Environment Variables
struct EnvVar {
@@ -50,6 +71,35 @@ static EnvVar g_env[16] = {
};
static size_t g_env_count = 5;
static void get_cpu_brand(char *brand, size_t max_len) {
memset(brand, 0, max_len);
uint32_t regs[4];
__asm__ volatile("cpuid" : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3]) : "a"(0x80000000));
if (regs[0] >= 0x80000004) {
char *p = brand;
for (uint32_t leaf = 0x80000002; leaf <= 0x80000004; leaf++) {
uint32_t b_regs[4];
__asm__ volatile("cpuid" : "=a"(b_regs[0]), "=b"(b_regs[1]), "=c"(b_regs[2]), "=d"(b_regs[3]) : "a"(leaf));
if (p - brand + 16 < (int)max_len) {
memcpy(p, b_regs, 16);
p += 16;
}
}
brand[max_len - 1] = '\0';
char *src = brand;
while (*src == ' ') src++;
if (src != brand) {
memmove(brand, src, strlen(src) + 1);
}
} else {
__asm__ volatile("cpuid" : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3]) : "a"(0));
memcpy(brand, &regs[1], 4);
memcpy(brand + 4, &regs[3], 4);
memcpy(brand + 8, &regs[2], 4);
brand[12] = '\0';
}
}
static void print_fastfetch() {
sysinfo_data_t info = {0, 0, 0, 0, 0};
sys_sysinfo(&info);
@@ -71,6 +121,9 @@ static void print_fastfetch() {
gpu_info_t gpu;
bool has_gpu = (pci_detect_gpu(&gpu) == 0);
char cpu_brand[64] = {0};
get_cpu_brand(cpu_brand, sizeof(cpu_brand));
printf("\n");
printf(" \033[1;36m ___ \033[1;32mroot\033[0m@\033[1;36mopencoreC\033[0m\n");
printf(" \033[1;36m / \\ \033[0;37m-----------------\033[0m\n");
@@ -84,7 +137,9 @@ static void print_fastfetch() {
printf(" \033[1;34m [=== opencoreC ===] \033[1;34mDisplay:\033[0m 1280x800 @ 60Hz (Limine FB)\n");
}
printf(" \033[1;35m x86_64 SMP \033[1;34mDE / WM:\033[0m LVGL v8.3 Windows/KDE Compositor\n");
printf(" \033[1;35m Ring 3 Userspace \033[1;34mCPU:\033[0m QEMU Virtual CPU (4 Cores SMP)\n");
printf(" \033[1;35m Ring 3 Userspace \033[1;34mCPU:\033[0m %s (%u Cores SMP)\n",
*cpu_brand ? cpu_brand : "x86_64 Processor",
acpi.lapic_count > 0 ? (unsigned int)acpi.lapic_count : 4);
if (has_gpu) {
if (gpu.vram_mb > 0) {
printf(" \033[1;35m Fast-Path IPC Cap \033[1;34mGPU:\033[0m %s (%u MiB VRAM)\n", gpu.model_name, (unsigned int)gpu.vram_mb);
@@ -97,8 +152,16 @@ static void print_fastfetch() {
printf(" \033[1;34mMemory:\033[0m %u MiB / %u MiB (%u%%)\n",
(unsigned int)used_mb, (unsigned int)total_mb,
total_mb > 0 ? (unsigned int)(used_mb * 100 / total_mb) : 0);
printf(" \033[1;34mNetwork:\033[0m Realtek RTL8139 (10.0.2.15)\n");
printf(" \033[1;34mACPI:\033[0m S5 Poweroff, Reset, MADT 4 Cores\n");
char ip_str[32] = {0};
format_ip(g_net_cfg.ip, ip_str);
if (g_net_cfg.ip != 0) {
printf(" \033[1;34mNetwork:\033[0m PCI Ethernet (%s)\n", ip_str);
} else {
printf(" \033[1;34mNetwork:\033[0m PCI Ethernet (Unconfigured)\n");
}
printf(" \033[1;34mACPI:\033[0m S5 Poweroff, Reset, MADT %u Cores\n",
acpi.lapic_count > 0 ? (unsigned int)acpi.lapic_count : 4);
printf(" \033[1;34mSecurity:\033[0m Ring 3 Signal Fault Isolation (SIGSEGV)\n");
printf(" \033[1;34mEntropy:\033[0m Hardware RNG (RDRAND / TSC)\n\n");
printf(" \033[40m \033[41m \033[42m \033[43m \033[44m \033[45m \033[46m \033[47m \033[0m\n");
@@ -310,7 +373,7 @@ static void cmd_modules() {
}
}
printf("------------------------------------------------------\n");
puts("To run: type './hello.opc' or 'run hello.opc'\n");
puts("To run: type '<program>', './<program>', or 'run <program>'\n");
} else {
puts("modules: No boot modules detected.");
}
@@ -402,13 +465,15 @@ static void handle_command(char *cmd) {
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(" ifconfig / ip - Display network interface status");
puts(" ping [target] - Real ICMP Echo ping over network");
puts(" dhcp - Acquire network lease from DHCP server");
puts(" dns <domain> - Query domain name IP via DNS");
puts(" curl / fetch <u - Fetch webpage via TCP/IPv4 stack");
puts(" lspci - Enumerate hardware devices on PCI bus");
puts(" gpu - Display detected GPU accelerator & VRAM");
puts(" modules - List in-memory boot modules available to run");
puts(" run / ./<module> - Execute native .opc or .elf binary (e.g. ./hello.opc)");
puts(" <prog> / ./<prog>- Execute native .opc or .elf binary");
puts(" notify <msg> - Send desktop notification toast to GUI");
puts(" gui - Launch Framebuffer graphics & window desktop");
puts(" write <str> - Send Rendezvous IPC message to UART driver");
@@ -444,9 +509,22 @@ static void handle_command(char *cmd) {
puts(cmd + 5);
} else if (strcmp(cmd, "echo") == 0) {
puts("");
} else if (strcmp(cmd, "ls") == 0 || strcmp(cmd, "dir") == 0) {
} else if (strncmp(cmd, "ls", 2) == 0 || strncmp(cmd, "dir", 3) == 0) {
const char *filter = NULL;
if (strncmp(cmd, "ls ", 3) == 0) {
filter = cmd + 3;
while (*filter == ' ') filter++;
} else if (strncmp(cmd, "dir ", 4) == 0) {
filter = cmd + 4;
while (*filter == ' ') filter++;
}
puts("MODE SIZE NAME");
for (size_t i = 0; i < vfs_count; i++) {
if (filter && *filter) {
if (strncmp(vfs_nodes[i].name, filter, strlen(filter)) != 0) {
continue;
}
}
if (vfs_nodes[i].is_dir) {
printf("drwxr-xr-x 4096 %s\n", vfs_nodes[i].name);
} else {
@@ -721,9 +799,14 @@ static void handle_command(char *cmd) {
}
} else if (strcmp(cmd, "ifconfig") == 0 || strcmp(cmd, "ip") == 0) {
net_init();
char ip_str[32], mask_str[32], gw_str[32];
format_ip(g_net_cfg.ip, ip_str);
format_ip(g_net_cfg.netmask, mask_str);
format_ip(g_net_cfg.gateway, gw_str);
printf("eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> 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",
printf(" inet %s netmask %s\n", ip_str, mask_str);
printf(" gateway %s\n", gw_str);
printf(" ether %02x:%02x:%02x:%02x:%02x:%02x txqueuelen 1000 (PCI 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);
@@ -873,7 +956,33 @@ static void handle_command(char *cmd) {
puts("Powering off system...");
sys_shutdown();
} else {
printf("osh: command not found: %s\n", cmd);
char prog_name[64];
strncpy(prog_name, cmd, sizeof(prog_name) - 1);
prog_name[sizeof(prog_name) - 1] = '\0';
const char *exec_target = prog_name;
while (*exec_target == '.' || *exec_target == '/') {
exec_target++;
}
int64_t tid = sys_module_exec(exec_target);
if (tid < 0 && !strstr(exec_target, ".")) {
char opc_name[70];
snprintf(opc_name, sizeof(opc_name), "%s.opc", exec_target);
tid = sys_module_exec(opc_name);
if (tid < 0) {
char elf_name[70];
snprintf(elf_name, sizeof(elf_name), "%s.elf", exec_target);
tid = sys_module_exec(elf_name);
}
}
if (tid >= 0) {
printf("[osh] Process spawned with TID %ld on Ring 3\n", (long)tid);
for (int i = 0; i < 6; i++) sys_yield();
} else {
printf("osh: command not found: %s\n", cmd);
}
}
}
@@ -883,6 +992,9 @@ extern "C" void _start() {
sys_yield();
}
// Initialize VFS with any loaded boot modules
vfs_init_modules();
// Clean screen after all boot logs are finished
sys_log_debug("\033[2J\033[H", 7);
print_fastfetch();