Index: generic/src/main/uinit.c
===================================================================
--- generic/src/main/uinit.c	(revision 93165be1285f3a50e69871962061a2e2fcfb9ae6)
+++ generic/src/main/uinit.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -31,9 +31,20 @@
 #include <proc/thread.h>
 #include <userspace.h>
+#include <mm/slab.h>
 #include <print.h>
 
+/** Thread used to bring up userspace thread.
+ *
+ * @param arg Pointer to structure containing userspace entry and stack addresses.
+ */
 void uinit(void *arg)
 {
-	printf("USER task, uinit thread: kernel mode\n");
-	userspace((__address)(arg));
+	uspace_arg_t uarg;
+	
+	uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry;
+	uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack;
+
+	free((uspace_arg_t *) arg);
+	
+	userspace(&uarg);
 }
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision 93165be1285f3a50e69871962061a2e2fcfb9ae6)
+++ generic/src/proc/task.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -116,4 +116,5 @@
 	thread_t *t;
 	task_t *task;
+	uspace_arg_t *uarg;
 
 	as = as_create(0);
@@ -125,7 +126,10 @@
 	} 
 	
+	uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
+	uarg->uspace_entry = (__address) ((elf_header_t *) program_addr)->e_entry;
+	uarg->uspace_stack = USTACK_ADDRESS;
+	
 	task = task_create(as, name);
-	t = thread_create(uinit, (void *)((elf_header_t *)program_addr)->e_entry, 
-			  task, 0, "uinit");
+	t = thread_create(uinit, uarg, task, 0, "uinit");
 	
 	/*
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision 93165be1285f3a50e69871962061a2e2fcfb9ae6)
+++ generic/src/proc/thread.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -54,4 +54,5 @@
 #include <mm/slab.h>
 #include <debug.h>
+#include <main/uinit.h>
 
 char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */
@@ -281,5 +282,6 @@
 	interrupts_restore(ipl);
 	
-	t->name = name;
+	memcpy(t->name, name, THREAD_NAME_BUFLEN);
+	
 	t->thread_code = func;
 	t->thread_arg = arg;
@@ -424,2 +426,39 @@
 	interrupts_restore(ipl);
 }
+
+/** Process syscall to create new thread.
+ *
+ */
+__native sys_thread_create(__address function, void *arg, void *stack, char *name)
+{
+        thread_t *t;
+        char namebuf[THREAD_NAME_BUFLEN];
+	uspace_arg_t *uarg;
+	__u32 tid;
+
+        copy_from_uspace(namebuf, name, THREAD_NAME_BUFLEN);
+	uarg = (uspace_arg_t *) malloc(sizeof(uarg), 0);
+	
+	uarg->uspace_entry = function;
+	uarg->uspace_stack = (__address) stack;
+
+        if ((t = thread_create(uinit, uarg, TASK, 0, namebuf))) {
+		tid = t->tid;
+                thread_ready(t);
+		return (__native) tid; 
+        } else {
+                free(namebuf);
+        }
+
+        return (__native) -1;
+}
+
+/** Process syscall to terminate thread.
+ *
+ */
+__native sys_thread_exit(int status)
+{
+        thread_exit();
+        /* Unreachable */
+        return 0;
+}
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision 93165be1285f3a50e69871962061a2e2fcfb9ae6)
+++ generic/src/syscall/syscall.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -38,11 +38,4 @@
 #include <ipc/sysipc.h>
 
-static __native sys_ctl(void) {
-	printf("Thread finished\n");
-	thread_exit();
-	/* Unreachable */
-	return 0;
-}
-
 static __native sys_io(int fd, const void * buf, size_t count) {
 	
@@ -56,5 +49,4 @@
 	return count;
 }
-
 
 static __native sys_mmap(void *address, size_t size, int flags)
@@ -72,6 +64,7 @@
 
 syshandler_t syscall_table[SYSCALL_END] = {
-	sys_ctl,
 	sys_io,
+	sys_thread_create,
+	sys_thread_exit,
 	sys_mmap,
 	sys_mremap,
