/** * opencoreC - Virtual File System Server (Ring 3 User Space) * Centralized file system daemon managing in-memory and virtual file hierarchy. * Listens on VFS_ENDPOINT (5) and handles synchronous IPC requests. */ #include "stdio.h" #include "string.h" #include "abi/syscalls.h" #include "abi/ipc.h" #include "abi/vfs.h" #include "ahci.h" #include "fat32.h" #define MAX_VFS_NODES 64 struct VfsNode { char name[48]; bool is_dir; uint32_t size; char content[1024]; }; static VfsNode g_nodes[MAX_VFS_NODES]; static size_t g_node_count = 0; static void vfs_add_dir(const char *name) { if (g_node_count >= MAX_VFS_NODES) return; strncpy(g_nodes[g_node_count].name, name, sizeof(g_nodes[0].name) - 1); g_nodes[g_node_count].is_dir = true; g_nodes[g_node_count].size = 4096; g_nodes[g_node_count].content[0] = '\0'; g_node_count++; } static void vfs_add_file(const char *name, const char *content) { if (g_node_count >= MAX_VFS_NODES) return; strncpy(g_nodes[g_node_count].name, name, sizeof(g_nodes[0].name) - 1); g_nodes[g_node_count].is_dir = false; uint32_t len = (uint32_t)strlen(content); if (len >= sizeof(g_nodes[0].content)) len = sizeof(g_nodes[0].content) - 1; memcpy(g_nodes[g_node_count].content, content, len); g_nodes[g_node_count].content[len] = '\0'; g_nodes[g_node_count].size = len; g_node_count++; } static void vfs_init() { g_node_count = 0; vfs_add_dir("/"); vfs_add_dir("/bin"); vfs_add_dir("/etc"); vfs_add_dir("/proc"); vfs_add_dir("/dev"); vfs_add_dir("/tmp"); vfs_add_dir("/disk"); vfs_add_file("/disk/readme.txt", "This directory is mounted on the physical AHCI SATA / USB disk!\n" "Files saved here are permanently written to FAT32 sectors.\n"); if (ahci_detect_and_init() == 0) { if (fat32_mount() == 0) { puts("[VFS-SERVER] AHCI SATA Disk successfully mounted at /disk (FAT32 filesystem)"); } } vfs_add_file("/etc/os-release", "NAME=\"opencoreC\"\n" "VERSION=\"0.1.0-release\"\n" "ID=opencorec\n" "PRETTY_NAME=\"opencoreC Microkernel x86_64\"\n"); vfs_add_file("/etc/motd", "=======================================================\n" " Welcome to opencoreC Pure Microkernel (x86_64)!\n" " Servers: init, uart, vfs, net, procmgr, sh, gui\n" "=======================================================\n"); vfs_add_file("/etc/hosts", "127.0.0.1 localhost\n"); vfs_add_file("/proc/version", "opencoreC version 0.1.0-microkernel (Rust Ring 0 + C++ Ring 3)\n"); vfs_add_file("/proc/cpuinfo", "model name: x86_64 SMP Microkernel Processor\ncores: 4\n"); vfs_add_file("/dev/null", ""); vfs_add_file("/dev/uart0", ""); vfs_add_file("/dev/net0", ""); // Dynamically discover in-memory boot modules from Limine char mbuf[512] = {0}; int len = sys_module_list(mbuf, sizeof(mbuf) - 1); if (len > 0) { char *p = mbuf; while (*p) { char mod_name[48] = {0}; int mi = 0; while (*p && *p != ' ' && mi < 40) { mod_name[mi++] = *p++; } while (*p == ' ') p++; if (mi > 0) { char full_path[56]; snprintf(full_path, sizeof(full_path), "/bin/%s", mod_name); vfs_add_file(full_path, "[Executable Binary Module]"); } } } } extern "C" void _start(void) { vfs_init(); puts("[VFS-SERVER] Virtual File System Daemon Started (Endpoint 5, Ring 3)."); uint64_t last_client = 0; uint64_t reply_val0 = 0; uint64_t reply_val1 = 0; while (1) { uint64_t sender_tid = 0; uint64_t opcode = 0; uint64_t arg0 = 0; uint64_t arg1 = 0; sysret_t ret = sys_ipc_reply_recv_raw( VFS_ENDPOINT, last_client, reply_val0, reply_val1, &sender_tid, &opcode, &arg0, &arg1 ); if (ret == 0 && sender_tid != 0) { last_client = sender_tid; if (opcode == VFS_OP_STAT) { // Path passed packed in arg0 (first 8 bytes) + arg1 (next 8 bytes) char path[32] = {0}; memcpy(path, &arg0, 8); memcpy(path + 8, &arg1, 8); bool found = false; for (size_t i = 0; i < g_node_count; i++) { if (strcmp(g_nodes[i].name, path) == 0) { reply_val0 = 0; // Success reply_val1 = g_nodes[i].size | (g_nodes[i].is_dir ? 0x80000000ULL : 0ULL); found = true; break; } } if (!found) { reply_val0 = (uint64_t)-1; // Not found reply_val1 = 0; } } else if (opcode == VFS_OP_LIST) { // arg0 = index size_t idx = (size_t)arg0; if (idx < g_node_count) { reply_val0 = 0; // Success reply_val1 = (uint64_t)g_nodes[idx].size | (g_nodes[idx].is_dir ? 0x80000000ULL : 0ULL); } else { reply_val0 = (uint64_t)-1; // End of list reply_val1 = 0; } } else if (opcode == VFS_OP_READ_FILE) { // arg0: packed name (first 8 bytes), arg1: offset char path[16] = {0}; memcpy(path, &arg0, 8); size_t offset = (size_t)arg1; bool found = false; for (size_t i = 0; i < g_node_count; i++) { if (strcmp(g_nodes[i].name, path) == 0) { found = true; if (offset < g_nodes[i].size) { uint64_t chunk = 0; size_t avail = g_nodes[i].size - offset; if (avail > 8) avail = 8; memcpy(&chunk, g_nodes[i].content + offset, avail); reply_val0 = avail; reply_val1 = chunk; } else { reply_val0 = 0; // EOF reply_val1 = 0; } break; } } if (!found) { reply_val0 = (uint64_t)-1; reply_val1 = 0; } } else if (opcode == VFS_OP_WRITE_FILE) { // arg0: packed name (first 8 bytes), arg1: 8 bytes data char path[16] = {0}; memcpy(path, &arg0, 8); bool found = false; for (size_t i = 0; i < g_node_count; i++) { if (strcmp(g_nodes[i].name, path) == 0) { found = true; memcpy(g_nodes[i].content, &arg1, 8); g_nodes[i].size = 8; reply_val0 = 0; reply_val1 = 8; break; } } if (!found && g_node_count < MAX_VFS_NODES) { vfs_add_file(path, ""); memcpy(g_nodes[g_node_count - 1].content, &arg1, 8); g_nodes[g_node_count - 1].size = 8; reply_val0 = 0; reply_val1 = 8; } } else { reply_val0 = (uint64_t)-1; reply_val1 = 0; } } else { last_client = 0; sys_yield(); } } }