feat(microkernel): implement pure microkernel architecture with vfs_server, net_server, and procmgr

- Added vfs_server in Ring 3 (Endpoint 5) managing unified VFS tree (/, /bin, /etc, /proc, /dev, /tmp)
- Added net_server in Ring 3 (Endpoint 6) owning RTL8139 hardware NIC, DHCP, DNS, and TCP/IPv4 stack
- Refactored procmgr in Ring 3 (Endpoint 4) to handle userspace process spawning via PROC_OP_SPAWN
- Added primitive microkernel syscalls in Ring 0: SYS_TASK_CREATE (29), SYS_TASK_MAP_PAGE (30), SYS_TASK_START (31)
- Updated shell (sh) and desktop GUI (gui_server) to delegate process management and I/O to Ring 3 daemons
- Expanded boot pipeline to orchestrate 7 concurrent Ring 3 servers across dedicated SMP CPU cores
This commit is contained in:
RarDog
2026-09-03 11:03:35 +03:00
parent c18717539c
commit 5a4206acb6
15 changed files with 604 additions and 34 deletions
+214
View File
@@ -0,0 +1,214 @@
/**
* 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"
#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_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();
}
}
}