From f85145edea7e0621fd3f73b5e544f5455399df60 Mon Sep 17 00:00:00 2001 From: di Date: Sun, 2 Aug 2026 00:00:00 +0000 Subject: [PATCH 01/11] [SERVICES] added services [PACKAGE] added package manager Signed-off-by: di --- Makefile | 7 ++- kernel/kernel_processes/boot/bootprocess.c | 23 +++++-- kernel/process/syscall.c | 2 +- kernel/tools/tools.c | 12 ++-- services/Makefile | 25 ++++++++ services/ServiceMakefile | 48 +++++++++++++++ services/pacguy/main.c | 70 ++++++++++++++++++++++ shared | 2 +- 8 files changed, 178 insertions(+), 11 deletions(-) create mode 100644 services/Makefile create mode 100644 services/ServiceMakefile create mode 100644 services/pacguy/main.c diff --git a/Makefile b/Makefile index 993aa303..305a403b 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ endif .PHONY: all shared user kernel clean raspi virt run debug dump prepare-fs help install -all: kshared modules kernel shared user tools libs docs +all: kshared modules kernel shared user tools libs services docs @echo "Build complete." ./createfs @@ -33,6 +33,9 @@ kernel: kshared modules tools: shared libs prepare-fs $(MAKE) -C tools +services: shared libs prepare-fs + $(MAKE) -C services + libs: shared $(MAKE) -C libs @@ -50,6 +53,7 @@ clean: $(MAKE) -C tools $@ $(MAKE) -C modules $@ $(MAKE) -C libs $@ + $(MAKE) -C services $@ @echo "removing images" $(RM) kernel.img kernel.elf dump @@ -72,6 +76,7 @@ dump: $(ARCH)objdump -S -D kernel.elf > dump $(MAKE) -C user $@ $(MAKE) -C tools $@ + $(MAKE) -C services $@ install: $(MAKE) clean diff --git a/kernel/kernel_processes/boot/bootprocess.c b/kernel/kernel_processes/boot/bootprocess.c index bbb36c9c..228635ec 100644 --- a/kernel/kernel_processes/boot/bootprocess.c +++ b/kernel/kernel_processes/boot/bootprocess.c @@ -6,16 +6,17 @@ #include "input/input_dispatch.h" #include "usb/usb.h" #include "graph/graphics.h" -#include "exceptions/exception_handler.h" #include "kernel_processes/boot/screensaver.h" #include "kernel_processes/boot/login_screen.h" #include "kernel_processes/windows/dos.h" #include "tools/tools.h" +#include "files/helpers.h" enum { bsm_none, bsm_screensaver, bsm_login, + bsm_services, bsm_userland } boot_state; @@ -27,12 +28,25 @@ void visual_init(){ mouse_config((gpu_point){(i32)screen_size.width/2,(i32)screen_size.height/2}, screen_size); } +void load_service(const char *directory, const char *service){ + if (strlen(service) && *service == '.') return; + string full_name = string_format("%s/%s",directory,service); + process_t *proc = execute(full_name.data, 0, 0, EXEC_MODE_KEEP_FOCUS); + string_free(full_name); + if (!proc) print("[BOOT error] failed to load service %s",service); +} + void bootsm_transition(int new_state){ boot_state = new_state; switch (boot_state) { case bsm_none: break; case bsm_screensaver: current_proc = start_screensaver(); break; case bsm_login: current_proc = present_login(); break; + case bsm_services: { + traverse_directory("/boot/redos/services", false, load_service); + current_proc = 0; + break; + } case bsm_userland: { if (system_config.headless || !system_config.use_windows){ const char *argv = system_config.headless ? "headless" : ""; @@ -55,9 +69,10 @@ void bootsm_advance(){ bootsm_transition(bsm_screensaver); break; } - bootsm_transition(bsm_userland); break; - case bsm_screensaver: bootsm_transition(bsm_userland); break; - case bsm_login: bootsm_transition(system_config.headless ? bsm_userland : bsm_screensaver); break; + bootsm_transition(bsm_services); break; + case bsm_screensaver: bootsm_transition(bsm_services); break; + case bsm_login: bootsm_transition(system_config.headless ? bsm_services : bsm_screensaver); break; + case bsm_services: bootsm_transition(bsm_userland); break; case bsm_userland: bootsm_transition(bsm_none); break; } } diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index ddd5e448..849dac11 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -692,7 +692,7 @@ void sync_el0_handler_c(){ while (true); } else { kprintf("Process has crashed. ESR: %llx. ELR: %llx. FAR: %llx. SP: %llx", esr, elr, far, current_thread->sp); - if (syscall_depth <= 2) coredump(esr, elr, far, current_thread->sp); + coredump(esr, elr, far, current_thread->sp); syscall_depth--; stop_current_process(ec); } diff --git a/kernel/tools/tools.c b/kernel/tools/tools.c index 4a00bc52..20208083 100644 --- a/kernel/tools/tools.c +++ b/kernel/tools/tools.c @@ -48,10 +48,14 @@ process_t* execute(const char* prog_name, int argc, const char* argv[], uint32_t i++; } - string executable = string_format("%s/%s.elf",prog_name,proc_name); - process_t *proc = load_elf_process_path(proc_name, prog_name, executable.data, argc, argv); - release(executable.data); - if (!proc) return 0; + process_t *proc = load_elf_process_path(proc_name, prog_name, prog_name, argc, argv); + if (!proc) { + //TODO: this should only be for .red + string executable = string_format("%s/%s.elf",prog_name,proc_name); + proc = load_elf_process_path(proc_name, prog_name, executable.data, argc, argv); + release(executable.data); + if (!proc) return 0; + } if (win_id) proc->win_id = win_id; if (transfer_focus) sys_set_focus(proc->id); diff --git a/services/Makefile b/services/Makefile new file mode 100644 index 00000000..85ecd230 --- /dev/null +++ b/services/Makefile @@ -0,0 +1,25 @@ +include ../common.mk + +SUBDIRS := $(wildcard */.) +SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) +SUBDUMP = $(addsuffix .dump,$(SUBDIRS)) +MAKEFILE := $(shell pwd)/ServiceMakefile + +all: $(SUBDIRS) + +dump: $(SUBDUMP) + +$(SUBDIRS): + $(MAKE) -f $(MAKEFILE) -C $@ + +clean: $(SUBCLEAN) + +$(SUBCLEAN): %.clean: + $(MAKE) -f $(MAKEFILE) -C $* clean + +$(SUBDUMP): %.dump: + $(MAKE) -f $(MAKEFILE) -C $* dump + +clean: $(SUBCLEAN) + +.PHONY: all $(SUBDIRS) diff --git a/services/ServiceMakefile b/services/ServiceMakefile new file mode 100644 index 00000000..a55630bd --- /dev/null +++ b/services/ServiceMakefile @@ -0,0 +1,48 @@ +include ../../common.mk + +CPPFLAGS := -I. -I../../shared -I../../libs +CFLAGS := $(CFLAGS_BASE) $(CPPFLAGS) +CXXFLAGS := $(CXXFLAGS_BASE) $(CPPFLAGS) +LDFLAGS := -emain + +CLEAN_OBJS := $(shell find . -name '*.o') +CLEAN_DEPS := $(shell find . -name '*.d') +C_SRC := $(shell find . -name '*.c') +OBJ := $(C_SRC:%.c=$(BUILD_DIR)/%.o) +DEP := $(C_SRC:%.c=$(BUILD_DIR)/%.d) + +NAME := $(notdir $(CURDIR)) +ELF := $(NAME).elf +TARGET := $(NAME).bin +LOCATION := ../../fs/redos/services/ +LIBRARIES := $(wildcard ../../libs/*.a) + +.PHONY: prepare all clean + +all: prepare $(TARGET) + +prepare: + mkdir -p $(LOCATION) + mkdir -p $(BUILD_DIR) + +$(TARGET): ../../shared/libshared.a $(OBJ) + $(VLD) $(LDFLAGS) -o $(ELF) $(addprefix $(BUILD_DIR)/,$(notdir $(OBJ))) $(LIBRARIES) ../../shared/libshared.a + $(OBJCOPY) -O binary $(ELF) $@ + cp -r $(ELF) $(LOCATION)/$(NAME) + +$(BUILD_DIR)/%.o: %.S + @mkdir -p $(dir $@) + $(VAS) $(CFLAGS) -c $< -o $@ + +$(BUILD_DIR)/%.o: %.c + @mkdir -p $(dir $@) + $(VCC) $(CFLAGS) -c -MMD -MP $< -o $@ + +clean: + $(RM) $(CLEAN_OBJS) $(CLEAN_DEPS) $(TARGET) $(ELF) + $(RM) -r $(BUILD_DIR) + +dump: all + $(ARCH)objdump -S $(ELF) > dump + +-include $(DEP) diff --git a/services/pacguy/main.c b/services/pacguy/main.c new file mode 100644 index 00000000..b6efb6b8 --- /dev/null +++ b/services/pacguy/main.c @@ -0,0 +1,70 @@ +#include "syscalls/syscalls.h" +#include "files/system_module.h" +#include "files/vfs.h" +#include "files/helpers.h" + +bool loaded = false; + +uint16_t find_extension(char *path){ + uint16_t count = 0; + while (*path && *path != '.'){ path++; count++; } + return path ? count : 0; +} + +void handle_entry(const char *directory, const char *file) { + if (!strcmp_case("launcher.red",file,true)) return; + if (strlen(file) && *file == '.') return; + string fullpath = string_format("%s/%s",directory, file); + uint16_t ext_loc = find_extension((char*)file); + string_slice name = make_string_slice(fullpath.data, fullpath.length - strlen(file), ext_loc); + uint16_t extra = ext_loc ? 1 : 0; + string_slice ext = make_string_slice(name.data + ext_loc + 1, 0, strlen(file)-ext_loc-extra); + if (slice_lit_match(ext,"red",true)){ + print("Found file %s/%s",directory,file); + make_complex_entry(file, backing_virtual, entry_directory, DATA_SIG_REDPKG, (file_actions){}, fullpath); + } else string_free(fullpath); +} + +void refresh_apps(){ + if (!entries) entries = stack_create(sizeof(module_file),32); + size_t count = stack_count(entries); + for (size_t i = 0; i < count; i++){ + string_free(STACK_GET(module_file, entries, i).name); + string_free(STACK_GET(module_file, entries, i).alias_info.alias_path); + } + stack_reset(entries); + traverse_directory("/home/applications", false, handle_entry); + traverse_directory("/boot/redos/system", false, handle_entry); + loaded = true; +} + +size_t custom_readdir(const char *path, void *buf, size_t size, file_offset *offset){ + refresh_apps(); + return vfs_readdir(path, buf, size, offset); +} + +bool custom_stat(const char *path, fs_stat *out_stat){ + return vfs_stat(path, out_stat); +} + +system_module apps_mod = { + .name = "apps folder", + .mount = "apps", + //TODO: can init be brought back now? + .version = VERSION_NUM(0, 1, 0, 0), + .open = vfs_open, + .read = vfs_read, + .write = vfs_write, + .getstat = vfs_stat, + .readdir = vfs_readdir, +}; + +int main(int argc, char* argv[]){ + print("Ello world mate"); + refresh_apps(); + load_fsmodule(&apps_mod, true); + + while (true){} + + return 0; +} \ No newline at end of file diff --git a/shared b/shared index 7449400a..76cb1495 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 7449400aae7e5d49d45497fa87f2ac46a3c2e44b +Subproject commit 76cb149514dd70ff2fab832e0675c1a99192b092 From 707d92765f7d5ec6c76c7a275462bcd53b96a3bc Mon Sep 17 00:00:00 2001 From: di Date: Sun, 2 Aug 2026 00:00:00 +0000 Subject: [PATCH 02/11] [JOB] always interrupt kernel Signed-off-by: di --- kernel/process/jobs/job_manager.c | 65 ++++++++++++++----------------- kernel/process/jobs/job_save.S | 5 +-- kernel/process/syscall.c | 1 + 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/kernel/process/jobs/job_manager.c b/kernel/process/jobs/job_manager.c index 7878d6e8..21e1c8a8 100644 --- a/kernel/process/jobs/job_manager.c +++ b/kernel/process/jobs/job_manager.c @@ -111,13 +111,11 @@ u64 create_new_job(job_application_t application, system_module *mod, thread_t * new_t->job_id = job->id; job->worker = new_t; requester->state = BLOCKED; - if (syscall_depth >= 1){ - print("[JOB debug] kstack has been saved to %llx - %x",job_kstack.ptr,job_kstack.size); - memcpy(&job->kernel_ctx, kthread, sizeof(thread_t)); - job->kernel_ctx.job_id = job->id; - job->kernel_ctx.pc = job_save_ret(); - job->kstack = job_kstack; - } else memset(&job->kernel_ctx, 0, sizeof(thread_t)); + print("[JOB debug] kstack has been saved to %llx - %x",job_kstack.ptr,job_kstack.size); + memcpy(&job->kernel_ctx, kthread, sizeof(thread_t)); + job->kernel_ctx.job_id = job->id; + job->kernel_ctx.pc = job_save_ret(); + job->kstack = job_kstack; schedule_thread(fs_owner, new_t); switch_proc(YIELD); return 0; @@ -177,35 +175,30 @@ void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ } } } - print("[JOB] %i fulfilled by %i",job_id,thread->tid); - if (st->kernel_ctx.job_id){ - st->kernel_ctx.PROC_X0 = ret; - job_kpec = (uptr)&st->kernel_ctx; - cpec = (uptr)st->requester; - - if (st->kstack.ptr){ - st->kernel_ctx.sp = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.sp); - print("[JOB debug] Initial Address %llx",st->kernel_ctx.regs[29]); - st->kernel_ctx.regs[29] = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.regs[29]); - - uptr addr = st->kernel_ctx.regs[29]; - uptr fp = 0; - do { - print("[JOB debug] Address %llx",addr); - fp = *(uptr*)addr; - print("[JOB debug] Link %llx",fp); - fp = translate_stack(st->kstack.ptr+0x10000, fp); - print("[JOB debug] In new stack %llx",fp); - *(uptr*)addr = fp; - addr = fp; - } while(addr && (addr & 0xfffff00000000000) == 0xffffc00000000000); - } - st->requester->state = RUNNING; - prepare_process_restore(proc); + print("[JOB] %i fulfilled by %i with return value %llx",job_id,thread->tid); + st->kernel_ctx.PROC_X0 = ret; + job_kpec = (uptr)&st->kernel_ctx; + cpec = (uptr)st->requester; + + if (st->kstack.ptr){ + st->kernel_ctx.sp = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.sp); + print("[JOB debug] Initial Address %llx",st->kernel_ctx.regs[29]); + st->kernel_ctx.regs[29] = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.regs[29]); + + uptr addr = st->kernel_ctx.regs[29]; + uptr fp = 0; + do { + print("[JOB debug] Address %llx",addr); + fp = *(uptr*)addr; + print("[JOB debug] Link %llx",fp); + fp = translate_stack(st->kstack.ptr+0x10000, fp); + print("[JOB debug] In new stack %llx",fp); + *(uptr*)addr = fp; + addr = fp; + } while(addr && (addr & 0xfffff00000000000) == 0xffffc00000000000); job_ksp = st->kstack.ptr+0x10000; - job_restore_kernel(); - } else { - ready_thread(st->requester); - st->requester->PROC_X0 = ret; } + st->requester->state = RUNNING; + prepare_process_restore(proc); + job_restore_kernel(); } \ No newline at end of file diff --git a/kernel/process/jobs/job_save.S b/kernel/process/jobs/job_save.S index 2cbfbb58..80a984b1 100644 --- a/kernel/process/jobs/job_save.S +++ b/kernel/process/jobs/job_save.S @@ -1,6 +1,5 @@ .global job_save_kernel job_save_kernel: - msr daifset, #2 stp x17, x18, [sp, #-16]! add x17, sp, #16 @@ -59,7 +58,7 @@ adrp x1, ksp add x1, x1, :lo12:ksp cmp x0, x1 -b.ne 2f +b.ne 1f mov x1, sp sub x21, x0, x1 @@ -77,7 +76,7 @@ mov x1, sp mov x2, x21 bl memcpy -2: +1: ldp x0, x1, [sp, #0] ldp x21,x30, [sp, #16] diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index 87739089..ff53b2d6 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -707,6 +707,7 @@ void sync_el0_handler_c(){ //TODO: schedule kstack_top to cleanup, but don't do immediately as we're in it current_thread->kstack_top = 0; } + job_ksp = (uptr)ksp; process_restore(); } From bd268c270a9f8d8af61fa2a4749caf123154e6c4 Mon Sep 17 00:00:00 2001 From: di Date: Thu, 6 Aug 2026 00:00:00 +0000 Subject: [PATCH 03/11] [JOB] proper reuse of kstack Signed-off-by: di --- kernel/filesystem/filesystem.c | 1 + kernel/process/jobs/job_manager.c | 17 +++++++---------- kernel/process/jobs/job_manager.h | 4 +--- kernel/process/loading/elf_file.c | 4 +++- services/pacguy/main.c | 12 ++++++++++++ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/kernel/filesystem/filesystem.c b/kernel/filesystem/filesystem.c index e15488b1..32ae8fda 100644 --- a/kernel/filesystem/filesystem.c +++ b/kernel/filesystem/filesystem.c @@ -60,6 +60,7 @@ FS_RESULT open_file_global(module_root *root, const char* path, file* descriptor job_serialize_str(&app, 0, search_path); job_serialize_fd(&app, 1, descriptor, copy_on_end); }); + *out_mod = mod; return j_ret; } else { result = mod->open(search_path, descriptor); diff --git a/kernel/process/jobs/job_manager.c b/kernel/process/jobs/job_manager.c index 21e1c8a8..cfdfd3e4 100644 --- a/kernel/process/jobs/job_manager.c +++ b/kernel/process/jobs/job_manager.c @@ -99,7 +99,8 @@ u64 create_new_job(job_application_t application, system_module *mod, thread_t * job->type = application.type; job->mod = mod; thread_t *requester = (thread_t*)get_thread_from_proc(requesting_proc, application.requesting_tid); - if (job_ksp != (uptr)ksp) requester->kstack_top = job_ksp; + if (job_kstack.ptr) + requester->kstack_top = job_kstack.ptr+job_kstack.size; job->requester = requester; process_t *fs_owner = get_proc_by_pid(application.worker_pid); thread_t *new_t = alloc_thread(); @@ -162,17 +163,13 @@ void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ for (size_t i = 0; i < st->buffer_count; i++){ job_buffer buf = st->buffers[i]; if (buf.sync & copy_on_end && buf.worker_ptr.ptr){ - print("[JOB debug] Copy buffer %x into %x",buf.worker_ptr.ptr,buf.orig_ptr.ptr); + print("[JOB debug] Copy buffer %x into %llx",buf.worker_ptr.ptr,buf.orig_ptr.ptr); void* addr = quick_translate(st->requester, proc, buf.orig_ptr.ptr); - if (!addr) continue; - memcpy(addr, (void*)buf.worker_ptr.ptr, buf.worker_ptr.size); - file *fd = addr; - if (buf.fd){ - print("[JOB DEBUG] fd %i size %i signature %s",fd->id,fd->size,&fd->data_type); - if (st->type == job_open){ - instance_local_fd(st->mod, addr); - } + if (!addr){ + if (buf.orig_ptr.ptr & HIGH_VA) addr = (void*)buf.orig_ptr.ptr;//TODO: extra safety checks? + else continue; } + memcpy(addr, (void*)buf.worker_ptr.ptr, buf.worker_ptr.size); } } print("[JOB] %i fulfilled by %i with return value %llx",job_id,thread->tid); diff --git a/kernel/process/jobs/job_manager.h b/kernel/process/jobs/job_manager.h index f8842116..68c5a5a1 100644 --- a/kernel/process/jobs/job_manager.h +++ b/kernel/process/jobs/job_manager.h @@ -14,11 +14,9 @@ extern void save_kstack(); thread_t kthread = {};\ job_kstack = (sizedptr){};\ job_kpec = (uptr)&kthread;\ - if (!job_ksp) job_ksp = (uptr)ksp;\ + job_ksp = get_current_thread()->kstack_top ?: (uptr)ksp;\ job_save_kernel();\ - print("KStack save to %llx",job_ksp);\ save_kstack();\ - print("KStack saved to %llx of size %llx from %llx",job_kstack.ptr,job_kstack.size,ksp);\ process_t *owner_proc = get_proc_by_pid(mod->owner);\ job_application_t app = (job_application_t){\ .requesting_pid = get_current_proc()->id,\ diff --git a/kernel/process/loading/elf_file.c b/kernel/process/loading/elf_file.c index ad6e90b9..4acc856a 100644 --- a/kernel/process/loading/elf_file.c +++ b/kernel/process/loading/elf_file.c @@ -206,8 +206,10 @@ process_t* load_elf_process_path(const char *name, const char *bundle, const cha close_file(&fd); return 0; } + + size_t amt = read_file(&fd, program, fd.size); + bool ok = amt == fd.size; - bool ok = read_file(&fd, program, fd.size) == fd.size; close_file(&fd); if (!ok) { release(program); diff --git a/services/pacguy/main.c b/services/pacguy/main.c index b6efb6b8..3722a524 100644 --- a/services/pacguy/main.c +++ b/services/pacguy/main.c @@ -47,6 +47,18 @@ bool custom_stat(const char *path, fs_stat *out_stat){ return vfs_stat(path, out_stat); } +FS_RESULT custom_open(const char *path, file *fd){ + FS_RESULT res = vfs_open(path, fd); + print("Opened fd inside module with %i",fd->id); + return res; +} + +size_t custom_read(file *fd, char *buf, size_t size, file_offset off){ + size_t res = vfs_read(fd, buf, size, off); + print("Result on fid %i size %i",fd->id,size); + return res; +} + system_module apps_mod = { .name = "apps folder", .mount = "apps", From aa3e1eec7349e46c227847084aec128b06412227 Mon Sep 17 00:00:00 2001 From: di Date: Fri, 7 Aug 2026 00:00:00 +0000 Subject: [PATCH 04/11] [PACKAGEMAN] tools dir [TOOLS] ktools rename and listing [JOBS] added TODO since values within the stack might themselves need translation Signed-off-by: di --- kernel/filesystem/filesystem.c | 1 + kernel/process/jobs/job_manager.c | 6 +-- kernel/process/jobs/job_manager.h | 6 +++ kernel/tools/tools.c | 38 +++++++++++----- services/pacguy/apps.c | 39 ++++++++++++++++ services/pacguy/main.c | 75 +++---------------------------- services/pacguy/tools.c | 35 +++++++++++++++ shared | 2 +- 8 files changed, 118 insertions(+), 84 deletions(-) create mode 100644 services/pacguy/apps.c create mode 100644 services/pacguy/tools.c diff --git a/kernel/filesystem/filesystem.c b/kernel/filesystem/filesystem.c index 32ae8fda..5cf0b358 100644 --- a/kernel/filesystem/filesystem.c +++ b/kernel/filesystem/filesystem.c @@ -57,6 +57,7 @@ FS_RESULT open_file_global(module_root *root, const char* path, file* descriptor FS_RESULT result = FS_RESULT_DRIVER_ERROR; if (mod->owner != get_kernel_proc()->id){ job_make(job_open, mod, { + //TODO: here, out_mod is in the stack, and we're referencing it through a pointer, which we of course lose as we move the stack the first time. job_serialize_str(&app, 0, search_path); job_serialize_fd(&app, 1, descriptor, copy_on_end); }); diff --git a/kernel/process/jobs/job_manager.c b/kernel/process/jobs/job_manager.c index cfdfd3e4..0ce6f28a 100644 --- a/kernel/process/jobs/job_manager.c +++ b/kernel/process/jobs/job_manager.c @@ -145,10 +145,6 @@ void* quick_translate(thread_t *thread, process_t *proc, uptr ptr){ extern uptr cpec; -static inline uptr translate_stack(uptr new_top, uptr ptr){ - return new_top-((uptr)ksp-ptr); -} - void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ job_state_t *st = get_job_state(job_id); if (!st) { @@ -163,7 +159,7 @@ void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ for (size_t i = 0; i < st->buffer_count; i++){ job_buffer buf = st->buffers[i]; if (buf.sync & copy_on_end && buf.worker_ptr.ptr){ - print("[JOB debug] Copy buffer %x into %llx",buf.worker_ptr.ptr,buf.orig_ptr.ptr); + print("[JOB debug] Copy buffer %llx into %llx",buf.worker_ptr.ptr,buf.orig_ptr.ptr); void* addr = quick_translate(st->requester, proc, buf.orig_ptr.ptr); if (!addr){ if (buf.orig_ptr.ptr & HIGH_VA) addr = (void*)buf.orig_ptr.ptr;//TODO: extra safety checks? diff --git a/kernel/process/jobs/job_manager.h b/kernel/process/jobs/job_manager.h index 68c5a5a1..363112ae 100644 --- a/kernel/process/jobs/job_manager.h +++ b/kernel/process/jobs/job_manager.h @@ -92,3 +92,9 @@ static inline void job_serialize_off(job_application_t *application, int arg_num u64 create_new_job(job_application_t application, system_module *mod, thread_t *kthread); void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread); + +extern char ksp[]; + +static inline uptr translate_stack(uptr new_top, uptr ptr){ + return new_top-((uptr)ksp-ptr); +} \ No newline at end of file diff --git a/kernel/tools/tools.c b/kernel/tools/tools.c index 20208083..cfedccc5 100644 --- a/kernel/tools/tools.c +++ b/kernel/tools/tools.c @@ -88,27 +88,45 @@ process_t* execute(const char* prog_name, int argc, const char* argv[], uint32_t return 0; } -FS_RESULT open_tools(){ - return FS_RESULT_DRIVER_ERROR; -} - -size_t read_tools(){ - return 0; +size_t ktools_list(const char *path, void *buf, size_t size, file_offset *offset){ + file_offset off = offset ? *offset : 0; + fs_dir_list_helper helper = create_dir_list_helper(buf, size); + for (u64 i = off; i < N_ARR(available_cmds); i++){ + if (!dir_list_fill(&helper, available_cmds[i].name)){ + if (offset) *offset = i; + return dir_buf_size(&helper); + } + } + return dir_buf_size(&helper); } -size_t list_tools(const char *path, void *buf, size_t size, file_offset offset){ - return 0; +bool ktools_stat(const char *path, fs_stat *out_stat){ + if (strlen(path) && *path == '/') path++; + if (!strlen(path)){ + stat_dir(out_stat); + return true; + } + for (u64 i = 0; i < N_ARR(available_cmds); i++){ + if (strncmp(available_cmds[i].name, path, strlen(available_cmds[i].name)) == 0){ + out_stat->size = 0; + out_stat->data_type = DATA_SIGNATURE("KPROC"); + out_stat->type = entry_file; + return true; + } + } + return true; } //TODO: finish listing tool module system_module tool_module = (system_module){ .name = "tools", - .mount = "tools", + .mount = "ktools", .version = VERSION_NUM(0, 1, 0, 1), .init = init_tools, .fini = 0, .open = 0, .read = 0, .write = 0, - .readdir = 0, + .getstat = ktools_stat, + .readdir = ktools_list, }; diff --git a/services/pacguy/apps.c b/services/pacguy/apps.c new file mode 100644 index 00000000..d29071e1 --- /dev/null +++ b/services/pacguy/apps.c @@ -0,0 +1,39 @@ +#include "files/vfs.h" +#include "files/helpers.h" + +void handle_entry(const char *directory, const char *file) { + if (strlen(file) && *file == '.') return; + string fullpath = string_format("%s/%s",directory, file); + uint16_t ext_loc = find_find_extension_index((char*)file); + string_slice name = make_string_slice(fullpath.data, fullpath.length - strlen(file), ext_loc); + uint16_t extra = ext_loc ? 1 : 0; + string_slice ext = make_string_slice(name.data + ext_loc + 1, 0, strlen(file)-ext_loc-extra); + if (slice_lit_match(ext,"red",true)){ + print("Found file %s/%s",directory,file); + make_complex_entry(file, backing_virtual, entry_directory, DATA_SIG_REDPKG, (file_actions){}, fullpath); + } else string_free(fullpath); +} + +void refresh_apps(){ + if (!entries) entries = stack_create(sizeof(module_file),32); + size_t count = stack_count(entries); + for (size_t i = 0; i < count; i++){ + string_free(STACK_GET(module_file, entries, i).name); + string_free(STACK_GET(module_file, entries, i).alias_info.alias_path); + } + stack_reset(entries); + traverse_directory("/home/applications", false, handle_entry); + traverse_directory("/boot/redos/system", false, handle_entry); +} + +system_module apps_mod = { + .name = "apps folder", + .mount = "apps", + //TODO: can init be brought back now? + .version = VERSION_NUM(0, 1, 0, 0), + .open = vfs_open, + .read = vfs_read, + .write = vfs_write, + .getstat = vfs_stat, + .readdir = vfs_readdir, +}; \ No newline at end of file diff --git a/services/pacguy/main.c b/services/pacguy/main.c index 3722a524..47dfd02d 100644 --- a/services/pacguy/main.c +++ b/services/pacguy/main.c @@ -1,81 +1,20 @@ #include "syscalls/syscalls.h" #include "files/system_module.h" -#include "files/vfs.h" #include "files/helpers.h" -bool loaded = false; +extern void refresh_apps(); +extern system_module apps_mod; -uint16_t find_extension(char *path){ - uint16_t count = 0; - while (*path && *path != '.'){ path++; count++; } - return path ? count : 0; -} - -void handle_entry(const char *directory, const char *file) { - if (!strcmp_case("launcher.red",file,true)) return; - if (strlen(file) && *file == '.') return; - string fullpath = string_format("%s/%s",directory, file); - uint16_t ext_loc = find_extension((char*)file); - string_slice name = make_string_slice(fullpath.data, fullpath.length - strlen(file), ext_loc); - uint16_t extra = ext_loc ? 1 : 0; - string_slice ext = make_string_slice(name.data + ext_loc + 1, 0, strlen(file)-ext_loc-extra); - if (slice_lit_match(ext,"red",true)){ - print("Found file %s/%s",directory,file); - make_complex_entry(file, backing_virtual, entry_directory, DATA_SIG_REDPKG, (file_actions){}, fullpath); - } else string_free(fullpath); -} - -void refresh_apps(){ - if (!entries) entries = stack_create(sizeof(module_file),32); - size_t count = stack_count(entries); - for (size_t i = 0; i < count; i++){ - string_free(STACK_GET(module_file, entries, i).name); - string_free(STACK_GET(module_file, entries, i).alias_info.alias_path); - } - stack_reset(entries); - traverse_directory("/home/applications", false, handle_entry); - traverse_directory("/boot/redos/system", false, handle_entry); - loaded = true; -} - -size_t custom_readdir(const char *path, void *buf, size_t size, file_offset *offset){ - refresh_apps(); - return vfs_readdir(path, buf, size, offset); -} - -bool custom_stat(const char *path, fs_stat *out_stat){ - return vfs_stat(path, out_stat); -} - -FS_RESULT custom_open(const char *path, file *fd){ - FS_RESULT res = vfs_open(path, fd); - print("Opened fd inside module with %i",fd->id); - return res; -} - -size_t custom_read(file *fd, char *buf, size_t size, file_offset off){ - size_t res = vfs_read(fd, buf, size, off); - print("Result on fid %i size %i",fd->id,size); - return res; -} - -system_module apps_mod = { - .name = "apps folder", - .mount = "apps", - //TODO: can init be brought back now? - .version = VERSION_NUM(0, 1, 0, 0), - .open = vfs_open, - .read = vfs_read, - .write = vfs_write, - .getstat = vfs_stat, - .readdir = vfs_readdir, -}; +extern void refresh_tools(); +extern system_module tools_mod; int main(int argc, char* argv[]){ - print("Ello world mate"); refresh_apps(); load_fsmodule(&apps_mod, true); + refresh_tools(); + load_fsmodule(&tools_mod, true); + while (true){} return 0; diff --git a/services/pacguy/tools.c b/services/pacguy/tools.c new file mode 100644 index 00000000..c803c2be --- /dev/null +++ b/services/pacguy/tools.c @@ -0,0 +1,35 @@ +#include "files/system_module.h" +#include "files/vfs.h" +#include "files/helpers.h" + +void tools_handle_entry(const char *directory, const char *file) { + print("Found tool %s",file); + if (strlen(file) && *file == '.') return; + string fullpath = string_format("%s/%s",directory, file); + make_complex_entry(file, backing_virtual, entry_file, DATA_SIG_REDPKG, (file_actions){}, fullpath); +} + +void refresh_tools(){ + if (!entries) entries = stack_create(sizeof(module_file),32); + size_t count = stack_count(entries); + for (size_t i = 0; i < count; i++){ + string_free(STACK_GET(module_file, entries, i).name); + string_free(STACK_GET(module_file, entries, i).alias_info.alias_path); + } + stack_reset(entries); + traverse_directory("/home/tools", false, tools_handle_entry); + traverse_directory("/boot/redos/tools", false, tools_handle_entry); + traverse_directory("/ktools", false, tools_handle_entry); +} + +system_module tools_mod = { + .name = "tools folder", + .mount = "tools", + //TODO: can init be brought back now? + .version = VERSION_NUM(0, 1, 0, 0), + .open = vfs_trace_open, + .read = vfs_trace_read, + .write = vfs_trace_write, + .getstat = vfs_trace_stat, + .readdir = vfs_trace_readdir, +}; \ No newline at end of file diff --git a/shared b/shared index 1442cef4..5444877f 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 1442cef44fcf72143332558c5f86be9f7d9f6ca6 +Subproject commit 5444877f6eac64d1ba799b8f19eebcf110189f96 From 543dd0d0e35ac73e84198c266b61e5d7673d9fd2 Mon Sep 17 00:00:00 2001 From: di Date: Sat, 8 Aug 2026 00:00:00 +0000 Subject: [PATCH 05/11] [FAT32] stat fix Signed-off-by: di --- kernel/filesystem/fat32.cpp | 4 ++-- kernel/process/jobs/job_manager.c | 1 + shared | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/filesystem/fat32.cpp b/kernel/filesystem/fat32.cpp index 3ce9a314..b3338300 100644 --- a/kernel/filesystem/fat32.cpp +++ b/kernel/filesystem/fat32.cpp @@ -402,7 +402,7 @@ u32 FAT32FS::alloc_fat(){ f32_walk_result FAT32FS::read_entry_handler(FAT32FS *instance, f32file_entry *entry, char *filename, const char *seek) { if (entry->flags.volume_id) return {}; - + size_t name_len = strlen_max(filename, 0); int matched = strstart_case(seek, filename, true); if (matched != (int)name_len) return {}; @@ -417,7 +417,7 @@ f32_walk_result FAT32FS::read_entry_handler(FAT32FS *instance, f32file_entry *en uint32_t bpc = bps * spc; uint32_t count = entry->filesize > 0 ? ((entry->filesize + bpc - 1) / bpc) : instance->count_FAT(filecluster); - if (entry->flags.directory) return instance->walk_directory(count, filecluster, next, read_entry_handler); + if (entry->flags.directory && *next) return instance->walk_directory(count, filecluster, next, read_entry_handler); if (*next != '\0') return {}; return {.entry = *entry, .cluster = 0, .offset = 0, .found = true}; } diff --git a/kernel/process/jobs/job_manager.c b/kernel/process/jobs/job_manager.c index 0ce6f28a..755493a4 100644 --- a/kernel/process/jobs/job_manager.c +++ b/kernel/process/jobs/job_manager.c @@ -173,6 +173,7 @@ void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ job_kpec = (uptr)&st->kernel_ctx; cpec = (uptr)st->requester; + //TODO: this entire thing is flimsy, we're only translating stack returns so we can make our way back to the userland proc, but any &values stored in the stack are not translated and risk corruption + failure if (st->kstack.ptr){ st->kernel_ctx.sp = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.sp); print("[JOB debug] Initial Address %llx",st->kernel_ctx.regs[29]); diff --git a/shared b/shared index 5444877f..e407b15d 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 5444877f6eac64d1ba799b8f19eebcf110189f96 +Subproject commit e407b15d4bb3dfa86837bec7e9457a1029607d60 From 605df03b7fbb61d852ef88c9b56ef33aa628ede6 Mon Sep 17 00:00:00 2001 From: di Date: Sat, 8 Aug 2026 00:00:00 +0000 Subject: [PATCH 06/11] [APP_BUNDLE] added package identifiers (not yet parsed) Signed-off-by: di --- shared | 2 +- user/UserMakefile | 1 + user/demo/package.info | 8 ++++---- user/filebrowser/package.info | 3 +++ user/launcher/package.info | 3 +++ user/terminal/package.info | 3 +++ user/theme/package.info | 3 +++ 7 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 user/filebrowser/package.info create mode 100644 user/launcher/package.info create mode 100644 user/terminal/package.info create mode 100644 user/theme/package.info diff --git a/shared b/shared index e407b15d..9ca10745 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit e407b15d4bb3dfa86837bec7e9457a1029607d60 +Subproject commit 9ca10745fe148e79c545413b043c17bd73d8996d diff --git a/user/UserMakefile b/user/UserMakefile index da135fa9..921f4c48 100644 --- a/user/UserMakefile +++ b/user/UserMakefile @@ -27,6 +27,7 @@ prepare: mkdir -p $(BUILD_DIR) mkdir -p $(PACKAGE) cp -r resources $(PACKAGE) + cp package.info $(PACKAGE)/package.info 2>/dev/null || : $(PACKAGE)/$(TARGET): ../../shared/libshared.a $(OBJ) $(VLD) $(LDFLAGS) -o $(PACKAGE)/$(ELF) $(addprefix $(BUILD_DIR)/,$(notdir $(OBJ))) ../../shared/libshared.a diff --git a/user/demo/package.info b/user/demo/package.info index 09b2ff74..cbe80f6f 100644 --- a/user/demo/package.info +++ b/user/demo/package.info @@ -1,10 +1,10 @@ # Name app_name = "Demo" -app_author="[REDACTED]" # Comments are allowed -unknown values="will be ignored" +unknown_values="will be ignored" -// C-style comments are allowed too + indentation="is ok" +app_author="[REDACTED]" - "indentation"=and no quotes \ No newline at end of file +app_bundle_id="com.redos.demo" \ No newline at end of file diff --git a/user/filebrowser/package.info b/user/filebrowser/package.info new file mode 100644 index 00000000..62c72342 --- /dev/null +++ b/user/filebrowser/package.info @@ -0,0 +1,3 @@ +app_name="File browser" +app_author="[REDACTED]" +app_bundle_id="com.redos.filebrowser" \ No newline at end of file diff --git a/user/launcher/package.info b/user/launcher/package.info new file mode 100644 index 00000000..ce7b7cd0 --- /dev/null +++ b/user/launcher/package.info @@ -0,0 +1,3 @@ +app_name="App launcher" +app_author="[REDACTED]" +app_bundle_id="com.redos.launcher" \ No newline at end of file diff --git a/user/terminal/package.info b/user/terminal/package.info new file mode 100644 index 00000000..05091c24 --- /dev/null +++ b/user/terminal/package.info @@ -0,0 +1,3 @@ +app_name="Terminal" +app_author="[REDACTED]" +app_bundle_id="com.redos.legacy.terminal" \ No newline at end of file diff --git a/user/theme/package.info b/user/theme/package.info new file mode 100644 index 00000000..8a1c0613 --- /dev/null +++ b/user/theme/package.info @@ -0,0 +1,3 @@ +app_name="Theme selector" +app_author="[REDACTED]" +app_bundle_id="com.redos.theme" \ No newline at end of file From 3de0af4cf3096fefe73dbd046a86c28a0a12a660 Mon Sep 17 00:00:00 2001 From: di Date: Sat, 8 Aug 2026 00:00:00 +0000 Subject: [PATCH 07/11] [FS] added transform operations [BUNDLE] added package ids [TOOLS] added launch tool with pkg id [PACKAGEMAN] added resolve Signed-off-by: di --- kernel/filesystem/fat32.cpp | 1 + kernel/filesystem/filesystem.c | 22 +++++++++++++++++++ kernel/filesystem/filesystem.h | 1 + kernel/filesystem/virtio_9p_pci.cpp | 1 + kernel/networking/network.cpp | 1 + kernel/process/jobs/job_manager.c | 1 + kernel/process/kernel_syscall_impl.c | 8 ++++++- kernel/process/syscall.c | 17 ++++++++++++++ modules/audio/virt/audio.cpp | 1 + modules/disk/raspi/disk.cpp | 1 + modules/graph/raspi/graphics.cpp | 1 + modules/graph/virt/graphics.cpp | 1 + modules/usb/common/usb_common.cpp | 1 + services/pacguy/apps.c | 31 ++++++++++++++++++++++++++ shared | 2 +- tools/launch/launch.c | 33 ++++++++++++++++++++++++++++ user/launcher/main.c | 2 +- user/launcher/package_info.c | 18 --------------- user/launcher/package_info.h | 19 ---------------- 19 files changed, 122 insertions(+), 40 deletions(-) create mode 100644 tools/launch/launch.c delete mode 100644 user/launcher/package_info.c delete mode 100644 user/launcher/package_info.h diff --git a/kernel/filesystem/fat32.cpp b/kernel/filesystem/fat32.cpp index b3338300..519fd631 100644 --- a/kernel/filesystem/fat32.cpp +++ b/kernel/filesystem/fat32.cpp @@ -703,6 +703,7 @@ system_module boot_fs_module = (system_module){ .truncate = boot_truncate, .getstat = boot_stat, .readdir = boot_partition_readdir, + .transform = 0, .alias_info = {} }; diff --git a/kernel/filesystem/filesystem.c b/kernel/filesystem/filesystem.c index 5cf0b358..a70d849c 100644 --- a/kernel/filesystem/filesystem.c +++ b/kernel/filesystem/filesystem.c @@ -143,6 +143,28 @@ size_t read_file(file *descriptor, char* buf, size_t size){ return amount_read; } +size_t transform_file(module_root *root, const char* path, void* buf, size_t size){ + const char *search_path = path; + if (*search_path == '/') search_path++; + if (!*search_path) return FS_RESULT_NOTFOUND; + system_module *mod = get_module_from(root, &search_path); + if (!mod) return FS_RESULT_NOTFOUND; + if (!mod->transform) return FS_RESULT_NOTFOUND; + FS_RESULT result = FS_RESULT_DRIVER_ERROR; + if (mod->owner != get_kernel_proc()->id){ + job_make(job_transform, mod, { + job_serialize_str(&app, 0, search_path); + job_serialize_buf(&app, 1, true, (void*)buf, size, copy_on_start | copy_on_end); + }); + return j_ret; + } else { + result = mod->transform(search_path, buf, size); + } + if (result != FS_RESULT_SUCCESS) return result; + if (!open_files) return FS_RESULT_DRIVER_ERROR; + return FS_RESULT_SUCCESS; +} + void close_file(file *descriptor){ if (!open_files || !descriptor) return; open_file_descriptors *ofile = 0; diff --git a/kernel/filesystem/filesystem.h b/kernel/filesystem/filesystem.h index 54c2d786..2115d939 100644 --- a/kernel/filesystem/filesystem.h +++ b/kernel/filesystem/filesystem.h @@ -13,6 +13,7 @@ FS_RESULT open_file_global(module_root *root, const char* path, file* descriptor FS_RESULT open_file(module_root *root, const char* path, file* descriptor); FS_RESULT instance_local_fd(system_module *mod, file *descriptor); size_t read_file(file *descriptor, char* buf, size_t size); +size_t transform_file(module_root *root, const char* path, void* buf, size_t size); size_t write_file(file *descriptor, const char* buf, size_t size); void close_file_global(file *descriptor, system_module *mod); void close_file(file *descriptor); diff --git a/kernel/filesystem/virtio_9p_pci.cpp b/kernel/filesystem/virtio_9p_pci.cpp index f13b5718..2d10a8cb 100644 --- a/kernel/filesystem/virtio_9p_pci.cpp +++ b/kernel/filesystem/virtio_9p_pci.cpp @@ -606,6 +606,7 @@ system_module p9_fs_module = (system_module){ .truncate = shared_truncate, .getstat = shared_stat, .readdir = shared_readdir, + .transform = 0, .alias_info = {} }; diff --git a/kernel/networking/network.cpp b/kernel/networking/network.cpp index c1b7e87e..c4ff365a 100644 --- a/kernel/networking/network.cpp +++ b/kernel/networking/network.cpp @@ -100,5 +100,6 @@ system_module net_module = (system_module){ .truncate = 0, .getstat = 0, .readdir = 0, + .transform = 0, .alias_info = {} }; \ No newline at end of file diff --git a/kernel/process/jobs/job_manager.c b/kernel/process/jobs/job_manager.c index 755493a4..305b282c 100644 --- a/kernel/process/jobs/job_manager.c +++ b/kernel/process/jobs/job_manager.c @@ -55,6 +55,7 @@ bool prepare_thread(job_state_t *job, system_module *mod, job_application_t appl case job_read: entry = (uptr)mod->read; break; case job_write: entry = (uptr)mod->write; break; case job_trunc: entry = (uptr)mod->truncate; break; + case job_transform: entry = (uptr)mod->transform; break; default: return false; } if (!entry) return false; diff --git a/kernel/process/kernel_syscall_impl.c b/kernel/process/kernel_syscall_impl.c index f9c35be9..f20fac4c 100644 --- a/kernel/process/kernel_syscall_impl.c +++ b/kernel/process/kernel_syscall_impl.c @@ -80,7 +80,6 @@ void resize_draw_ctx(draw_ctx* d_ctx, uint32_t width, uint32_t height){ gpu_flush(); } - uint32_t gpu_char_size(uint32_t scale){ return gpu_get_char_size(scale); } @@ -135,6 +134,13 @@ size_t readf(file *descriptor, char* buf, size_t size){ return read_file(descriptor, buf, size); } +size_t transformf(const char *path, void* buf, size_t size){ + module_root rootfs = {}; + string s = resolve_isolated_path(path, get_current_proc()->permissions.fs_id, &rootfs, true); + if (!s.data || !s.length) return transform_file(kernel_fs(), path, buf, size); + return transform_file(&rootfs, path, buf, size); +} + size_t writef(file *descriptor, const char* buf, size_t size){ return write_file(descriptor, buf, size); } diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index ff53b2d6..5b8c2d1b 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -379,6 +379,22 @@ u64 syscall_writef(process_t *ctx, thread_t *current_thread){ return write_file(descriptor, buf, size); } +u64 syscall_transf(process_t *ctx, thread_t *current_thread){ + SYSCALL_STR(path, PROC_X0, false); + size_t size = (size_t)current_thread->PROC_X2; + SYSCALL_ARG_SIZE(void, buf, size, PROC_X1, true); +#ifdef ISOLATEDFS + module_root rootfs = {}; + string s = resolve_isolated_path(path, ctx->permissions.fs_id, &rootfs, ISOLATEDFS_ALLOW_KFS); + if (!s.data || !s.length) return 0; + size_t ret = transform_file(&rootfs, s.data, buf, size); + string_free(s); + return ret; +#else + return transform_file(kernel_fs(), path, buf, size); +#endif +} + u64 syscall_sreadf(process_t *ctx, thread_t *current_thread){ SYSCALL_STR(path, PROC_X0, false); size_t size = (size_t)current_thread->PROC_X2; @@ -549,6 +565,7 @@ syscall_entry syscalls[] = { [DIR_LIST_CODE] = syscall_dir_list, [FILE_STAT_CODE] = syscall_stat, [FILE_TRNC_CODE] = syscall_trunc, + [FILE_TRANS_CODE] = syscall_transf, [LOAD_FSMODULE_CODE] = syscall_load_fsmod, [UNLOAD_FSMODULE_CODE] = syscall_unload_fsmod, diff --git a/modules/audio/virt/audio.cpp b/modules/audio/virt/audio.cpp index f6d38000..748a956a 100644 --- a/modules/audio/virt/audio.cpp +++ b/modules/audio/virt/audio.cpp @@ -314,5 +314,6 @@ system_module audio_module = (system_module){ .truncate = 0, .getstat = 0,//TODO: stat .readdir = 0, + .transform = 0, .alias_info = {} }; diff --git a/modules/disk/raspi/disk.cpp b/modules/disk/raspi/disk.cpp index 2d221c4b..ce9a1e36 100644 --- a/modules/disk/raspi/disk.cpp +++ b/modules/disk/raspi/disk.cpp @@ -36,5 +36,6 @@ system_module disk_module = (system_module){ .truncate = 0, .getstat = 0, .readdir = 0, + .transform = 0, .alias_info = {} }; \ No newline at end of file diff --git a/modules/graph/raspi/graphics.cpp b/modules/graph/raspi/graphics.cpp index 5f356d92..1ae8810e 100644 --- a/modules/graph/raspi/graphics.cpp +++ b/modules/graph/raspi/graphics.cpp @@ -121,5 +121,6 @@ system_module graphics_module = { .truncate = 0, .getstat = 0,//TODO: stat .readdir = 0, + .transform = 0, .alias_info = {} }; \ No newline at end of file diff --git a/modules/graph/virt/graphics.cpp b/modules/graph/virt/graphics.cpp index 0c0dad13..c3d53469 100644 --- a/modules/graph/virt/graphics.cpp +++ b/modules/graph/virt/graphics.cpp @@ -131,5 +131,6 @@ system_module graphics_module = { .truncate = 0, .getstat = 0, .readdir = 0, + .transform = 0, .alias_info = {} }; \ No newline at end of file diff --git a/modules/usb/common/usb_common.cpp b/modules/usb/common/usb_common.cpp index 9527131e..90cd8a0a 100644 --- a/modules/usb/common/usb_common.cpp +++ b/modules/usb/common/usb_common.cpp @@ -86,5 +86,6 @@ system_module usb_module = (system_module){ .truncate = 0, .getstat = 0,//TODO: stat .readdir = 0, + .transform = 0, .alias_info = {} }; \ No newline at end of file diff --git a/services/pacguy/apps.c b/services/pacguy/apps.c index d29071e1..5aecb508 100644 --- a/services/pacguy/apps.c +++ b/services/pacguy/apps.c @@ -1,5 +1,9 @@ #include "files/vfs.h" #include "files/helpers.h" +#include "utils/package_info.h" +#include "data/format/toml.h" + +int manual_entries = 0; void handle_entry(const char *directory, const char *file) { if (strlen(file) && *file == '.') return; @@ -14,6 +18,31 @@ void handle_entry(const char *directory, const char *file) { } else string_free(fullpath); } +size_t resolve_fs(const char *path, void* buf, size_t size){ + char *prompt = buf; + (void)prompt; + size_t count = stack_count(entries); + for (u32 i = manual_entries; i < count; i++){ + module_file *file = chunk_array_get(entries, i); + if (file->alias_info.alias_path.data){ + string s = string_format("%S/package.info",file->alias_info.alias_path); + char *package = read_full_file(s.data, 0); + package_info pkg_info = parse_package_info(package); + if (slice_lit_match(slice_from_string(pkg_info.id), prompt, true)){ + if (size < file->alias_info.alias_path.length) { + package_info_dispose(&pkg_info); + return 0; + } + memcpy(buf, file->alias_info.alias_path.data, file->alias_info.alias_path.length); + package_info_dispose(&pkg_info); + return file->alias_info.alias_path.length; + } else package_info_dispose(&pkg_info); + release(package); + } + } + return 0; +} + void refresh_apps(){ if (!entries) entries = stack_create(sizeof(module_file),32); size_t count = stack_count(entries); @@ -22,6 +51,7 @@ void refresh_apps(){ string_free(STACK_GET(module_file, entries, i).alias_info.alias_path); } stack_reset(entries); + manual_entries += make_complex_entry("resolve", backing_virtual, entry_file, 0, (file_actions){.transform = resolve_fs}, (string){}); traverse_directory("/home/applications", false, handle_entry); traverse_directory("/boot/redos/system", false, handle_entry); } @@ -36,4 +66,5 @@ system_module apps_mod = { .write = vfs_write, .getstat = vfs_stat, .readdir = vfs_readdir, + .transform = vfs_trace_transform, }; \ No newline at end of file diff --git a/shared b/shared index 9ca10745..de0cb5cb 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 9ca10745fe148e79c545413b043c17bd73d8996d +Subproject commit de0cb5cb7a5bc076ea0093145c7de19f083cc5bf diff --git a/tools/launch/launch.c b/tools/launch/launch.c new file mode 100644 index 00000000..164753e7 --- /dev/null +++ b/tools/launch/launch.c @@ -0,0 +1,33 @@ +#include "syscalls/syscalls.h" +#include "memory/memory.h" + +int main(int argc, const char* argv[]){ + + if (argc < 2){ + print("Usage: launch bundle.id"); + return -1; + } + + const char* bundle_id = argv[1]; + size_t bsize = strlen(bundle_id)+1; + + if (bsize > 64){ + print("Bundle id too large"); + return -1; + } + + char *buf = zalloc(512); + memcpy(buf, bundle_id, bsize); + + transformf("/apps/resolve", buf, 512); + + print("Resolved id to %s",buf); + + fs_stat out_stat = {}; + if (statf(buf, &out_stat)){ + exec(buf, 0, 0, EXEC_MODE_DEFAULT); + return 0; + } + + return -1; +} diff --git a/user/launcher/main.c b/user/launcher/main.c index 5ae2c64b..d0b9c444 100644 --- a/user/launcher/main.c +++ b/user/launcher/main.c @@ -6,7 +6,7 @@ #include "memory/memory.h" #include "input_keycodes.h" #include "string/slice.h" -#include "package_info.h" +#include "utils/package_info.h" #define MAX_COLS 3 #define MAX_ROWS 3 diff --git a/user/launcher/package_info.c b/user/launcher/package_info.c deleted file mode 100644 index 88182067..00000000 --- a/user/launcher/package_info.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "package_info.h" -#include "data/format/toml.h" - -static inline void handle_package_kvp(string_slice key, string_slice value, void* ctx){ - package_info *pkg_info = (package_info*)ctx; - if ((size_t)strstart_case("app_name", key.data,true) == key.length) - pkg_info->name = string_from_literal_length(value.data, value.length); - if ((size_t)strstart_case("app_author", key.data,true) == key.length) - pkg_info->author = string_from_literal_length(value.data, value.length); - if ((size_t)strstart_case("app_version", key.data,true) == key.length) - pkg_info->version = string_from_literal_length(value.data, value.length); -} - -package_info parse_package_info(char *info){ - package_info pkg_info = {}; - read_toml(info, handle_package_kvp, (void*)&pkg_info); - return pkg_info; -} \ No newline at end of file diff --git a/user/launcher/package_info.h b/user/launcher/package_info.h deleted file mode 100644 index 4a396f40..00000000 --- a/user/launcher/package_info.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "types.h" -#include "std/string.h" - -typedef struct { - bool valid; - string name; - string author; - string version; -} package_info; - -#ifdef __cplusplus -extern "C" { -#endif -package_info parse_package_info(char *info); -#ifdef __cplusplus -} -#endif \ No newline at end of file From 8248550053c1c6a276e62cb89225681431e77d9f Mon Sep 17 00:00:00 2001 From: di Date: Mon, 10 Aug 2026 00:00:00 +0000 Subject: [PATCH 08/11] [KBD] differentiate between key press and key continue --- kernel/usb/USBKeyboard.cpp | 2 +- shared | 2 +- user/launcher/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/usb/USBKeyboard.cpp b/kernel/usb/USBKeyboard.cpp index 4f613401..6d25083c 100644 --- a/kernel/usb/USBKeyboard.cpp +++ b/kernel/usb/USBKeyboard.cpp @@ -113,7 +113,7 @@ void USBKeyboard::process_keypress(keypress *rkp){ if (now < next_repeat[key]) continue; kbd_event event = {}; - event.type = KEY_PRESS; + event.type = KEY_CONTINUE; event.key = (char)key; register_event(event); diff --git a/shared b/shared index de0cb5cb..d4cf40ca 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit de0cb5cb7a5bc076ea0093145c7de19f083cc5bf +Subproject commit d4cf40cad57d761d0db01395c251e86aec6c50a5 diff --git a/user/launcher/main.c b/user/launcher/main.c index d0b9c444..c6508c37 100644 --- a/user/launcher/main.c +++ b/user/launcher/main.c @@ -117,7 +117,7 @@ void draw_desktop(){ gpu_point old_selected = selected; kbd_event event; while (read_event(&event)){ - if (event.type == KEY_PRESS){ + if (event.type == KEY_PRESS || event.type == KEY_CONTINUE){ switch (event.key) { case KEY_ENTER: case KEY_KPENTER: From ed8ecddeb0e9532244a7e7848010af7876db1cdb Mon Sep 17 00:00:00 2001 From: di Date: Mon, 10 Aug 2026 00:00:00 +0000 Subject: [PATCH 09/11] [SHARED] sign fix --- shared | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared b/shared index d4cf40ca..2200ae41 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit d4cf40cad57d761d0db01395c251e86aec6c50a5 +Subproject commit 2200ae4183c1a473e942aef791eb4b99cef6c1c5 From 9cb5b038fc37c70b234a729afc0719f6a12800ab Mon Sep 17 00:00:00 2001 From: di Date: Tue, 11 Aug 2026 00:00:00 +0000 Subject: [PATCH 10/11] [JOB] replace the stack using virtual mapping --- kernel/memory/mmu.c | 58 ++++++++++++++++++++++--- kernel/memory/mmu.h | 3 ++ kernel/process/jobs/job_manager.c | 50 ++++++++++----------- kernel/process/jobs/job_manager.h | 12 ++--- kernel/process/jobs/job_save.S | 17 +++----- kernel/process/loading/elf_file.c | 4 +- kernel/process/loading/process_loader.c | 1 - kernel/process/process.h | 2 +- kernel/process/scheduler.c | 1 + kernel/process/syscall.c | 10 +++-- 10 files changed, 98 insertions(+), 60 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 27f06933..f5215c58 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -503,10 +503,7 @@ void mmu_init() { page_alloc_enable_high_va(); kernel_ttbr0_hw = pt_va_to_pa(kernel_ttbr0) & PTE_ADDR_MASK; - uint64_t ttbr1_pa = pt_va_to_pa(kernel_ttbr1) & PTE_ADDR_MASK; - asm volatile("msr ttbr1_el1, %0" :: "r"(ttbr1_pa)); - asm volatile("dsb ish"); - asm volatile("isb"); + mmu_swap_kttbr(0); mmu_swap_ttbr(0); @@ -538,6 +535,12 @@ void mmu_copy(uintptr_t *new_ttbr, uintptr_t *old_ttbr, int level){ } } +bool mmu_replace(uptr *table, uptr va, uptr new_pa){ + mmu_unmap_and_get_pa(table, va, 0); + mmu_map_4kb(table, va, new_pa, MAIR_IDX_NORMAL, MEM_RW | MEM_NORM, MEM_PRIV_KERNEL); + return true; +} + typedef struct { uintptr_t *table; int level; @@ -722,6 +725,44 @@ uintptr_t mmu_translate(uint64_t *root, uintptr_t va, int *status){ return (uintptr_t)((e3 & PTE_ADDR_MASK) | ((uint64_t)va & (GRANULE_4KB - 1))); } +//TODO: let's use this everywhere, to make code more readable +typedef union { + struct { + u64 vb: 1;//Validity descriptor + u64 tb: 1;//Table descriptor + u64 indx: 2;//Index into MAIR + u64 ns: 1; + u64 ap: 2; + u64 sh: 2; + u64 af: 1; + u64 rsvd3: 2; + u64 addr: 36; + u64 rsvd2: 5; + u64 pxn: 1; + u64 uxn: 1; + u64 sw: 4; + u64 rsvd: 5; + }; + u64 entry; +} +mmu_entry_t; + +void mmu_print_entry(mmu_entry_t entry){ + print("========="); + print("MMU entry %llb",entry); + print("UXN: %b",entry.uxn); + print("PXN: %b",entry.pxn); + print("ADDR: %llx",entry.addr); + print("AF: %b",entry.af); + print("SH: %b",entry.sh); + print("AP: %b",entry.ap); + print("NS: %b",entry.ns); + print("INDX: %i",entry.indx); + print("TB: %b",entry.tb); + print("VB: %b",entry.vb); + print("========="); +} + void debug_mmu_address(uint64_t va){ int tr = 0; uintptr_t pa = mmu_translate(0, (uintptr_t)va, &tr); @@ -771,7 +812,7 @@ void debug_mmu_address(uint64_t va){ if ((e2 & 0b11) == PD_BLOCK) { kprintf("Mapped as 2MB memory in L3"); - kprintf("Entry: %b", (uint64_t)e2); + mmu_print_entry((mmu_entry_t){ .entry = e2 }); return; } @@ -786,7 +827,7 @@ void debug_mmu_address(uint64_t va){ kprintf("L4 Table entry missing"); return; } - kprintf("Entry: %b", e3); + mmu_print_entry((mmu_entry_t){.entry = e3}); return; } @@ -803,6 +844,11 @@ void mmu_ttbr0_enable_user() { asm volatile("dsb ish\n\tisb" ::: "memory"); } +void mmu_swap_kttbr(uptr *ttbr){ + uint64_t ttbr1_pa = pt_va_to_pa(ttbr ?: kernel_ttbr1); + asm volatile("msr ttbr1_el1, %0" :: "r"(ttbr1_pa)); +} + void mmu_swap_ttbr(mm_struct *mm){ if (mm && mm->ttbr0) { pttbr = mm->ttbr0; diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index 80d150a1..5cb8f12c 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -45,6 +45,7 @@ void mmu_map_4kb(uint64_t *table, uint64_t va, uint64_t pa, uint64_t attr_index, void mmu_unmap_table(uint64_t *table, uint64_t va, uint64_t pa); void debug_mmu_address(uint64_t va); void mmu_enable_verbose(); +void mmu_swap_kttbr(uptr *ttbr); void mmu_swap_ttbr(mm_struct *mm); void mmu_ttbr0_disable_user(); void mmu_ttbr0_enable_user(); @@ -53,6 +54,8 @@ void mmu_asid_ensure(mm_struct *mm); void mmu_asid_release(mm_struct *mm); bool mmu_unmap_and_get_pa(uint64_t *table, uint64_t va, uint64_t *pa); bool mmu_set_access_flag(uint64_t *table, uint64_t va); +void mmu_copy(uintptr_t *new_ttbr, uintptr_t *old_ttbr, int level); +bool mmu_replace(uptr *ttbr, uptr va, uptr new_pa); uintptr_t* mmu_default_ttbr(); void mmu_free_ttbr(uintptr_t *ttbr); uintptr_t mmu_translate(uint64_t *root, uintptr_t va, int *status); diff --git a/kernel/process/jobs/job_manager.c b/kernel/process/jobs/job_manager.c index 305b282c..02b4459d 100644 --- a/kernel/process/jobs/job_manager.c +++ b/kernel/process/jobs/job_manager.c @@ -20,7 +20,7 @@ typedef struct { thread_t *requester; thread_t *worker; thread_t kernel_ctx; - sizedptr kstack; + uptr* kttbr; job_id_t id; job_buffer buffers[8]; size_t buffer_count; @@ -94,20 +94,18 @@ u64 create_new_job(job_application_t application, system_module *mod, thread_t * process_t *requesting_proc = get_proc_by_pid(application.requesting_pid); if (!requesting_proc){ print("[JOB error] Unknown requesting proc %i",application.requesting_pid); - return (job_id_t){}; + return 0; } job_state_t *job = job_alloc(); job->type = application.type; job->mod = mod; thread_t *requester = (thread_t*)get_thread_from_proc(requesting_proc, application.requesting_tid); - if (job_kstack.ptr) - requester->kstack_top = job_kstack.ptr+job_kstack.size; job->requester = requester; process_t *fs_owner = get_proc_by_pid(application.worker_pid); thread_t *new_t = alloc_thread(); if (!prepare_thread(job, mod, application, fs_owner, new_t)){ print("[JOB error] failed to prepare thread for job %i",job->id); - return false; + return 0; } print("[JOB debug] Sync between %i - %i will happen with job %i of type %i using thread %i",requester->pid,application.worker_pid,job->id,application.type,new_t->tid); new_t->job_id = job->id; @@ -117,7 +115,19 @@ u64 create_new_job(job_application_t application, system_module *mod, thread_t * memcpy(&job->kernel_ctx, kthread, sizeof(thread_t)); job->kernel_ctx.job_id = job->id; job->kernel_ctx.pc = job_save_ret(); - job->kstack = job_kstack; + if (job_kstack.ptr && job_kstack.size){ + uptr* ttbr1k = mmu_default_ttbr(); + uptr* newttbr1 = mmu_new_ttbr(); + job->kttbr = newttbr1; + mmu_copy(newttbr1, ttbr1k, 0); + uptr base = (uptr)ksp - 0x10000; + for (uptr a = 0; a < 0x10000; a += PAGE_SIZE){ + int st = 0; + uptr addr = mmu_translate(newttbr1, job_kstack.ptr + a, &st); + if (st) return 0;//TODO: release table + mmu_replace(newttbr1, base + a, addr); + } + } schedule_thread(fs_owner, new_t); switch_proc(YIELD); return 0; @@ -163,9 +173,12 @@ void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ print("[JOB debug] Copy buffer %llx into %llx",buf.worker_ptr.ptr,buf.orig_ptr.ptr); void* addr = quick_translate(st->requester, proc, buf.orig_ptr.ptr); if (!addr){ - if (buf.orig_ptr.ptr & HIGH_VA) addr = (void*)buf.orig_ptr.ptr;//TODO: extra safety checks? - else continue; + if (buf.orig_ptr.ptr & HIGH_VA){ + int stb = 0; + addr = (void*)PHYS_TO_VIRT(mmu_translate(st->kttbr, buf.orig_ptr.ptr, &stb)); + } } + if (!addr) continue; memcpy(addr, (void*)buf.worker_ptr.ptr, buf.worker_ptr.size); } } @@ -174,26 +187,9 @@ void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread){ job_kpec = (uptr)&st->kernel_ctx; cpec = (uptr)st->requester; - //TODO: this entire thing is flimsy, we're only translating stack returns so we can make our way back to the userland proc, but any &values stored in the stack are not translated and risk corruption + failure - if (st->kstack.ptr){ - st->kernel_ctx.sp = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.sp); - print("[JOB debug] Initial Address %llx",st->kernel_ctx.regs[29]); - st->kernel_ctx.regs[29] = translate_stack((st->kstack.ptr+0x10000), st->kernel_ctx.regs[29]); - - uptr addr = st->kernel_ctx.regs[29]; - uptr fp = 0; - do { - print("[JOB debug] Address %llx",addr); - fp = *(uptr*)addr; - print("[JOB debug] Link %llx",fp); - fp = translate_stack(st->kstack.ptr+0x10000, fp); - print("[JOB debug] In new stack %llx",fp); - *(uptr*)addr = fp; - addr = fp; - } while(addr && (addr & 0xfffff00000000000) == 0xffffc00000000000); - job_ksp = st->kstack.ptr+0x10000; - } st->requester->state = RUNNING; + st->requester->special_mm = st->kttbr; prepare_process_restore(proc); + mmu_swap_kttbr(st->kttbr); job_restore_kernel(); } \ No newline at end of file diff --git a/kernel/process/jobs/job_manager.h b/kernel/process/jobs/job_manager.h index 363112ae..18709484 100644 --- a/kernel/process/jobs/job_manager.h +++ b/kernel/process/jobs/job_manager.h @@ -14,9 +14,9 @@ extern void save_kstack(); thread_t kthread = {};\ job_kstack = (sizedptr){};\ job_kpec = (uptr)&kthread;\ - job_ksp = get_current_thread()->kstack_top ?: (uptr)ksp;\ job_save_kernel();\ - save_kstack();\ + if (!get_current_thread()->special_mm)\ + save_kstack();\ process_t *owner_proc = get_proc_by_pid(mod->owner);\ job_application_t app = (job_application_t){\ .requesting_pid = get_current_proc()->id,\ @@ -91,10 +91,4 @@ static inline void job_serialize_off(job_application_t *application, int arg_num } u64 create_new_job(job_application_t application, system_module *mod, thread_t *kthread); -void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread); - -extern char ksp[]; - -static inline uptr translate_stack(uptr new_top, uptr ptr){ - return new_top-((uptr)ksp-ptr); -} \ No newline at end of file +void fulfill_job(job_id_t job_id, u64 ret, thread_t *thread); \ No newline at end of file diff --git a/kernel/process/jobs/job_save.S b/kernel/process/jobs/job_save.S index 80a984b1..c3c8759f 100644 --- a/kernel/process/jobs/job_save.S +++ b/kernel/process/jobs/job_save.S @@ -50,15 +50,8 @@ sub sp, sp, #32 stp x0, x1, [sp, #0] stp x21,x30, [sp, #16] -adrp x0, job_ksp -add x0, x0, :lo12:job_ksp -ldr x0, [x0] - -adrp x1, ksp -add x1, x1, :lo12:ksp -cmp x0, x1 - -b.ne 1f +adrp x0, ksp +add x0, x0, :lo12:ksp mov x1, sp sub x21, x0, x1 @@ -76,7 +69,6 @@ mov x1, sp mov x2, x21 bl memcpy -1: ldp x0, x1, [sp, #0] ldp x21,x30, [sp, #16] @@ -119,6 +111,11 @@ job_restore_kernel: ldr x30, [x18, #(8 * 32)] ldr x18, [x18, #(8 * 18)] + dsb ishst + tlbi vmalle1is + dsb ish + isb + ret .global job_save_ret diff --git a/kernel/process/loading/elf_file.c b/kernel/process/loading/elf_file.c index 4acc856a..c8f8da0d 100644 --- a/kernel/process/loading/elf_file.c +++ b/kernel/process/loading/elf_file.c @@ -199,7 +199,7 @@ process_t* load_elf_process_path(const char *name, const char *bundle, const cha if (!path || !*path) return 0; file fd = {}; - if (open_file(kernel_fs(), path, &fd) != FS_RESULT_SUCCESS) return 0; + if (open_file(kernel_fs(), path, &fd) != FS_RESULT_SUCCESS || fd.size == 0) return 0; char *program = (char*)zalloc(fd.size); if (!program) { @@ -208,7 +208,7 @@ process_t* load_elf_process_path(const char *name, const char *bundle, const cha } size_t amt = read_file(&fd, program, fd.size); - bool ok = amt == fd.size; + bool ok = amt && amt == fd.size; close_file(&fd); if (!ok) { diff --git a/kernel/process/loading/process_loader.c b/kernel/process/loading/process_loader.c index 9b1b74f5..b97b5326 100644 --- a/kernel/process/loading/process_loader.c +++ b/kernel/process/loading/process_loader.c @@ -405,7 +405,6 @@ process_t* create_process(const char *name, const char *bundle, program_load_dat proc->mm.rss_stack_pages = 0; - proc->shared_page = shared_base; proc->main_thread.regs[30] = proc->shared_page; kprintf("[NEW PROC:U]: %s (pid: %i, main tid: %i) allocated at %llx entry=%llx stack=%llx-%llx anon=%llx (phys=%llx)", name, proc->id, proc->main_thread.tid, proc, (uint64_t)proc->main_thread.pc, (uint64_t)proc->mm.stack_limit, (uint64_t)proc->mm.stack_top, (uint64_t)proc->mm.mmap_bottom, (uint64_t)proc->heap_phys); diff --git a/kernel/process/process.h b/kernel/process/process.h index b1a2a2cf..67c9afe7 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -72,7 +72,7 @@ struct thread_t { uint64_t spsr; //Not used in context saving stack_t stack_info; - uptr kstack_top; + uptr *special_mm; u16 pid; u16 tid; process_state state; diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index 5bab0b64..fb151713 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -172,6 +172,7 @@ void switch_proc(ProcSwitchReason reason) { } if (current_proc->mm.ttbr0) mmu_asid_ensure(¤t_proc->mm); + mmu_swap_kttbr(0); mmu_swap_ttbr(current_proc->mm.ttbr0 ? ¤t_proc->mm : 0); if (prev && prev != current_proc && prev != idle_proc && process_can_reset(prev)) reset_process(prev); diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index 5b8c2d1b..0ddb8a2e 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -705,7 +705,7 @@ void sync_el0_handler_c(){ if (syscall_depth < 3){ uint64_t ksp = 0; asm volatile ("mov %0, sp" : "=r"(ksp)); - kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx. KSP: %llx", esr, elr, far, ksp); + kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx. SP: %llx", esr, elr, far, ksp); coredump(esr, elr, far, ksp); } handle_exception("UNEXPECTED EXCEPTION", ec); @@ -719,10 +719,12 @@ void sync_el0_handler_c(){ } syscall_depth--; save_syscall_return(result); - // print("Return to %i",current_thread->pid); - if (current_thread->kstack_top) { + if (current_thread->special_mm) { //TODO: schedule kstack_top to cleanup, but don't do immediately as we're in it - current_thread->kstack_top = 0; + current_thread->special_mm = 0; + mmu_swap_kttbr(0); + mmu_flush_all(); + mmu_flush_icache(); } job_ksp = (uptr)ksp; process_restore(); From f7049b19de154f55d61883cbde479ee33d01892a Mon Sep 17 00:00:00 2001 From: di Date: Wed, 12 Aug 2026 00:00:00 +0000 Subject: [PATCH 11/11] [MMU] restored flushes to header --- kernel/memory/mmu.c | 20 -------------------- kernel/memory/mmu.h | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index f5215c58..ff8dd0e7 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -38,8 +38,6 @@ static uintptr_t *kernel_ttbr1; static uint64_t kernel_ttbr0_hw; static bool mmu_verbose; -static inline void mmu_flush_icache(); -static inline void mmu_flush_all(); static uint64_t asid_shift; @@ -296,24 +294,6 @@ void mmu_map_4kb(uint64_t *table, uint64_t va, uint64_t pa, uint64_t attr_index, l3[l3_index] = want; } -static inline void mmu_flush_all() { - asm volatile ( - "dsb ishst\n" // Ensure all memory accesses complete - "tlbi vmalle1is\n" // Invalidate all EL1 TLB entries (Inner Shareable) - "dsb ish\n" // Ensure completion of TLB invalidation - "isb\n" // Synchronize pipeline - ::: "memory" - ); -} - -static inline void mmu_flush_icache() { - asm volatile ( - "ic iallu\n" // Invalidate all instruction caches to PoU - "isb\n" // Ensure completion before continuing - ::: "memory" - ); -} - uintptr_t* mmu_default_ttbr(){ return kernel_ttbr1; } diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index 5cb8f12c..9475d406 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -66,4 +66,22 @@ void mmu_map_all(paddr_t pa); void mmu_unmap(uint64_t va, uint64_t pa); -void mmu_init_kernel(); \ No newline at end of file +void mmu_init_kernel(); + +static inline void mmu_flush_all() { + asm volatile ( + "dsb ishst\n" // Ensure all memory accesses complete + "tlbi vmalle1is\n" // Invalidate all EL1 TLB entries (Inner Shareable) + "dsb ish\n" // Ensure completion of TLB invalidation + "isb\n" // Synchronize pipeline + ::: "memory" + ); +} + +static inline void mmu_flush_icache() { + asm volatile ( + "ic iallu\n" // Invalidate all instruction caches to PoU + "isb\n" // Ensure completion before continuing + ::: "memory" + ); +} \ No newline at end of file