diff --git a/include/Cpu.h b/include/Cpu.h
index 65d0e91b9d0107cc67e62028e326bcfe0c80666d..6fdac1dcbbaa35b6246901265a224068e1eea7a3 100644
--- a/include/Cpu.h
+++ b/include/Cpu.h
@@ -6,8 +6,6 @@ struct Cpu {
     int lastInterruptEnable; //were interrupts enabled before disable interrupt
 };
 
-#define CPU_NUM 5
-
 struct Cpu* myCpu();
 
 #endif
\ No newline at end of file
diff --git a/include/Hart.h b/include/Hart.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a3f69b1de99dc56dac655e5bac81d14a4dde6ca
--- /dev/null
+++ b/include/Hart.h
@@ -0,0 +1,14 @@
+#ifndef _HART_H_
+#define _HART_H_
+#include "Process.h"
+
+struct Hart {
+    int interruptLayer; //depth of disable interrupt
+    int lastInterruptEnable; //were interrupts enabled before disable interrupt
+};
+
+struct Hart* myHart(void);
+Trapframe* getHartTrapFrame(void);
+u64 getHartKernelTopSp();
+
+#endif
\ No newline at end of file
diff --git a/include/MemoryConfig.h b/include/MemoryConfig.h
index fe1c3970e8ba4b18aa084a5c6791ab579bdb629c..c28ff0dd65319892a3b1646be747f77da620025c 100644
--- a/include/MemoryConfig.h
+++ b/include/MemoryConfig.h
@@ -36,7 +36,7 @@
 #define PHYSICAL_PAGE_NUM (PHYSICAL_MEMORY_SIZE >> PAGE_SHIFT)
 
 #define KERNEL_ADDRESS_TOP (1L << 38)
-#define TRAMPOLINE_BASE (KERNEL_ADDRESS_TOP - PAGE_SIZE)
+#define TRAMPOLINE_BASE (KERNEL_ADDRESS_TOP - (PAGE_SIZE << 1))
 #define USER_STACK_TOP TRAMPOLINE_BASE
 
 #endif
