kernel_proc->state = PROCESS_RUNNING;
kernel_proc->wake_at_tick = 0;
kernel_proc->addr_space = hal_cpu_get_address_space();
+
+ for (int i = 0; i < PROCESS_MAX_FILES; i++) {
+ kernel_proc->files[i] = NULL;
+ }
current_process = kernel_proc;
ready_queue_head = kernel_proc;
proc->state = PROCESS_READY;
proc->addr_space = current_process->addr_space;
proc->wake_at_tick = 0;
+
+ for (int i = 0; i < PROCESS_MAX_FILES; i++) {
+ proc->files[i] = NULL;
+ }
void* stack_phys = pmm_alloc_page_low();
if (!stack_phys) {
#include "syscall.h"
#include "idt.h"
+#include "fs.h"
+#include "heap.h"
+#include "process.h"
#include "uart_console.h"
#include "uaccess.h"
#include <stddef.h>
+struct file {
+ fs_node_t* node;
+ uint32_t offset;
+ uint32_t flags;
+};
+
+static int fd_alloc(struct file* f) {
+ if (!current_process || !f) return -1;
+
+ for (int fd = 3; fd < PROCESS_MAX_FILES; fd++) {
+ if (current_process->files[fd] == NULL) {
+ current_process->files[fd] = f;
+ return fd;
+ }
+ }
+ return -1;
+}
+
+static struct file* fd_get(int fd) {
+ if (!current_process) return NULL;
+ if (fd < 0 || fd >= PROCESS_MAX_FILES) return NULL;
+ return current_process->files[fd];
+}
+
+static int fd_close(int fd) {
+ if (!current_process) return -1;
+ if (fd < 0 || fd >= PROCESS_MAX_FILES) return -1;
+
+ struct file* f = current_process->files[fd];
+ if (!f) return -1;
+ current_process->files[fd] = NULL;
+ kfree(f);
+ return 0;
+}
+
+static int syscall_open_impl(const char* user_path, uint32_t flags) {
+ (void)flags;
+ if (!user_path) return -1;
+
+ char path[128];
+ for (size_t i = 0; i < sizeof(path); i++) {
+ if (copy_from_user(&path[i], &user_path[i], 1) < 0) {
+ return -1;
+ }
+ if (path[i] == 0) break;
+ if (i + 1 == sizeof(path)) {
+ path[sizeof(path) - 1] = 0;
+ break;
+ }
+ }
+
+ fs_node_t* node = vfs_lookup(path);
+ if (!node) return -1;
+ if ((node->flags & FS_FILE) == 0) return -1;
+
+ struct file* f = (struct file*)kmalloc(sizeof(*f));
+ if (!f) return -1;
+ f->node = node;
+ f->offset = 0;
+ f->flags = 0;
+
+ int fd = fd_alloc(f);
+ if (fd < 0) {
+ kfree(f);
+ return -1;
+ }
+ return fd;
+}
+
+static int syscall_read_impl(int fd, void* user_buf, uint32_t len) {
+ if (len > 1024 * 1024) return -1;
+ if (user_range_ok(user_buf, (size_t)len) == 0) return -1;
+
+ struct file* f = fd_get(fd);
+ if (!f || !f->node) return -1;
+
+ uint8_t kbuf[256];
+ uint32_t total = 0;
+ while (total < len) {
+ uint32_t chunk = len - total;
+ if (chunk > sizeof(kbuf)) chunk = (uint32_t)sizeof(kbuf);
+
+ uint32_t rd = vfs_read(f->node, f->offset, chunk, kbuf);
+ if (rd == 0) break;
+
+ if (copy_to_user((uint8_t*)user_buf + total, kbuf, rd) < 0) {
+ return -1;
+ }
+
+ f->offset += rd;
+ total += rd;
+
+ if (rd < chunk) break;
+ }
+
+ return (int)total;
+}
+
static void syscall_handler(struct registers* regs) {
uint32_t syscall_no = regs->eax;
return;
}
+ if (syscall_no == SYSCALL_OPEN) {
+ const char* path = (const char*)regs->ebx;
+ uint32_t flags = regs->ecx;
+ regs->eax = (uint32_t)syscall_open_impl(path, flags);
+ return;
+ }
+
+ if (syscall_no == SYSCALL_READ) {
+ int fd = (int)regs->ebx;
+ void* buf = (void*)regs->ecx;
+ uint32_t len = regs->edx;
+ regs->eax = (uint32_t)syscall_read_impl(fd, buf, len);
+ return;
+ }
+
+ if (syscall_no == SYSCALL_CLOSE) {
+ int fd = (int)regs->ebx;
+ regs->eax = (uint32_t)fd_close(fd);
+ return;
+ }
+
if (syscall_no == SYSCALL_EXIT) {
uart_print("[USER] exit()\n");
for(;;) {
enum {
SYSCALL_WRITE = 1,
SYSCALL_EXIT = 2,
+ SYSCALL_OPEN = 4,
+ SYSCALL_READ = 5,
+ SYSCALL_CLOSE = 6,
};
static int sys_write(int fd, const void* buf, uint32_t len) {
return ret;
}
+static int sys_open(const char* path, uint32_t flags) {
+ int ret;
+ __asm__ volatile(
+ "int $0x80"
+ : "=a"(ret)
+ : "a"(SYSCALL_OPEN), "b"(path), "c"(flags)
+ : "memory"
+ );
+ return ret;
+}
+
+static int sys_read(int fd, void* buf, uint32_t len) {
+ int ret;
+ __asm__ volatile(
+ "int $0x80"
+ : "=a"(ret)
+ : "a"(SYSCALL_READ), "b"(fd), "c"(buf), "d"(len)
+ : "memory"
+ );
+ return ret;
+}
+
+static int sys_close(int fd) {
+ int ret;
+ __asm__ volatile(
+ "int $0x80"
+ : "=a"(ret)
+ : "a"(SYSCALL_CLOSE), "b"(fd)
+ : "memory"
+ );
+ return ret;
+}
+
__attribute__((noreturn)) static void sys_exit(int code) {
(void)code;
__asm__ volatile(
static const char msg[] = "[init] hello from init.elf\n";
(void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1));
+
+ static const char path[] = "/init.elf";
+ int fd = sys_open(path, 0);
+ if (fd < 0) {
+ static const char emsg[] = "[init] open(/init.elf) failed\n";
+ (void)sys_write(1, emsg, (uint32_t)(sizeof(emsg) - 1));
+ sys_exit(1);
+ }
+
+ uint8_t hdr[4];
+ int rd = sys_read(fd, hdr, (uint32_t)sizeof(hdr));
+ (void)sys_close(fd);
+
+ if (rd == 4 && hdr[0] == 0x7F && hdr[1] == 'E' && hdr[2] == 'L' && hdr[3] == 'F') {
+ static const char ok[] = "[init] open/read/close OK (ELF magic)\n";
+ (void)sys_write(1, ok, (uint32_t)(sizeof(ok) - 1));
+ } else {
+ static const char bad[] = "[init] read failed or bad header\n";
+ (void)sys_write(1, bad, (uint32_t)(sizeof(bad) - 1));
+ }
sys_exit(0);
}