summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-22 11:43:55 +0200
committerAndreas Kling <awesomekling@gmail.com>2018-10-22 11:43:55 +0200
commit3a3c57357c95629dc89c1045c7dbe3b0c1c6c778 (patch)
tree33fee3c22d29290280b1f73df74c8f1995ef2899
parent79ffdb720564bea95d753f6ebe7815fa0ada3501 (diff)
downloadserenity-3a3c57357c95629dc89c1045c7dbe3b0c1c6c778.zip
Add a sys$exit and make init_stage2 call it when finished.
-rw-r--r--Kernel/Syscall.cpp4
-rw-r--r--Kernel/Syscall.h7
-rw-r--r--Kernel/Task.cpp20
-rw-r--r--Kernel/Task.h2
-rw-r--r--Kernel/init.cpp5
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");
}