diff --git a/kern/include/ec.h b/kern/include/ec.h
index ead1858..673e948 100644
--- a/kern/include/ec.h
+++ b/kern/include/ec.h
@@ -30,6 +30,8 @@ class Ec
     private:
         void        (*cont)();
         Exc_regs    regs;
+        Ec*         prev;
+        Ec*         next;
 
         REGPARM (1)
         static void handle_exc (Exc_regs *) asm ("exc_handler");
@@ -45,6 +47,8 @@ class Ec
         ALWAYS_INLINE
         inline Exc_regs *exc_regs() { return &regs; }
 
+        void enqueue();
+
     public:
         static Ec * current;
 
@@ -77,6 +81,10 @@ class Ec
 
         NORETURN
         static void sys_dump();
+        NORETURN
+        static void sys_create_ec();
+        NORETURN
+        static void sys_yield();
 
         ALWAYS_INLINE
         static inline void *operator new (size_t) { return Kalloc::allocator.alloc(sizeof (Ec)); }
diff --git a/kern/src/ec.cc b/kern/src/ec.cc
index e6217f0..eec31b9 100644
--- a/kern/src/ec.cc
+++ b/kern/src/ec.cc
@@ -35,6 +35,7 @@ Ec::Ec (void (*f)(), mword mbi) : cont (f)
     regs.es  = SEL_USER_DATA;
     regs.ss  = SEL_USER_DATA;
     regs.efl = 0x200;           // IF = 1
+    enqueue();
 }
 
 // only used by syscall create thread (EC+SC)
@@ -48,6 +49,21 @@ Ec::Ec (mword eip, mword esp)
     regs.efl = 0x200;           // IF = 1
     regs.eip = eip;
     regs.esp = esp;
+    enqueue();
+}
+
+void Ec::enqueue()
+{
+    if(current) {
+        current->next->prev = this;
+        next = current->next;
+        current->next = this;
+        prev = current;
+    }
+    else {
+        next = this;
+        prev = this;
+    }
 }
 
 void Ec::ret_user_sysexit()
@@ -142,6 +158,14 @@ void Ec::syscall_handler (uint8 n)
         sys_dump();
         break;
 
+    case 1:
+        sys_yield();
+        break;
+
+    case 2:
+        sys_create_ec();
+        break;
+
     default:
         printf ("syscall %d - unknown\n", n);
         break;
@@ -159,6 +183,25 @@ void Ec::sys_dump()
     ret_user_sysexit();
 }
 
+void Ec::sys_create_ec()
+{
+    auto regs = current->sys_regs();
+
+    printf ("EC:%p SYS_CREATE_EC : %#lx, %#lx\n", current, regs->esi, regs->edi);
+
+    new Ec(regs->esi, regs->edi);
+
+    ret_user_sysexit();
+}
+
+void Ec::sys_yield()
+{
+    printf ("EC:%p SYS_YIELD -> %p\n", current, current->next);
+
+    current->cont = ret_user_sysexit;
+    current->next->make_current();
+}
+
 bool Ec::handle_exc_ts (Exc_regs *r)
 {
     if (r->user())
diff --git a/user/src/linker.ld b/user/src/linker.ld
index 1cc43d3..3d6e271 100644
--- a/user/src/linker.ld
+++ b/user/src/linker.ld
@@ -12,7 +12,7 @@ SECTIONS
 {
     . =  0x1000 + SIZEOF_HEADERS;
 
-    .data  :
+    .data : ALIGN(0x1000)
     {
         BYTE(42);
         . = ALIGN(0x1000);
@@ -22,7 +22,7 @@ SECTIONS
         *(.bss);
     } : data
 
-    .text :
+    .text : ALIGN(0x1000)
     {
         . = ALIGN(0x1000);
         *(.text);
diff --git a/user/src/user.cc b/user/src/user.cc
index 238e4cf..20b340d 100644
--- a/user/src/user.cc
+++ b/user/src/user.cc
@@ -23,14 +23,44 @@ unsigned syscall2 (unsigned w0, unsigned w1)
     return w0;
 }
 
+unsigned syscall3 (unsigned w0, unsigned w1, unsigned w2)
+{
+    asm volatile (
+        "   mov %%esp, %%ecx    ;"
+        "   mov $1f, %%edx      ;"
+        "   sysenter            ;"
+        "1:                     ;"
+        : "+a" (w0) : "S" (w1), "D" (w2) : "ecx", "edx");
+    return w0;
+}
+
 // example syscall for yielding
 unsigned sys_yield()
 {
-    return syscall1 (0xdeadbeaf /* TODO use correct syscall number*/);
+    return syscall1 (1);
+}
+
+unsigned sys_create_ec(void (*func)(), void *stack)
+{
+    return syscall3 (2, reinterpret_cast<unsigned>(func),
+                        reinterpret_cast<unsigned>(stack));
+}
+
+static void my_thread() {
+    while(1)
+        sys_yield();
 }
 
 EXTERN_C NORETURN
 void main_func ()
 {
-    while (1) ;
+    unsigned stack1[128];
+    sys_create_ec(my_thread, stack1 + sizeof(stack1));
+    unsigned stack2[128];
+    sys_create_ec(my_thread, stack2 + sizeof(stack2));
+    unsigned stack3[128];
+    sys_create_ec(my_thread, stack3 + sizeof(stack3));
+
+    while (1)
+        sys_yield();
 }
