From dc3d80d707dcac99977db703ca8f9a709fac8b02 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Wed, 10 Sep 2025 23:25:03 +0200 Subject: [PATCH] Handle process arguments --- kernel/hal/x86_64/intr.c | 2 +- kernel/hal/x86_64/switch.S | 3 --- kernel/proc/proc.c | 21 +++++++++++++++------ kernel/proc/proc.h | 18 ++++++++++++++++++ kernel/syscall/processctl.c | 36 +++++++++++++++++++++++++++++++++++- kernel/syscall/processctl.h | 2 +- share/sysdefs/processctl.h | 4 ++++ ulib/_premain.c | 32 ++++++++++++++++++++++++++++++++ ulib/args.h | 7 +++++++ ulib/system/system.c | 4 ++-- ulib/system/system.h | 2 +- user/init/main.c | 10 ++++++---- user/tb/main.c | 9 +++++---- 13 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 ulib/args.h diff --git a/kernel/hal/x86_64/intr.c b/kernel/hal/x86_64/intr.c index 06fc30e..c45d6e7 100644 --- a/kernel/hal/x86_64/intr.c +++ b/kernel/hal/x86_64/intr.c @@ -186,7 +186,7 @@ void intr_handleintr(IntrStackFrame *frame) { if (frame->trapnum <= 31) { kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); intr_dumpframe(frame); - if (frame->trapnum == 14 && frame->errnum & 0x4) { + if ((frame->trapnum == 14 && frame->errnum & 0x4) || frame->trapnum == 0x6) { kprintf("killed pid %ld %s\n", PROCS.current->pid, PROCS.current->name); proc_killself(); proc_sched((void *)frame); diff --git a/kernel/hal/x86_64/switch.S b/kernel/hal/x86_64/switch.S index 3e344ea..91a9363 100644 --- a/kernel/hal/x86_64/switch.S +++ b/kernel/hal/x86_64/switch.S @@ -1,8 +1,5 @@ #include "regs.S" -siema: - jmp siema - .global hal_switchproc hal_switchproc: mov %cr3, %rcx diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 7c518c2..21a8f02 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -198,7 +198,6 @@ Proc *proc_nextready(void) { } proc = proc->next; } - return proc; } void proc_reaper(void) { @@ -243,6 +242,14 @@ void proc_reaper(void) { } pmm_free((uintptr_t)zombie->platformdata.cr3, 1); + + ProcArg *arg = zombie->procargs.list; + while (arg) { + dlfree(arg->string); + ProcArg *tmp = arg; + arg = arg->next; + dlfree(tmp); + } } dlfree(zombie); } else { @@ -251,19 +258,21 @@ void proc_reaper(void) { } } +extern void hal_zombiespin(void); + void proc_sched(void *cpustate) { hal_intr_disable(); sched_ticks++; - if (sched_ticks % PROC_REAPER_FREQ == 0) { - proc_reaper(); - } - IntrStackFrame *frame = cpustate; PROCS.current->platformdata.trapframe = *frame; - + PROCS.current = proc_nextready(); + + if (sched_ticks % PROC_REAPER_FREQ == 0) { + proc_reaper(); + } hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3); } diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index 65f2749..350df0a 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -7,6 +7,7 @@ #include "bitmap/bitmap.h" #include "vfs/vfs.h" #include "ipc/pipe/pipe.h" +#include "sysdefs/processctl.h" #define PROC_NAME_MAX 0x100 @@ -33,6 +34,11 @@ enum { PROC_WAITING = 3, }; +typedef struct ProcArg { + struct ProcArg *next; + char string[PROC_ARG_MAX]; +} ProcArg; + typedef struct Proc { struct Proc *next; @@ -53,6 +59,10 @@ typedef struct Proc { IpcPipe *list; SpinLock spinlock; } bcast_pipes; + struct { + ProcArg *list; + size_t len; + } procargs; uint64_t mman_map_base; } Proc; @@ -79,4 +89,12 @@ void proc_kill(Proc *proc); for(;;); \ } while(0) + +#define PROC_ARG(proc, str) \ + do { \ + ProcArg *__arg = dlmalloc(sizeof(*__arg)); \ + hal_strcpy(__arg->string, (str)); \ + LL_APPEND((proc)->procargs.list, __arg); \ + (proc)->procargs.len++; \ + } while(0) #endif // PROC_PROC_H_ diff --git a/kernel/syscall/processctl.c b/kernel/syscall/processctl.c index dcbd365..0fab511 100644 --- a/kernel/syscall/processctl.c +++ b/kernel/syscall/processctl.c @@ -8,11 +8,12 @@ #include "vfs/vfs.h" #include "path/path.h" #include "kprintf.h" +#include "dlmalloc/malloc.h" #define PCTL_MP_MAX 0xff #define PCTL_PATH_MAX VFS_PATH_MAX -int32_t SYSCALL3(sys_processctl, pid1, cmd1, arg1) { +int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) { uint64_t pid = pid1; uint64_t cmd = cmd1; int32_t ret = E_OK; @@ -58,6 +59,13 @@ int32_t SYSCALL3(sys_processctl, pid1, cmd1, arg1) { ret = E_NOMEMORY; goto done; } + + size_t argslen = arg3; + char **args = (char **)arg2; + for (size_t i = 0; i < argslen; i++) { + PROC_ARG(newproc, args[i]); + } + proc_register(newproc); ret = newproc->pid; } break; @@ -70,6 +78,32 @@ int32_t SYSCALL3(sys_processctl, pid1, cmd1, arg1) { case PCTL_GETPID: { ret = proc->pid; } break; + case PCTL_ARGLEN: { + ret = proc->procargs.len; + } break; + case PCTL_ARGV: { + char **argbuf = (char **)arg1; + if (argbuf == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + size_t len = arg2; + ProcArg *arg = proc->procargs.list; + size_t i = 0; + while (arg) { + if (i == len) { + break; + } + if (argbuf[i] == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + hal_strcpy(argbuf[i], arg->string); + arg = arg->next; + i++; + } + ret = E_OK; + } break; default: { ret = E_INVALIDARGUMENT; } break; diff --git a/kernel/syscall/processctl.h b/kernel/syscall/processctl.h index b25d7be..2023d2f 100644 --- a/kernel/syscall/processctl.h +++ b/kernel/syscall/processctl.h @@ -4,6 +4,6 @@ #include #include "syscall.h" -int32_t SYSCALL3(sys_processctl, pid1, cmd1, arg1); +int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3); #endif // SYSCALL_PROCESSCTL_H_ diff --git a/share/sysdefs/processctl.h b/share/sysdefs/processctl.h index ef2b726..fd62551 100644 --- a/share/sysdefs/processctl.h +++ b/share/sysdefs/processctl.h @@ -1,12 +1,16 @@ #ifndef SHARE_HDRS_PROCESSCTL_H_ #define SHARE_HDRS_PROCESSCTL_H_ +#define PROC_ARG_MAX 0x400 + enum { PCTL_KILL = 0, PCTL_SPAWN = 1, PCTL_POLLSTATE = 2, PCTL_RUN = 3, PCTL_GETPID = 4, + PCTL_ARGLEN = 5, + PCTL_ARGV = 6, }; #endif // SHARE_HDRS_PROCESSCTL_H_ diff --git a/ulib/_premain.c b/ulib/_premain.c index 4420903..7c2c75a 100644 --- a/ulib/_premain.c +++ b/ulib/_premain.c @@ -1,5 +1,10 @@ #include #include +#include +#include +#include +#include +#include extern void main(void); @@ -14,9 +19,36 @@ void bss_clear(void) { } } +static char **_args; +static size_t _argslen; + +char **args(void) { + return _args; +} + +size_t argslen(void) { + return _argslen; +} + // ulib initialization goes here void _premain(void) { bss_clear(); + + _argslen = processctl(-1, PCTL_ARGLEN, 0, 0, 0); + _args = dlmalloc(_argslen * sizeof(*_args)); + if (_args == NULL) { + return; + } + for (size_t i = 0; i < _argslen; i++) { + _args[i] = dlmalloc(PROC_ARG_MAX); + if (_args[i] == NULL) { + return; + } + } + if (processctl(-1, PCTL_ARGV, (uint64_t)_args, _argslen, 0) != E_OK) { + return; + } + main(); } diff --git a/ulib/args.h b/ulib/args.h new file mode 100644 index 0000000..e82ad0c --- /dev/null +++ b/ulib/args.h @@ -0,0 +1,7 @@ +#ifndef ULIB_ARGS_H_ +#define ULIB_ARGS_H_ + +char **args(void); +size_t argslen(void); + +#endif // ULIB_ARGS_H_ diff --git a/ulib/system/system.c b/ulib/system/system.c index 7a9e90a..bb4386b 100644 --- a/ulib/system/system.c +++ b/ulib/system/system.c @@ -11,8 +11,8 @@ int32_t ioctl(uint64_t ioh, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t return syscall(SYS_IOCTL, ioh, cmd, arg1, arg2, arg3, 0); } -int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1) { - return syscall(SYS_PROCESSCTL, pid, cmd, arg1, 0, 0, 0); +int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3) { + return syscall(SYS_PROCESSCTL, pid, cmd, arg1, arg2, arg3, 0); } int32_t ipcpipe(uint64_t pid, uint64_t pipenum, uint64_t cmd, uint8_t *buffer, size_t len) { diff --git a/ulib/system/system.h b/ulib/system/system.h index 483769d..98d6b0b 100644 --- a/ulib/system/system.h +++ b/ulib/system/system.h @@ -6,7 +6,7 @@ void debugprint(const char *string); int32_t ioctl(uint64_t ioh, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3); -int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1); +int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3); int32_t ipcpipe(uint64_t pid, uint64_t pipenum, uint64_t cmd, uint8_t *buffer, size_t len); int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out); int32_t mman_unmap(uint8_t *addr); diff --git a/user/init/main.c b/user/init/main.c index b448abd..ba7d946 100644 --- a/user/init/main.c +++ b/user/init/main.c @@ -30,10 +30,12 @@ void main(void) { uprintf("Hello world using uprintf\n"); - int32_t tb = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb"); - ipcpipe(tb, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)(uint64_t)processctl(-1, PCTL_GETPID, 0), IPCPIPE_OUT); - processctl(tb, PCTL_RUN, 0); - while(processctl(tb, PCTL_POLLSTATE, 0) != 2); + const char *tbargs[] = { "-i" }; + int32_t tb = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)tbargs, 1); + uint64_t selfpid = (uint64_t)processctl(-1, PCTL_GETPID, 0, 0, 0); + ipcpipe(tb, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)selfpid, IPCPIPE_OUT); + processctl(tb, PCTL_RUN, 0, 0, 0); + while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 2); if (ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_MAKE, NULL, 0) < 0) { uprintf("failed to create 10th pipe\n"); diff --git a/user/tb/main.c b/user/tb/main.c index d0ac596..fefecc9 100644 --- a/user/tb/main.c +++ b/user/tb/main.c @@ -1,11 +1,12 @@ #include #include +#include void main(void) { uprintf("Hello from tb!\n"); - int *tmp = dlmalloc(sizeof(*tmp) * 1024); - *tmp = 123456; - uprintf("*tmp = %d\n", *tmp); - dlfree(tmp); + for (size_t i = 0; i < argslen(); i++) { + uprintf("i = %d\n", i); + uprintf("arg: %s\n", args()[i]); + } }