Index: arch/amd64/src/userspace.c
===================================================================
--- arch/amd64/src/userspace.c	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ arch/amd64/src/userspace.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -40,5 +40,5 @@
  *
  */
-void userspace(__address entry)
+void userspace(uspace_arg_t *uarg)
 {
 	ipl_t ipl;
@@ -47,20 +47,16 @@
 
 	__asm__ volatile (""
-			  "movq %0, %%rax;"		       
-			  "movq %1, %%rbx;"
-			  "movq %2, %%rcx;"
-			  "movq %3, %%rdx;"
-			  "movq %4, %%rsi;"
-			  "pushq %%rax;"
-			  "pushq %%rbx;"
-			  "pushq %%rcx;"
-			  "pushq %%rdx;"
-			  "pushq %%rsi;"
-			  "iretq;"
-			  : : "i" (gdtselector(UDATA_DES) | PL_USER), 
-			  "i" (USTACK_ADDRESS+THREAD_STACK_SIZE), 
+			  "pushq %0\n"
+			  "pushq %1\n"
+			  "pushq %2\n"
+			  "pushq %3\n"
+			  "pushq %4\n"
+			  "iretq\n"
+			  : : 
+			  "i" (gdtselector(UDATA_DES) | PL_USER), 
+			  "r" (uarg->uspace_stack+THREAD_STACK_SIZE), 
 			  "r" (ipl), 
 			  "i" (gdtselector(UTEXT_DES) | PL_USER), 
-			  "r" (entry));
+			  "r" (uarg->uspace_entry));
 	
 	/* Unreachable */
Index: arch/ia32/include/fpu_context.h
===================================================================
--- arch/ia32/include/fpu_context.h	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ arch/ia32/include/fpu_context.h	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -40,5 +40,4 @@
 
 struct fpu_context {
-	/* TODO: We need malloc that aligns structures on 16-byte boundary */
 	__u8 fpu[512]; 		/* FXSAVE & FXRSTOR storage area */
 };
Index: arch/ia32/src/userspace.c
===================================================================
--- arch/ia32/src/userspace.c	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ arch/ia32/src/userspace.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -40,5 +40,5 @@
  *
  */
-void userspace(__address entry)
+void userspace(uspace_arg_t *uarg)
 {
 	ipl_t ipl;
@@ -61,5 +61,6 @@
 		"iret"
 		: 
-		: "i" (selector(UDATA_DES) | PL_USER), "r" (USTACK_ADDRESS+(THREAD_STACK_SIZE)), "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (entry)
+		: "i" (selector(UDATA_DES) | PL_USER), "r" (uarg->uspace_stack+THREAD_STACK_SIZE),
+		  "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (uarg->uspace_entry)
 		: "eax");
 	
Index: arch/ia64/src/ia64.c
===================================================================
--- arch/ia64/src/ia64.c	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ arch/ia64/src/ia64.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -42,4 +42,5 @@
 #include <userspace.h>
 #include <console/console.h>
+#include <proc/thread.h>
 
 void arch_pre_mm_init(void)
@@ -73,5 +74,5 @@
 
 /** Enter userspace and never return. */
-void userspace(__address entry)
+void userspace(uspace_arg_t *uarg)
 {
 	psr_t psr;
@@ -91,5 +92,5 @@
 	rsc.mode = 3;				/* eager mode */
 
-	switch_to_userspace(entry, USTACK_ADDRESS+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), USTACK_ADDRESS, psr.value, rsc.value);
+	switch_to_userspace(uarg->uspace_entry, uarg->uspace_stack+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), uarg->uspace_stack, psr.value, rsc.value);
 
 	while (1) {
Index: arch/mips32/src/mips32.c
===================================================================
--- arch/mips32/src/mips32.c	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ arch/mips32/src/mips32.c	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -121,5 +121,5 @@
 __address supervisor_sp __attribute__ ((section (".text")));
 
-void userspace(__address entry)
+void userspace(uspace_arg_t *uarg)
 {
 	/* EXL=1, UM=1, IE=1 */
@@ -127,6 +127,6 @@
 					      cp0_status_um_bit |
 					      cp0_status_ie_enabled_bit));
