Add argument passing

This commit is contained in:
Ali Mashtizadeh 2023-08-20 19:04:28 -04:00
parent e261ccdcec
commit 2718379e6d
11 changed files with 127 additions and 21 deletions

View File

@ -78,7 +78,8 @@ Cmd_Run(int argc, const char *argv[])
continue;
}
status = OSSpawn(path);
argv[argc] = NULL;
status = OSSpawn(path, &argv[0]);
if (status > 100000) {
printf("Spawn failed!\n");
}

View File

@ -10,7 +10,7 @@
uint64_t OSTime();
uint64_t OSGetPID();
void OSExit(int status);
uint64_t OSSpawn(const char *path);
uint64_t OSSpawn(const char *path, const char *argv[]);
uint64_t OSWait(uint64_t pid);
// Memory

View File

@ -105,8 +105,8 @@ _start(char **ap)
char **argv = NULL;
char **env = NULL;
//argc = *(long *)(void *)ap;
//argv = ap + 1;
argc = *(long *)(void *)ap;
argv = ap + 1;
//env = ap + 2 + argc;
handle_argv(argc, argv, env);

View File

@ -26,9 +26,9 @@ OSGetPID()
}
uint64_t
OSSpawn(const char *path)
OSSpawn(const char *path, const char *argv[])
{
return syscall(SYSCALL_SPAWN, path);
return syscall(SYSCALL_SPAWN, path, argv);
}
uint64_t
@ -97,6 +97,12 @@ OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset)
return syscall(SYSCALL_READDIR, fd, buf, length, offset);
}
int
OSPipe(uint64_t fd[2])
{
return syscall(SYSCALL_PIPE, &fd[0]);
}
int
OSThreadCreate(uint64_t rip, uint64_t arg)
{

View File

@ -15,7 +15,7 @@ src.append(src_common)
src.append(env["CRTEND"])
init_env.Append(LINKFLAGS = ['-nostdlib'])
init_env.Append(CPPFLAGS = ['-nostdinc'])
init_env.Append(CPPFLAGS = ['-nostdinc', '-mno-sse'])
init_env.Append(CPPPATH = ['#build/include'])
init_env.Append(LIBPATH = ['#build/lib/libc'], LIBS = ['c'])

View File

@ -8,7 +8,8 @@ main(int argc, const char *argv[])
fputs("Init spawning shell\n", stdout);
status = OSSpawn("/bin/shell");
const char *args[] = { "/bin/shell", NULL };
status = OSSpawn("/bin/shell", &args[0]);
if (status > 100) {
printf("init: Could not spawn shell %016lx\n", status);
}

View File

@ -35,6 +35,7 @@
#define MEM_USERSPACE_STKBASE 0x0000000070000000ULL
#define MEM_USERSPACE_STKLEN 0x0000000000010000ULL
#define MEM_USERSPACE_STKTOP (MEM_USERSPACE_STKBASE + MEM_USERSPACE_STKLEN)
#define MEM_DIRECTMAP_BASE 0xFFFF800000000000ULL
#define MEM_DIRECTMAP_LEN 0x0000010000000000ULL

View File

@ -63,7 +63,7 @@ ThreadEnterUserLevelCB(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
tf.ds = SEL_UDS | 3;
tf.rip = (uint64_t)arg1;
tf.cs = SEL_UCS | 3;
tf.rsp = (uint64_t)arg2 + MEM_USERSPACE_STKLEN;
tf.rsp = (uint64_t)arg2 + MEM_USERSPACE_STKLEN - PGSIZE;
tf.ss = SEL_UDS | 3;
tf.rflags = RFLAGS_IF;
tf.rdi = (uint64_t)arg3; /* Userspace Argument */
@ -83,6 +83,10 @@ extern TaskStateSegment64 TSS[MAX_CPUS];
void
Thread_SwitchArch(Thread *oldthr, Thread *newthr)
{
/*
* Save and restore floating point and vector CPU state using the fxsave
* and fxrstor instructions.
*/
if (oldthr->arch.useFP)
{
fxsave(&oldthr->arch.xsa);

View File

@ -98,15 +98,23 @@ Loader_LoadFirst(Thread *thr, VNode *vn, void *buf, uint64_t len)
Log(loader, "Jumping to userspace\n");
uintptr_t ap[3];
ap[0] = 0;
ap[1] = 0;
ap[2] = 0xDEADBEEF;
uintptr_t rsp = MEM_USERSPACE_STKTOP - PGSIZE;
Copy_Out(&ap[0], rsp, sizeof(uintptr_t)*3);
TrapFrame tf;
memset(&tf, 0, sizeof(tf));
tf.ds = SEL_UDS | 3;
tf.rip = ehdr->e_entry;
tf.cs = SEL_UCS | 3;
tf.rsp = MEM_USERSPACE_STKBASE + MEM_USERSPACE_STKLEN;
tf.rsp = rsp;
tf.ss = SEL_UDS | 3;
tf.rflags = RFLAGS_IF;
tf.rdi = 0;
tf.rdi = rsp;
Trap_Pop(&tf);
return true;
@ -262,7 +270,7 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
}
}
Thread_SetupUThread(thr, ehdr->e_entry, 0);
Thread_SetupUThread(thr, ehdr->e_entry, MEM_USERSPACE_STKTOP - PGSIZE);
return true;
}

View File

@ -61,11 +61,12 @@ Syscall_Exit(uint64_t status)
}
uint64_t
Syscall_Spawn(uint64_t user_path)
Syscall_Spawn(uint64_t user_path, uint64_t user_argv)
{
int status;
char path[512];
void *pg;
char *arg;
VNode *file;
Process *proc;
Thread *thr;
@ -77,14 +78,52 @@ Syscall_Spawn(uint64_t user_path)
Log(syscall, "Spawn(%s)\n", path);
arg = PAlloc_AllocPage();
if (!arg) {
return SYSCALL_PACK(ENOMEM, 0);
}
/* Copy argument pointers */
for (int i = 0; i < 8; i++) {
uintptr_t off = sizeof(uintptr_t)*i;
status = Copy_In(user_argv+off, arg+sizeof(uintptr_t)*(1+i), sizeof(uintptr_t));
if (status != 0) {
PAlloc_Release(arg);
return SYSCALL_PACK(status, 0);
}
if (*(uintptr_t *)(arg+sizeof(uintptr_t)*(1+i)) == 0)
break;
}
/* Copy each argument in */
char *argstart = arg+sizeof(uintptr_t)*1;
for (int i = 3; i < 8; i++) {
uintptr_t *str = (uintptr_t *)(arg+sizeof(uintptr_t)*i);
if (*str == 0)
break;
status = Copy_StrIn(*str, argstart, 256); // XXX: Make sure there's no overrun
if (status != 0) {
PAlloc_Release(arg);
return SYSCALL_PACK(status, 0);
}
*str = (uintptr_t)argstart;
argstart += strlen(argstart)+1;
}
pg = PAlloc_AllocPage();
if (!pg) {
PAlloc_Release(arg);
return SYSCALL_PACK(ENOMEM, 0);
}
file = VFS_Lookup(path);
if (!file) {
// Free
PAlloc_Release(pg);
PAlloc_Release(arg);
return SYSCALL_PACK(ENOENT, 0);
}
@ -92,6 +131,8 @@ Syscall_Spawn(uint64_t user_path)
if (status < 0) {
Log(syscall, "Error VFS_Open\n");
// Release & free
PAlloc_Release(pg);
PAlloc_Release(arg);
return SYSCALL_PACK(status, 0);
}
@ -99,10 +140,16 @@ Syscall_Spawn(uint64_t user_path)
if (status < 0) {
Log(syscall, "Error VFS_Read\n");
// Release & free
VFS_Close(file);
PAlloc_Release(pg);
PAlloc_Release(arg);
return SYSCALL_PACK(status, 0);
}
if (!Loader_CheckHeader(pg)) {
VFS_Close(file);
PAlloc_Release(pg);
PAlloc_Release(arg);
return SYSCALL_PACK(EINVAL, 0);
}
@ -121,6 +168,34 @@ Syscall_Spawn(uint64_t user_path)
Loader_Load(thr, file, pg, 1024);
/* Translate mapping for stack page */
argstart = (char *)DMPA2VA(PMap_Translate(thr->space, MEM_USERSPACE_STKTOP-PGSIZE));
argstart += sizeof(uintptr_t)*8;
uintptr_t offset = sizeof(uintptr_t)*8;
/* Copy each argument and update the pointer array */
uintptr_t *arg_ap = (uintptr_t *)arg;
for (int i = 1; i < 8; i++) {
uintptr_t *str = (uintptr_t *)(arg+sizeof(uintptr_t)*i);
if (*str == 0) {
arg_ap[0] = i - 1;
arg_ap[i] = 0; // XXX: Environment
break;
}
size_t len = strlen((char *)arg_ap[i])+1;
strcpy(argstart, (char *)arg_ap[i]);
arg_ap[i] = (uintptr_t)(MEM_USERSPACE_STKTOP - PGSIZE + offset);
offset += len;
argstart += len;
}
/* Copy the argument pointer array */
argstart = (char *)DMPA2VA(PMap_Translate(thr->space, MEM_USERSPACE_STKTOP-PGSIZE));
memcpy(argstart, arg, sizeof(uintptr_t)*8);
VFS_Close(file);
Sched_SetRunnable(thr);
@ -651,7 +726,7 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2,
Syscall_Exit(a1);
return 0; // To eliminate warning
case SYSCALL_SPAWN:
return Syscall_Spawn(a1);
return Syscall_Spawn(a1, a2);
case SYSCALL_WAIT:
return Syscall_Wait(a1);
case SYSCALL_MMAP:

View File

@ -588,15 +588,10 @@ Thread_Dump(Thread *thr)
static void
Debug_Threads(int argc, const char *argv[])
{
int c = CPU();
Thread *thr;
//Spinlock_Lock(&threadLock);
kprintf("CPU %d\n", c);
kprintf("Current Thread: %d(%016llx) %d\n",
curProc[c]->tid, curProc[c], curProc[c]->ctxSwitches);
Thread_Dump(curProc[c]);
TAILQ_FOREACH(thr, &runnableQueue, schedQueue)
{
kprintf("Runnable Thread: %d(%016llx) %d\n", thr->tid, thr, thr->ctxSwitches);
@ -634,7 +629,22 @@ REGISTER_DBGCMD(processes, "Display list of processes", Debug_Processes);
static void
Debug_ThreadInfo(int argc, const char *argv[])
{
Thread *thr = curProc[CPU()];
kprintf("Current Thread State:\n");
Thread_Dump(thr);
}
REGISTER_DBGCMD(threadinfo, "Display thread state", Debug_ThreadInfo);
REGISTER_DBGCMD(threadinfo, "Display current thread state", Debug_ThreadInfo);
static void
Debug_ProcInfo(int argc, const char *argv[])
{
Thread *thr = curProc[CPU()];
kprintf("Current Process State:\n");
Process_Dump(thr->proc);
}
REGISTER_DBGCMD(procinfo, "Display current process state", Debug_ProcInfo);