\ No newline at end of file
diff --git a/include/Page.h b/include/Page.h
index 383c8e9cc4c4eb623eb6e3f65fd9832e1aeb2bb3..0c69a23bf8c45866e2782a7283c66c1ec3433dfa 100644
--- a/include/Page.h
+++ b/include/Page.h
@@ -42,8 +42,8 @@ inline PhysicalPage* pa2page(u64 pa) {
 
 void bcopy(void *src, void *dst, u32 len);
 void bzero(void *start, u32 len);
-void memoryInit(void);
-void startPage(void);
+void memoryInit();
+void startPage();
 
 #define PA2PPN(va) ((((u64)(va)) & 0x0fffffff) >> PAGE_SHIFT)
 #define PPN2PA(ppn) (((u64)(ppn)) << PAGE_SHIFT)
diff --git a/include/Sd.h b/include/Sd.h
index 96d07bb469a546f10c324a5040e5c83297b2f2ef..15c32eab45e70f7dfe940e29b39d131a8e3c75c9 100644
--- a/include/Sd.h
+++ b/include/Sd.h
@@ -6,5 +6,6 @@
 int sdInit(void);
 int sdRead(u8 *buf, u64 startSector, u32 sectorNumber);
 int sdWrite(u8 *buf, u64 startSector, u32 sectorNumber);
+int sdTest(void);
 
 #endif
\ No newline at end of file
diff --git a/include/Spinlock.h b/include/Spinlock.h
index 4d5caf3d707c566db78e500535e0e03b55fa0132..a68155f6a73d8d0baebec580331773d411bfe07d 100644
--- a/include/Spinlock.h
+++ b/include/Spinlock.h
@@ -1,6 +1,6 @@
 #ifndef __SPINLOCK_H
 #define __SPINLOCK_H
-#include "Cpu.h"
+#include "Hart.h"
 #include "Type.h"
 
 // Mutual exclusion lock.
@@ -9,7 +9,7 @@ struct Spinlock {
 
     // For debugging:
     char *name;        // Name of lock.
-    struct Cpu* cpu;   // The cpu holding the lock.
+    struct Hart* hart;   // The cpu holding the lock.
 };
 
 // Initialize a spinlock
diff --git a/include/Trap.h b/include/Trap.h
index 750de353283439763cb5a9e56853f63c5bb19621..43feef83c719d3067fc8e3dcd9d7154a3a3490e1 100644
--- a/include/Trap.h
+++ b/include/Trap.h
@@ -3,6 +3,7 @@
 
 #include <MemoryConfig.h>
 #include <Riscv.h>
+#include <Process.h>
 
 void trapInit();
 void kernelVector();
diff --git a/kernel/boot/QemuEntry.S b/kernel/boot/Entry.S
similarity index 88%
rename from kernel/boot/QemuEntry.S
rename to kernel/boot/Entry.S
index 4dea1417d695796135ec34bcb5acd31e49ab4b79..f8643ae30f9c91e215f2a219fa0745f1b18960d9 100644
--- a/kernel/boot/QemuEntry.S
+++ b/kernel/boot/Entry.S
@@ -4,6 +4,7 @@
     .globl _start
 _start:
     mv t0, a0
+    add t0, t0, 1
     slli t0, t0, 16
     la sp, kernelStack
     add sp, sp, t0
@@ -16,7 +17,7 @@ loop:
     .globl kernelStack
     .align 12
 kernelStack:
-    .space KERNEL_STACK_SIZE * 4
+    .space KERNEL_STACK_SIZE * 5
     .globl kernelStackTop
 kernelStackTop:
     
diff --git a/kernel/boot/Init.c b/kernel/boot/Init.c
index 850d5ab14162d4b2bf83ad4e9a2537ecc3e19a4e..1bc2d0d3a4ddb49fc4ee7dee901446e73a25e35d 100644
--- a/kernel/boot/Init.c
+++ b/kernel/boot/Init.c
@@ -6,13 +6,12 @@
 #include <Sd.h>
 
 volatile int mainCount = 1000;
+volatile int initFinish = 0;
 
 static inline void initHartId(u64 hartId) {
     asm volatile("mv tp, %0" : : "r" (hartId & 0x7));
 }
 
-//void ffff(int);
-u8 binary[1024];
 void main(u64 hartId) {
     initHartId(hartId);
 
@@ -30,60 +29,42 @@ void main(u64 hartId) {
         printf("Hello, risc-v!\nBoot hartId: %ld \n\n", hartId);
 
         memoryInit();
-        /*sdInit();
-        for (int j = 0; j < 10; j += 2) {
-            for (int i = 0; i < 1024; i++) {
-                binary[i] = i & 7;
-            }
-            sdWrite(binary, j, 2);
-            for (int i = 0; i < 1024; i++) {
-                binary[i] = 0;
-            }
-            sdRead(binary, j, 2);
-            for (int i = 0; i < 1024; i++) {
-                if (binary[i] != (i & 7)) {
-                    panic("gg: %d ", j);
-                    break;
-                }
-            }
-            printf("finish %d\n", j);
-        }*/
 
         for (int i = 1; i < 5; ++ i) {
             if (i != hartId) {
                 unsigned long mask = 1 << i;
                 setMode(i);
                 sbi_send_ipi(&mask);
-                /*int sum = 0;
-                for (int j = 0; j < 1e9; j++) {
-                    sum += j * j * j * j;
-                }*/
-                //printf("%d\n", sum);
             }
         }
-        //printf("end\n");
-        __sync_synchronize();
-        //printf("%d\n", mainCount);
-        //PROCESS_CREATE_PRIORITY(ForkTest, 1);
-
-        //yield();
 
-        /*printf("reach end\n");*/
-        mainCount++;
-        
         trapInit();
         processInit();
 
+        PROCESS_CREATE_PRIORITY(ProcessA, 2);
+        PROCESS_CREATE_PRIORITY(ProcessB, 3);
+        PROCESS_CREATE_PRIORITY(ProcessA, 5);
+
+
+        __sync_synchronize();     
+
+        initFinish = true;
+
+        //PROCESS_CREATE_PRIORITY(ForkTest, 1);
+
     } else {
+        while (initFinish == 0);
         __sync_synchronize();
+
         printf("Hello, risc-v!\nCurrent hartId: %ld \n\n", hartId);
-        mainCount++;
-        while (hartId != 4 || mainCount != 1005) {};
 
         startPage();
         trapInit();
 
-        PROCESS_CREATE_PRIORITY(ForkTest, 1);
-        yield();
+        //PROCESS_CREATE_PRIORITY(ForkTest, 1);
+        //PROCESS_CREATE_PRIORITY(ProcessB, 3);
+        //printf("Reach this place\n");
     }
+
+    yield();
 }
\ No newline at end of file
diff --git a/kernel/boot/Makefile b/kernel/boot/Makefile
index b8e289ecf672189c8213b19dd1ead70e8d228bce..c688fde103f817fdb43ffb92e5e741bb028e257d 100644
--- a/kernel/boot/Makefile
+++ b/kernel/boot/Makefile
@@ -1,6 +1,6 @@
 INCLUDES := -I../../include
 
-target = QemuEntry.o Init.o
+target = Entry.o Init.o
 
 .PHONY: build clean
 
diff --git a/kernel/driver/Print.c b/kernel/driver/Print.c
index 178b3d94f71873cccad6a67a9ec5f15809377d6f..ce89fa4935655ab3216087402d8e0bba451225be 100644
--- a/kernel/driver/Print.c
+++ b/kernel/driver/Print.c
@@ -106,9 +106,16 @@ void printf(const char *fmt, ...) {
     releaseLock(&printLock);
 }
 
+void panicPrintf(const char *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    print(fmt, ap);
+    va_end(ap);
+}
+
 void _panic_(const char *file, int line, const char *fmt, ...) {
     acquireLock(&printLock);
-    printf("panic at %s: %d: ", file, line);
+    panicPrintf("hartId %d panic at %s: %d: ", r_hartid(), file, line);
     va_list ap;
     va_start(ap, fmt);
     print(fmt, ap);
diff --git a/kernel/driver/sd.c b/kernel/driver/sd.c
index 74f5c11eaf5991f1a6fb244123fb20839d947ad4..c9b06a596008770c7993f6518bf750cb074ceb32 100755
--- a/kernel/driver/sd.c
+++ b/kernel/driver/sd.c
@@ -284,3 +284,26 @@ int sdInit(void) {
 	__asm__ __volatile__ ("fence.i" : : : "memory");
 	return 0;
 }
+
+u8 binary[1024];
+int sdTest(void) {
+	sdInit();
+    for (int j = 0; j < 10; j += 2) {
+        for (int i = 0; i < 1024; i++) {
+            binary[i] = i & 7;
+        }
+        sdWrite(binary, j, 2);
+        for (int i = 0; i < 1024; i++) {
+            binary[i] = 0;
+        }
+        sdRead(binary, j, 2);
+        for (int i = 0; i < 1024; i++) {
+            if (binary[i] != (i & 7)) {
+                panic("gg: %d ", j);
+                break;
+            }
+        }
+        printf("finish %d\n", j);
+    }
+	return 0;
+}
\ No newline at end of file
diff --git a/kernel/lock/Interrput.c b/kernel/lock/Interrput.c
index ff5789377dd9428074174a31322dee428ce33816..905c0d019096e4d8fd530f96544756531840221e 100644
--- a/kernel/lock/Interrput.c
+++ b/kernel/lock/Interrput.c
@@ -1,29 +1,29 @@
 #include "Interrupt.h"
 #include "Riscv.h"
-#include "Cpu.h"
+#include "Hart.h"
 #include "Driver.h"
 
 void interruptPush(void) {
     int oldInterruptEnable = intr_get();
     intr_off();
 
-    struct Cpu* cpu = myCpu();
-    if (cpu->interruptLayer == 0)
-        cpu->lastInterruptEnable = oldInterruptEnable;
-    cpu->interruptLayer++;
+    struct Hart* hart = myHart();
+    if (hart->interruptLayer == 0)
+        hart->lastInterruptEnable = oldInterruptEnable;
+    hart->interruptLayer++;
 }
 
 void interruptPop(void) {
-    struct Cpu* cpu = myCpu();
+    struct Hart* hart = myHart();
     if (intr_get()) {
         panic("Interrupt bit still have!\n");
     }
 
-    if (cpu->interruptLayer < 0) {
+    if (hart->interruptLayer < 0) {
         panic("Interrupt close error! Not match!\n");
     }
 
-    cpu->interruptLayer--;
-    if (cpu->interruptLayer == 0 && cpu->lastInterruptEnable)
+    hart->interruptLayer--;
+    if (hart->interruptLayer == 0 && hart->lastInterruptEnable)
         intr_on();
 }
\ No newline at end of file
diff --git a/kernel/lock/Spinlock.c b/kernel/lock/Spinlock.c
index df6f501c6036b4987b8a097ccd5dacacdaf91a9b..8a1303c25353d9110f8c21a9a56ee750fb3d5cc1 100644
--- a/kernel/lock/Spinlock.c
+++ b/kernel/lock/Spinlock.c
@@ -1,18 +1,18 @@
 #include "Spinlock.h"
-#include "Cpu.h"
+#include "Hart.h"
 #include "Interrupt.h"
 #include "Driver.h"
 
 void initLock(struct Spinlock* lock, char* name) {
     lock->name = name;
     lock->locked = 0;
-    lock->cpu = 0;
+    lock->hart = 0;
 }
 
 void acquireLock(struct Spinlock* lock) {
     interruptPush();
     if (holding(lock)) {
-        panic("You have acquire the lock!\n");
+        panic("You have acquire the lock! The lock is %s\n", lock->name);
     }
 
     // On RISC-V, sync_lock_test_and_set turns into an atomic swap:
@@ -27,15 +27,15 @@ void acquireLock(struct Spinlock* lock) {
     // On RISC-V, this emits a fence instruction.
     __sync_synchronize();
 
-    lock->cpu = myCpu();
+    lock->hart = myHart();
 }
 
 void releaseLock(struct Spinlock* lock) {
     if (!holding(lock)) {
-        panic("You have release the lock!\n");
+        panic("You have release the lock! The lock is %s\n", lock->name);
     }
 
-    lock->cpu = 0;
+    lock->hart = 0;
 
     __sync_synchronize();
 
@@ -47,12 +47,11 @@ void releaseLock(struct Spinlock* lock) {
     //   s1 = &lk->locked
     //   amoswap.w zero, zero, (s1)
     __sync_lock_release(&lock->locked);
-
     interruptPop();
 }
 
 int holding(struct Spinlock* lock) {
     int r;
-    r = (lock->locked && lock->cpu == myCpu());
+    r = (lock->locked && lock->hart == myHart());
     return r;
 }
\ No newline at end of file
diff --git a/kernel/memory/MemoryInit.c b/kernel/memory/MemoryInit.c
index dc85ae1c507a45f2ef88e66f5e7a1411c295e5fd..f2af70ee2ddcff761daab18ad7befff4b0cb03e5 100644
--- a/kernel/memory/MemoryInit.c
+++ b/kernel/memory/MemoryInit.c
@@ -3,6 +3,7 @@
 #include <MemoryConfig.h>
 #include <Riscv.h>
 #include <Platform.h>
+#include <Process.h>
 
 PageList freePages;
 PhysicalPage pages[PHYSICAL_PAGE_NUM];
diff --git a/kernel/system/Cpu.c b/kernel/system/Cpu.c
deleted file mode 100644
index 715023ee8ae4e8f73464ee2b9312c3a84f2d3c71..0000000000000000000000000000000000000000
--- a/kernel/system/Cpu.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "Cpu.h"
-#include "Riscv.h"
-
-struct Cpu cpus[CPU_NUM];
-
-inline struct Cpu* myCpu() {
-    int r = r_hartid();
-    return &cpus[r];
-}
\ No newline at end of file
diff --git a/kernel/system/Hart.c b/kernel/system/Hart.c
new file mode 100644
index 0000000000000000000000000000000000000000..6dae43b9dda23d31a9e256d822cd93bb3296e843
--- /dev/null
+++ b/kernel/system/Hart.c
@@ -0,0 +1,21 @@
+#include "Hart.h"
+#include "Riscv.h"
+#include "Process.h"
+#include "MemoryConfig.h"
+
+struct Hart harts[HART_TOTAL_NUMBER];
+
+inline struct Hart* myHart() {
+    int r = r_hartid();
+    return &harts[r];
+}
+
+Trapframe* getHartTrapFrame() {
+    extern Trapframe trapframe[];
+    return (Trapframe*)((u64)trapframe + r_hartid() * sizeof(Trapframe)); 
+}
+
+u64 getHartKernelTopSp() {
+    extern char kernelStack[];
+    return (u64)kernelStack + KERNEL_STACK_SIZE * (r_hartid() + 1);
+}
\ No newline at end of file
diff --git a/kernel/system/Makefile b/kernel/system/Makefile
index a1b00c219b6f32544b32b7691fb433812668c64a..06a3d281d8f1886b2183ac8f0df13c9ea5e62f0f 100644
--- a/kernel/system/Makefile
+++ b/kernel/system/Makefile
@@ -1,6 +1,6 @@
 INCLUDES := -I../../include
 
-target = Cpu.o
+target = Hart.o
 
 .PHONY: build clean
 
diff --git a/kernel/trap/Process.c b/kernel/trap/Process.c
index 469038e879724e1c2c451bd0f653d6254cc1d776..b60a11b24ba0599a99ac81effd83e7d1fa49d884 100644
--- a/kernel/trap/Process.c
+++ b/kernel/trap/Process.c
@@ -4,15 +4,22 @@
 #include <Elf.h>
 #include <Riscv.h>
 #include <Trap.h>
+#include <Spinlock.h>
 
 Process processes[PROCESS_TOTAL_NUMBER];
 static struct ProcessList freeProcesses;
 struct ProcessList scheduleList[2];
 Process *currentProcess[HART_TOTAL_NUMBER] = {0, 0, 0, 0, 0};
 
-extern Trapframe trapframe[];
+struct Spinlock freeProcessesLock, scheduleListLock;
+
+
 void processInit() {
     printf("Process init start...\n");
+    
+    initLock(&freeProcessesLock, "freeProcess");
+    initLock(&scheduleListLock, "scheduleList");
+    
     LIST_INIT(&freeProcesses);
     LIST_INIT(&scheduleList[0]);
     LIST_INIT(&scheduleList[1]);
@@ -23,7 +30,7 @@ void processInit() {
         processes[i].trapframe.kernelSatp = MAKE_SATP(kernelPageDirectory);
         LIST_INSERT_HEAD(&freeProcesses, &processes[i], link);
     }
-    w_sscratch((u64) trapframe);
+    w_sscratch((u64)getHartTrapFrame());
     printf("Process init finish!\n");
 }
 
@@ -48,18 +55,23 @@ static int setup(Process *p) {
     extern char trampoline[];
     pageInsert(p->pgdir, TRAMPOLINE_BASE, (u64)trampoline, 
         PTE_READ | PTE_WRITE | PTE_EXECUTE);
+    pageInsert(p->pgdir, TRAMPOLINE_BASE + PAGE_SIZE, ((u64)trampoline) + PAGE_SIZE, 
+        PTE_READ | PTE_WRITE | PTE_EXECUTE);
     return 0;
 }
 
 int processAlloc(Process **new, u64 parentId) {
     int r;
     Process *p;
+    acquireLock(&freeProcessesLock);
     if (LIST_EMPTY(&freeProcesses)) {
+        releaseLock(&freeProcessesLock);
         *new = NULL;
         return -NO_FREE_PROCESS;
     }
     p = LIST_FIRST(&freeProcesses);
     LIST_REMOVE(p, link);
+    releaseLock(&freeProcessesLock);
     if ((r = setup(p)) < 0) {
         return r;
     }
@@ -67,8 +79,7 @@ int processAlloc(Process **new, u64 parentId) {
     p->id = generateProcessId(p);
     p->state = RUNNABLE;
     p->parentId = parentId;
-    extern char kernelStack[];
-    p->trapframe.kernelSp = (u64)kernelStack + KERNEL_STACK_SIZE;
+    p->trapframe.kernelSp = getHartKernelTopSp();
     p->trapframe.sp = USER_STACK_TOP;
 
     *new = p;
@@ -132,7 +143,6 @@ int codeMapper(u64 va, u32 segmentSize, u8 *binary, u32 binSize, void *userData)
 
 void processCreatePriority(u8 *binary, u32 size, u32 priority) {
     Process *p;
-
     int r = processAlloc(&p, 0);
     if (r < 0) {
         return;
@@ -144,15 +154,19 @@ void processCreatePriority(u8 *binary, u32 size, u32 priority) {
     }
     p->trapframe.epc = entryPoint;
 
+    acquireLock(&scheduleListLock);
     LIST_INSERT_TAIL(&scheduleList[0], p, scheduleLink);
+    releaseLock(&scheduleListLock);
 }
 
 void processRun(Process *p) {
     int hartId = r_hartid();
+    Trapframe* trapframe = getHartTrapFrame();
     if (currentProcess[hartId]) {
         bcopy(trapframe, &(currentProcess[hartId]->trapframe), sizeof(Trapframe));
     }
     currentProcess[hartId] = p;
+    p->state = RUNNING;
     bcopy(&(currentProcess[hartId]->trapframe), trapframe, sizeof(Trapframe));
     userTrapReturn();
 }
@@ -162,10 +176,16 @@ void wakeup(void *channel) {
 }
 
 void yield() {
+    int r = r_hartid();
+    printf("hartid in yield: %d\n", r);
     static int count = 0;
     static int point = 0;
     int hartId = r_hartid();
+    acquireLock(&scheduleListLock);
     Process* next_env = currentProcess[hartId];
+    if (next_env && next_env->state == RUNNING) {
+        next_env->state = RUNNABLE;
+    }
     while ((count == 0) || (next_env == NULL) || (next_env->state != RUNNABLE)) {
         if (next_env != NULL) {
             LIST_INSERT_TAIL(&scheduleList[point ^ 1], next_env, scheduleLink);
@@ -174,14 +194,16 @@ void yield() {
             point = 1 - point;
         }
         if (LIST_EMPTY(&scheduleList[point])) {
+            releaseLock(&scheduleListLock);
             panic("No Env is RUNNABLE\n");
         }
         next_env = LIST_FIRST(&scheduleList[point]);
         LIST_REMOVE(next_env, scheduleLink);
         count = next_env->priority;
     }
+    releaseLock(&scheduleListLock);
     count--;
-    printf("\nyield %d\n", next_env->id);
+    printf("hartID %d yield process %d\n", hartId, next_env->id);
     processRun(next_env);
 }
 
@@ -195,11 +217,15 @@ void processFork() {
         return;
     }
     process->priority = currentProcess[hartId]->priority;
+    Trapframe* trapframe = getHartTrapFrame();
     bcopy(trapframe, &process->trapframe, sizeof(Trapframe));
     process->trapframe.a0 = 0;
+    
+    acquireLock(&scheduleListLock);
     LIST_INSERT_TAIL(&scheduleList[0], process, scheduleLink);
-    trapframe->a0 = process->id;
+    releaseLock(&scheduleListLock);
 
+    trapframe->a0 = process->id;
     u64 i, j, k;
     for (i = 0; i < 512; i++) {
         if (!(currentProcess[hartId]->pgdir[i] & PTE_VALID)) {
@@ -216,9 +242,12 @@ void processFork() {
                     continue;
                 }
                 u64 va = (i << 30) + (j << 21) + (k << 12);
-                if (va == TRAMPOLINE_BASE) {
+                if (va == TRAMPOLINE_BASE || va == TRAMPOLINE_BASE + PAGE_SIZE) {
                     continue;
                 }
+                // if (va == TRAMPOLINE_BASE) {
+                //     continue;
+                // }
                 if (pa2[k] & PTE_WRITE) {
                     pa2[k] |= PTE_COW;
                     pa2[k] &= ~PTE_WRITE;
diff --git a/kernel/trap/Syscall.c b/kernel/trap/Syscall.c
index 252edb0a0278813926eff527e56bdae2ce12d511..3258081391fdb9697fb9563783adca408a6e9c18 100644
--- a/kernel/trap/Syscall.c
+++ b/kernel/trap/Syscall.c
@@ -4,6 +4,8 @@
 #include <Type.h>
 #include <Page.h>
 #include <Riscv.h>
+#include <Trap.h>
+#include <Spinlock.h>
 
 void (*syscallVector[])(void) = {
     [SYSCALL_PUTCHAR]           syscallPutchar,
@@ -13,9 +15,13 @@ void (*syscallVector[])(void) = {
     [SYSCALL_PUT_STRING]        syscallPutString
 };
 
-extern Trapframe trapframe[];
+extern struct Spinlock printLock;
+
 void syscallPutchar() {
+    Trapframe* trapframe = getHartTrapFrame();
+    acquireLock(&printLock);
     putchar(trapframe->a0);
+    releaseLock(&printLock);
 }
 
 void syscallGetProcessId() {
@@ -31,6 +37,7 @@ void syscallFork() {
 }
 
 void syscallPutString() {
+    Trapframe* trapframe = getHartTrapFrame();
     u64 va = trapframe->a0;
     int len = trapframe->a1;
     extern Process *currentProcess[HART_TOTAL_NUMBER];
@@ -41,8 +48,10 @@ void syscallPutString() {
         panic("Syscall put string address error!\nThe virtual address is %x, the length is %x\n", va, len);
     }
     char* start = (char*) pa;
+    acquireLock(&printLock);
     while (len--) {
         putchar(*start);
         start++;
     }
+    releaseLock(&printLock);
 }
\ No newline at end of file
diff --git a/kernel/trap/Trampoline.S b/kernel/trap/Trampoline.S
index be36a262857642e455712762fb1304310bcb920f..08d1747d6f32839b25bde4ee052b7b624de62c35 100644
--- a/kernel/trap/Trampoline.S
+++ b/kernel/trap/Trampoline.S
@@ -11,6 +11,7 @@
         #
 	.section .trampoline
     .globl trampoline
+    .align 12
 trampoline:
     .align 4
     .globl userVector
@@ -140,5 +141,6 @@ userReturn:
     sret
 
     .globl trapframe
+    .align 12
 trapframe:
-    .space 1200
+    .space 4096
diff --git a/kernel/trap/Trap.c b/kernel/trap/Trap.c
index 5471813653469e002897eba23317a1aaa3a12e2b..656442b3f819b6c5efb157f13b12d878d78f344e 100644
--- a/kernel/trap/Trap.c
+++ b/kernel/trap/Trap.c
@@ -5,6 +5,7 @@
 #include <Process.h>
 #include <Page.h>
 #include <Syscall.h>
+#include <Hart.h>
 
 void trapInit() {
     printf("Trap init start...\n");
@@ -53,7 +54,7 @@ int trapDevice() {
 }
 
 void kernelTrap() {
-    //printf("kernel trap\n");
+    printf("kernel trap\n");
     u64 sepc = r_sepc();
     u64 sstatus = r_sstatus();
 
@@ -88,7 +89,7 @@ void userTrap() {
     int hartId = r_hartid();
 
     u64 scause = r_scause();
-    extern Trapframe trapframe[];
+    Trapframe* trapframe = getHartTrapFrame();
     if (scause & SCAUSE_INTERRUPT) {
         trapDevice();
         yield();
@@ -126,10 +127,9 @@ void userTrapReturn() {
     int hartId = r_hartid();
 
     extern Process *currentProcess[HART_TOTAL_NUMBER];
-    extern char kernelStack[];
-    extern Trapframe trapframe[];
+    Trapframe* trapframe = getHartTrapFrame();
 
-    trapframe->kernelSp = (u64)kernelStack + KERNEL_STACK_SIZE;
+    trapframe->kernelSp = getHartKernelTopSp();
     trapframe->trapHandler = (u64)userTrap;
     trapframe->kernelHartId = r_tp();
 
diff --git a/linkscript/Qemu.ld b/linkscript/Qemu.ld
index b0e44b7f05430dcf4b00160d75aa45cdb92dfc9f..c49716da0f0bc73ed80666ae83526b6a958b8148 100644
--- a/linkscript/Qemu.ld
+++ b/linkscript/Qemu.ld
@@ -17,7 +17,7 @@ SECTIONS {
         _trampoline = .;
         *(.trampoline)
         . = ALIGN(4096);
-        ASSERT(. - _trampoline == 4096, "error: trampoline larger than one page");
+        ASSERT(. - _trampoline == 8192, "error: trampoline not have two page");
         PROVIDE(textEnd = .);
     }
 
diff --git a/user/ProcessA.c b/user/ProcessA.c
index 49b986dff913bba11f9e07c952068b3e30589239..71bf2c0fc6ce939dd428236c295df0eb29561ca7 100644
--- a/user/ProcessA.c
+++ b/user/ProcessA.c
@@ -1,7 +1,9 @@
 #include <Syscall.h>
+#include <Printf.h>
 
 void userMain() {
-    while (1) {
+    for (int i = 1; i <= 100000000; ++ i) {
+        //uPrintf("This is process A\n");
         syscallPutchar('a');
     }   
 }
\ No newline at end of file
diff --git a/user/ProcessB.c b/user/ProcessB.c
index aaf5e089edefd143c98259e01ba06d9cee76134a..7ef3022a82d8e06cda0bf7edbb938e7cc3f5e302 100644
--- a/user/ProcessB.c
+++ b/user/ProcessB.c
@@ -1,7 +1,9 @@
 #include <Syscall.h>
+#include <Printf.h>
 
 void userMain() {
-    while (1) {
+    for (int i = 1; i <= 100000000; ++ i) {
+        //uPrintf("This is process B\n");
         syscallPutchar('b');
     }   
 }
\ No newline at end of file