-	cp0_epc_write(entry);
-	userspace_asm(USTACK_ADDRESS+PAGE_SIZE);
+	cp0_epc_write(uarg->uspace_entry);
+	userspace_asm(uarg->uspace_stack+PAGE_SIZE);
 	while (1)
 		;
Index: generic/include/ipc/ipc.h
===================================================================
--- generic/include/ipc/ipc.h	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ generic/include/ipc/ipc.h	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -79,5 +79,5 @@
  *
  * The protocol for negotiating is:
- * - sys_connecttome - sends a message IPC_M_CONNECTTOME
+ * - sys_connect_to_me - sends a message IPC_M_CONNECTTOME
  * - sys_wait_for_call - upon receipt tries to allocate new phone
  *                       - if it fails, responds with ELIMIT
Index: generic/include/proc/thread.h
===================================================================
--- generic/include/proc/thread.h	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ generic/include/proc/thread.h	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -44,6 +44,4 @@
 #define THREAD_STACK_SIZE	STACK_SIZE
 
-#define THREAD_USER_STACK	1
-
 enum state {
 	Invalid,	/**< It is an error, if thread is found in this state. */
@@ -60,8 +58,8 @@
 #define X_STOLEN	(1<<1)
 
+#define THREAD_NAME_BUFLEN	20
+
 /** Thread structure. There is one per thread. */
 struct thread {
-	char *name;
-	
 	link_t rq_link;				/**< Run queue link. */
 	link_t wq_link;				/**< Wait queue link. */
@@ -76,4 +74,6 @@
 	 */
 	SPINLOCK_DECLARE(lock);
+
+	char name[THREAD_NAME_BUFLEN];
 
 	void (* thread_code)(void *);		/**< Function implementing the thread. */
@@ -118,4 +118,10 @@
 };
 
+/** Structure passed to uinit kernel thread as argument. */
+typedef struct uspace_arg {
+	__address uspace_entry;
+	__address uspace_stack;
+} uspace_arg_t;
+
 /** Thread list lock.
  *
@@ -140,7 +146,10 @@
 extern void thread_destroy(thread_t *t);
 
-
 /* Fpu context slab cache */
 extern slab_cache_t *fpu_context_slab;
 
+/** Thread syscall prototypes. */
+__native sys_thread_create(__address function, void *arg, void *stack, char *name);
+__native sys_thread_exit(int status);
+
 #endif
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ generic/include/syscall/syscall.h	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -31,6 +31,7 @@
 
 typedef enum {
-	SYS_CTL = 0,
-	SYS_IO,
+	SYS_IO = 0,
+	SYS_THREAD_CREATE,
+	SYS_THREAD_EXIT,
 	SYS_MMAP,
 	SYS_MREMAP,
Index: generic/include/userspace.h
===================================================================
--- generic/include/userspace.h	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ generic/include/userspace.h	(revision 9f525639659c979c952ae9372c881791de6d13aa)
@@ -30,7 +30,9 @@
 #define __USERSPACE_H__
 
+#include <proc/thread.h>
 #include <arch/types.h>
 
-extern void userspace(__address entry) __attribute__ ((noreturn)); /**< Switch to user-space (CPU user priviledge level) */
+/** Switch to user-space (CPU user priviledge level) */
+extern void userspace(uspace_arg_t *uarg) __attribute__ ((noreturn)); 
 
 #endif
Index: generic/src/main/uinit.c
===================================================================
--- generic/src/main/uinit.c	(revision 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ 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 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ 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 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ 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 5fceec785d6aac1ee91264d9b49d5b564cf108af)
+++ 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,
