From 3a3c57357c95629dc89c1045c7dbe3b0c1c6c778 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 22 Oct 2018 11:43:55 +0200 Subject: [PATCH] Add a sys$exit and make init_stage2 call it when finished. --- Kernel/Syscall.cpp | 4 ++++ Kernel/Syscall.h | 7 ++++--- Kernel/Task.cpp | 20 ++++++++++++++++++++ Kernel/Task.h | 2 ++ Kernel/init.cpp | 5 +++++ 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index ebf0f71eef2..bbebaecdf81 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -77,6 +77,10 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) return current->sys$kill((pid_t)arg1, (int)arg2); case Syscall::PosixGetuid: return current->sys$getuid(); + case Syscall::PosixExit: + current->sys$exit((int)arg1); + ASSERT_NOT_REACHED(); + return 0; default: kprintf("int0x80: Unknown function %x requested {%x, %x, %x}\n", function, arg1, arg2, arg3); break; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 25f38b2c4de..3e624a83a73 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -16,6 +16,7 @@ enum Function { PosixSeek = 0x1988, PosixKill = 0x1989, PosixGetuid = 0x1990, + PosixExit = 0x1991, }; void initialize(); @@ -23,21 +24,21 @@ void initialize(); inline DWORD invoke(DWORD function) { DWORD result; - asm("int $0x80":"=a"(result):"a"(function)); + asm volatile("int $0x80":"=a"(result):"a"(function)); return result; } inline DWORD invoke(DWORD function, DWORD arg1) { DWORD result; - asm("int $0x80":"=a"(result):"a"(function),"d"(arg1)); + asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1)); return result; } inline DWORD invoke(DWORD function, DWORD arg1, DWORD arg2) { DWORD result; - asm("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2)); + asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2)); return result; } diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 581345a6692..e46985ee4b8 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -235,6 +235,26 @@ void Task::dumpRegions() } } +void Task::sys$exit(int status) +{ + cli(); + kprintf("sys$exit: %s(%u) exit with status %d\n", name().characters(), pid(), status); + + setState(Exiting); + dumpRegions(); + + s_tasks->remove(this); + + if (!scheduleNewTask()) { + kprintf("Task::taskDidCrash: Failed to schedule a new task :(\n"); + HANG; + } + + delete this; + + switchNow(); +} + void Task::taskDidCrash(Task* crashedTask) { // NOTE: This is called from an excepton handler, so interrupts are disabled. diff --git a/Kernel/Task.h b/Kernel/Task.h index 964e193d77b..cd6a8968ef8 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -31,6 +31,7 @@ public: BlockedSleep = 5, Terminated = 6, Crashing = 7, + Exiting = 8, }; enum RingLevel { @@ -83,6 +84,7 @@ public: int sys$kill(pid_t pid, int sig); int sys$geterror() { return m_error; } void sys$sleep(DWORD ticks); + void sys$exit(int status); struct { diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 39736ad7d7f..fd0c8d7510b 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -192,6 +192,11 @@ static void init_stage2() kprintf("init stage2 is done!\n"); + DO_SYSCALL_A1(Syscall::PosixExit, 413); + + kprintf("uh, we're still going after calling sys$exit...\n"); + HANG; + for (;;) { asm("hlt"); }