diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-10-22 11:43:55 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-10-22 11:43:55 +0200 |
commit | 3a3c57357c95629dc89c1045c7dbe3b0c1c6c778 (patch) | |
tree | 33fee3c22d29290280b1f73df74c8f1995ef2899 | |
parent | 79ffdb720564bea95d753f6ebe7815fa0ada3501 (diff) | |
download | serenity-3a3c57357c95629dc89c1045c7dbe3b0c1c6c778.zip |
Add a sys$exit and make init_stage2 call it when finished.
-rw-r--r-- | Kernel/Syscall.cpp | 4 | ||||
-rw-r--r-- | Kernel/Syscall.h | 7 | ||||
-rw-r--r-- | Kernel/Task.cpp | 20 | ||||
-rw-r--r-- | Kernel/Task.h | 2 | ||||
-rw-r--r-- | Kernel/init.cpp | 5 |
5 files changed, 35 insertions, 3 deletions
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index ebf0f71eef..bbebaecdf8 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 25f38b2c4d..3e624a83a7 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 581345a669..e46985ee4b 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 964e193d77..cd6a8968ef 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 39736ad7d7..fd0c8d7510 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"); } |