diff --git a/.clang-format b/.clang-format
index fe894e980847c0f3d02a12810ede23c8da586f9d..738b35547cd682c6775ec2e219500f63c9fc4822 100644
--- a/.clang-format
+++ b/.clang-format
@@ -12,10 +12,11 @@ AlignTrailingComments: true
 AllowAllArgumentsOnNextLine: true
 AllowAllConstructorInitializersOnNextLine: true
 AllowAllParametersOfDeclarationOnNextLine: true
-AllowShortBlocksOnASingleLine: Never
+AllowShortBlocksOnASingleLine: Empty
 AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: All
-AllowShortLambdasOnASingleLine: All
+AllowShortEnumsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortLambdasOnASingleLine: None
 AllowShortIfStatementsOnASingleLine: Never
 AllowShortLoopsOnASingleLine: false
 AlwaysBreakAfterDefinitionReturnType: None
@@ -84,6 +85,7 @@ IndentGotoLabels: true
 IndentPPDirectives: None
 IndentWidth:     4
 IndentWrappedFunctionNames: false
+InsertBraces: true
 JavaScriptQuotes: Leave
 JavaScriptWrapImports: true
 KeepEmptyLinesAtTheStartOfBlocks: true
diff --git a/.gitignore b/.gitignore
index b1d35f9e4a7e8f2106e5ac28a9c2578d014f5e13..798579adcad77570b3f973f66b1b1825790015ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
 !Makefile
 !Makefile.in
 !Dockerfile
+!compile_commands.json
 
 !*.S
 !*.s
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/Makefile b/Makefile
index d5ffdfba87f0f2f7d61b165d633655f9403f76ff..26c98d26ef80e83caec009b42a53d979b6572897 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,8 @@ dst				:= /mnt
 fs_img			:= sdcard.img
 
 modules := $(src_dir)
-objects := $(shell find $(src_dir) -name "*.o")
+sources := $(shell find $(src_dir) \( -name "*.S" -o -name "*.c" \))
+objects := $(patsubst %.S,%.o, $(patsubst %.c,%.o, $(sources)))
 
 .PHONY: build clean $(modules) run
 GDB := n
@@ -21,7 +22,7 @@ ifeq ($(MAKECMDGOALS), gdb)
 	GDB = y
 endif
 
-all : clean build
+all: clean build
 
 build: $(modules)
 	mkdir -p $(target_dir)
diff --git a/compile_commands.json b/compile_commands.json
new file mode 100644
index 0000000000000000000000000000000000000000..3e32e9e3f328e3e210ed5662a603ce3703590d97
--- /dev/null
+++ b/compile_commands.json
@@ -0,0 +1,694 @@
+[
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../../include",
+   "-I../../include",
+   "-c",
+   "exception.S"
+  ],
+  "file": "exception.S"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../../include",
+   "-I../../include",
+   "-c",
+   "head.S"
+  ],
+  "file": "head.S"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../../include",
+   "-I../../include",
+   "-c",
+   "stack.c"
+  ],
+  "file": "stack.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/init",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../../include",
+   "-I../../include",
+   "-c",
+   "vm.c"
+  ],
+  "file": "vm.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/sys",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../../include",
+   "-I../../include",
+   "-c",
+   "context.S"
+  ],
+  "file": "context.S"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/kernel/sys",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../../include",
+   "-I../../include",
+   "-c",
+   "smp.S"
+  ],
+  "file": "smp.S"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/sbi",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../include",
+   "-I../include",
+   "-c",
+   "common.c"
+  ],
+  "file": "common.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/arch/riscv/syscall",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../../include",
+   "-I../include",
+   "-c",
+   "syscall.c"
+  ],
+  "file": "syscall.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/drivers",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I..",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-c",
+   "screen.c"
+  ],
+  "file": "screen.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/fs",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "fs.c"
+  ],
+  "file": "fs.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/init",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "main.c"
+  ],
+  "file": "main.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/init",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "vm.c"
+  ],
+  "file": "vm.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/irq",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "irq.c"
+  ],
+  "file": "irq.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/mm",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "ioremap.c"
+  ],
+  "file": "ioremap.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/mm",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "mm.c"
+  ],
+  "file": "mm.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sync",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "lock.c"
+  ],
+  "file": "lock.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sync",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "sync.c"
+  ],
+  "file": "sync.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "info.c"
+  ],
+  "file": "info.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "pcb.c"
+  ],
+  "file": "pcb.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "smp.c"
+  ],
+  "file": "smp.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/kernel/sys",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../../include",
+   "-I../../arch/riscv/include",
+   "-I../../",
+   "-c",
+   "time.c"
+  ],
+  "file": "time.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/libs",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "printk.c"
+  ],
+  "file": "printk.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/libs",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "string.c"
+  ],
+  "file": "string.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/user",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "payload.c"
+  ],
+  "file": "payload.c"
+ },
+ {
+  "directory": "/home/bluespace/study/OS/OSKernel2023-550W/src/user",
+  "arguments": [
+   "riscv64-unknown-elf-gcc",
+   "-Wall",
+   "-Werror",
+   "-O",
+   "-fno-omit-frame-pointer",
+   "-ggdb",
+   "-g",
+   "-march=rv64g",
+   "-mabi=lp64f",
+   "-MD",
+   "-mcmodel=medany",
+   "-ffreestanding",
+   "-fno-common",
+   "-nostdlib",
+   "-mno-relax",
+   "-I.",
+   "-fno-stack-protector",
+   "-I../include",
+   "-I../arch/riscv/include",
+   "-I../",
+   "-c",
+   "user_programs.c"
+  ],
+  "file": "user_programs.c"
+ }
+]
diff --git a/docs/development.md b/docs/development.md
index c1bc6bc4ac2ef831257d1aaced5696b2f2643d96..ca1bfe6472b495bc1f80c888a2aa7ddb3775e93b 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -8,7 +8,7 @@
 
 源文件命名采用lower_case_with_underscores
 
-开发完成后一定要在使用`./script/format.sh`来格式化代码(注意不要用clang format格式化`.h, .S`的代码),本项目coding style基于llvm clang-format做了一些调整。
+开发完成后一定要在使用`./script/format.sh`来格式化代码(注意不要用clang format格式化`.h, .S`的代码),本项目coding style基于llvm clang-format做了一些调整。注意使用`clang-format 15`以上的版本,可以按照`./script/setup.sh`运行。
 
 全局变量头文件里都用`extern`,在`.c`中定义;其余需要共享的`#define`直接写,不用前缀;类型声明、函数等只能声明一次,在其余头文件中使用`extern`。
 
@@ -32,7 +32,7 @@
 - `typedef`
 - `typedef struct`
 - `extern`
-- 函数按照依赖次序排列,同类函数放在一起
+- 函数按照依赖次序排列,同类函数放在一起,`.c`文件的实现中函数与头文件中函数顺序一致
 
 系统调用全部使用`sys_`开头lower_case_with_underscores,系统调用号使用`SYS_`后面是lower_case_with_underscores。系统调用在各个子模块头文件中实现,而后将头文件加入./src/os/syscall.h。
 
@@ -53,12 +53,20 @@ func_name_out:
 }
 ```
 
+函数命名模板:
+
+- 系统调用全部使用`long sys_xxx(args)`的命名形式,开始一定要进行参数检查,指针一定是用户地址空间。
+- 内核内互相调用的函数,即在头文件中像内核其他模块暴露的函数全部以`k_`开头,效率起见可不做参数检查,参数可兼容用户态和内核态地址。
+- 其余函数不要放在头文件中,在函数内定义,使用`static`保证安全,开头不能是`k_`和`sys_`
+
+函数实现中尽量提取多个类似函数的共同操作组成`static`函数公用,减少代码量。
+
+内核中共享的变量和类型定义最好也使用`k_`开头定义,如果函数有枚举作用的参数只在内核态范围交换则使用`enum`,如果是用户态传入则使用其他`int`或`long`类型。
+
 ## 编译
 
 使用`./script/build.sh`来编译
 
-有时候需要重复运行两次,因为文件只能一次采样,不好动态赋值给Makefile变量
-
 ## 运行QEMU
 
 使用`./script/qemu_run.sh`来运行
diff --git a/kernel-qemu b/kernel-qemu
index dbeddc76352fa33314cbee6b99d30758e99a5820..0889007e912ba1e8d88651387209e63a443d5e40 100755
--- a/kernel-qemu
+++ b/kernel-qemu
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:04166f8722a87c2749cbb25f9a7f2c46f03867f88726245214756c92263abfc1
-size 1502872
+oid sha256:236f6d777344e58eca173840c83333e5f4242545faf95447760a4f75d7a777a9
+size 1539688
diff --git a/scripts/format.sh b/scripts/format.sh
index d4dc099373e91d1c4d26e784b946ac1cb5e35323..34b8afccc2a413454b695579d142874c1e2ac838 100755
--- a/scripts/format.sh
+++ b/scripts/format.sh
@@ -1 +1 @@
-find src -regex '.*\.\(cpp\|hpp\|cu\|c\)' -exec clang-format -style=file -i {} \;
\ No newline at end of file
+find src -regex '.*\.\(cpp\|hpp\|cu\|c\)' -exec clang-format-17 -style=file -i {} \;
\ No newline at end of file
diff --git a/scripts/setup.sh b/scripts/setup.sh
index 15e17b0412d1619f192df0cfb88273de0e052c48..687ffa5a7d9877283659a58fda3cb41d17ecb218 100644
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -21,9 +21,11 @@ echo "REPO = $REPO"
 echo "RISCV_DIR = $RISCV_DIR"
 echo "QEMU_DIR = $QEMU_DIR"
 echo "=== Install dependencies ==="
+wget https://apt.llvm.org/llvm-snapshot.gpg.key
 if [[ "$use_sudo_opt" = "y" ]]
 then
-    sudo apt update && \
+    sudo apt-key add llvm-snapshot.gpg.key
+    sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal main'
     sudo apt install -y apt-transport-https ca-certificates && \
     sudo update-ca-certificates
     sudo sed -i s@/archive.ubuntu.com/@/mirrors.tuna.tsinghua.edu.cn/@g /etc/apt/sources.list
@@ -33,14 +35,15 @@ then
         gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \
         libpixman-1-0 git python3 python3-pip make curl \
         sshpass openssh-client clang-10 libtinfo5 libc6-dev-i386 \
-        libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev
+        libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev clang-format-17
     curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
     sudo apt-get install git-lfs
     git lfs install
     pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
     pip3 install pytz Cython jwt jinja2 requests
 else
-    apt update && \
+    sudo apt-key add llvm-snapshot.gpg.key
+    sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal main'
     apt install -y apt-transport-https ca-certificates && \
     update-ca-certificates
     sed -i s@/archive.ubuntu.com/@/mirrors.tuna.tsinghua.edu.cn/@g /etc/apt/sources.list
@@ -50,13 +53,14 @@ else
         gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \
         libpixman-1-0 git python3 python3-pip make curl \
         sshpass openssh-client clang-10 libtinfo5 libc6-dev-i386 \
-        libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev
+        libncurses5 libpython2.7 libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev clang-format-17
     curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
     apt-get install git-lfs
     git lfs install
     pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
     pip3 install pytz Cython jwt jinja2 requests
 fi
+rm llvm-snapshot.gpg.key
 
 echo "=== Clone Repository ==="
 test -d env || mkdir env
diff --git a/src/arch/riscv/include/asm/context.h b/src/arch/riscv/include/asm/context.h
index 92cdc2e5e5da4d8a429490299a99f20c4a8cf392..1bc4771d1f0e51bca81d1697cc0f47e331a6297d 100644
--- a/src/arch/riscv/include/asm/context.h
+++ b/src/arch/riscv/include/asm/context.h
@@ -12,6 +12,7 @@ typedef struct regs_context {
     reg_t sepc;
     reg_t sbadaddr;
     reg_t scause;
+    reg_t sscratch;
 } regs_context_t;
 
 /* used to save register infomation in switch_to */
diff --git a/src/arch/riscv/include/asm/csr.h b/src/arch/riscv/include/asm/csr.h
index 16edd2f06c15c9ea8d535da448b63be2bd044753..830460a0c44d224823c81dd66edaf83a7fd623e5 100644
--- a/src/arch/riscv/include/asm/csr.h
+++ b/src/arch/riscv/include/asm/csr.h
@@ -75,3 +75,6 @@
 #define CSR_INSTRETH 0xc82
 
 #define CSR_MHARTID 0xf14
+
+#define BOOT_STACK_MASTER 0x80600000
+#define BOOT_STACK_SLAVE 0x805ff000
\ No newline at end of file
diff --git a/src/arch/riscv/include/asm/regs.h b/src/arch/riscv/include/asm/regs.h
index b9f3db666e08eb980ab1ad10db0003bc5c9554b8..8325a001d492356f102cdeb06babed6c8c4a94d5 100644
--- a/src/arch/riscv/include/asm/regs.h
+++ b/src/arch/riscv/include/asm/regs.h
@@ -53,13 +53,13 @@
 #define OFFSET_REG_SEPC 256
 #define OFFSET_REG_SBADADDR 264
 #define OFFSET_REG_SCAUSE 272
+#define OFFSET_REG_SSCRATCH 280
 
 /* Size of stack frame, word/double word alignment */
-#define OFFSET_SIZE 280
+#define OFFSET_SIZE 288
 
 #define PCB_KERNEL_SP 0
 #define PCB_USER_SP 8
-#define PCB_PREEMPT_COUNT 16
 
 /* offset in switch_to */
 #define SS(x,y) sd x,SWITCH_TO_##y##(t0)
diff --git a/src/arch/riscv/include/asm/stack.h b/src/arch/riscv/include/asm/stack.h
index 0c37373bb58e3f495a75c6252cf739d6cad92120..0d7eb17903700aee4f21571436cf47ad1ef643e6 100644
--- a/src/arch/riscv/include/asm/stack.h
+++ b/src/arch/riscv/include/asm/stack.h
@@ -5,6 +5,8 @@
 
 ptr_t get_kernel_address(pid_t pid);
 
-void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb, uint64_t argc, char **argv);
+void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb);
 
-void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb);
\ No newline at end of file
+void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb);
+
+void clone_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb, unsigned long flags, void *tls);
\ No newline at end of file
diff --git a/src/arch/riscv/kernel/init/exception.S b/src/arch/riscv/kernel/init/exception.S
index e010d37177b41660bc5c52e0ef6df00ea263c3c5..c8c273d616e200896e3a6cb01e52a273b79628ce 100644
--- a/src/arch/riscv/kernel/init/exception.S
+++ b/src/arch/riscv/kernel/init/exception.S
@@ -22,7 +22,7 @@ ENTRY(setup_exception)
 CORE2_EXCEP:
   la t0, exception_handler_entry
   csrw CSR_STVEC, t0
-  li t0, 0x222
+  li t0, SIE_STIE
   csrw CSR_SIE, t0
   li t0, SR_SIE
   csrw CSR_SSTATUS, t0
diff --git a/src/arch/riscv/kernel/init/head.S b/src/arch/riscv/kernel/init/head.S
index eab96cab100d94843ab8e383e250670009ed1e57..90870ad76d530ee80d02fd4ad199514ae195eedd 100644
--- a/src/arch/riscv/kernel/init/head.S
+++ b/src/arch/riscv/kernel/init/head.S
@@ -26,7 +26,7 @@ ENTRY(_start)
   .option pop
 
   csrr t0, CSR_MHARTID
-  bnez t0, CORE2
+  bnez t0, slave
 
   //these instructions will modify memory
   /* Clear BSS for flat non-ELF images */
@@ -39,22 +39,25 @@ clear_bss:
   blt a3, a4, clear_bss
 clear_bss_done:
 
-  //la a0, riscv_dtb
-  //sd a1, (a0)
-//for boot_kernel?
+  // core 0
+master:
+  li sp, BOOT_STACK_MASTER
   csrr a0, CSR_MHARTID 
-//
-  //la tp, pid0_pcb
-  li sp, 0x50202000
-  call prepare_vm
-  //j loop
-CORE2:
-//for boot_kernel?
-  csrr a0, CSR_MHARTID 
-//
-  //la tp, pid0_pcb2
-  li sp, 0x50203000
   call prepare_vm
+slave:
+  /* Mark all interrupt */
+  li t0, SR_FS
+  csrc sstatus, t0
+  /* Set stvec to kernel entry */
+  csrw CSR_SSCRATCH, t0
+  la t0, prepare_vm
+  csrw CSR_STVEC, t0
+  /* Enable supervisor software interrupt (ipi) */
+  li t0, SIE_SSIE
+  csrw CSR_SIE, t0
+  li t0, SR_SIE
+  csrw CSR_SSTATUS, t0
+  li sp, BOOT_STACK_SLAVE
 
 loop:
   wfi
diff --git a/src/arch/riscv/kernel/init/stack.c b/src/arch/riscv/kernel/init/stack.c
index 4929a3e8c5772fc4d0fc9528a7c1cf7655c16e03..405e8ca4b5b8d1a5079b3574895e9d83e36aacd7 100644
--- a/src/arch/riscv/kernel/init/stack.c
+++ b/src/arch/riscv/kernel/init/stack.c
@@ -1,6 +1,9 @@
+#include <asm/csr.h>
 #include <asm/pgtable.h>
 #include <asm/stack.h>
 #include <lib/stdio.h>
+#include <lib/string.h>
+#include <os/mm.h>
 #include <os/smp.h>
 
 extern void ret_from_exception();
@@ -8,75 +11,56 @@ extern void __global_pointer$();
 
 ptr_t address_base = 0xffffffc050504000lu;
 
-ptr_t get_kernel_address(pid_t pid) { return address_base + (pid + 1) * 0x2000; }
+ptr_t get_kernel_address(pid_t pid) {
+    return address_base + (pid + 1) * 2 * PAGE_SIZE;
+}
 
-ptr_t get_user_address(pid_t pid) { return address_base + pid * 0x2000 + 0x1000; }
+ptr_t get_user_address(pid_t pid) {
+    return address_base + pid * 2 * PAGE_SIZE + PAGE_SIZE;
+}
 
-void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb, uint64_t argc, char **argv) {
+void init_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, ptr_t entry_point, pcb_t *pcb) {
     regs_context_t *pt_regs = (regs_context_t *)(kernel_stack - sizeof(regs_context_t));
-    uint64_t user_stack_kva = kernel_stack - 0x1000;
-    for (int i = 5; i < 32; i++)
-        pt_regs->regs[i] = 0;
-    if (argv != NULL) {
-        char **u_argv = (char **)(user_stack_kva - 100);
-        for (int i = 0; i < argc; i++) {
-            char *s = (char *)(user_stack_kva - 100 - 20 * (i + 1));
-            char *t = argv[i];
-            int j = 0;
-            for (j = 0; t[j] != '\0'; j++)
-                s[j] = t[j];
-            s[j] = '\0';
-            u_argv[i] = (char *)(user_stack - 100 - 20 * (i + 1));
-            // prints("%x\n",u_argv[i]);
-        }
-        pcb->user_sp = user_stack - 256;
-        // prints("sp:%x\n", pcb->user_sp);
-        pt_regs->regs[11] = user_stack - 100;
-    } else
-        pcb->user_sp = user_stack;
+    k_memset(pt_regs, 0, sizeof(regs_context_t));
     pcb->kernel_sp = kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t);
+    pcb->user_sp = user_stack;
     pt_regs->regs[0] = 0;
     pt_regs->regs[1] = entry_point;
     pt_regs->regs[2] = pcb->user_sp;
-    if (pcb->type == USER_PROCESS)
+    if (pcb->type == USER_PROCESS) {
         pt_regs->regs[3] = (reg_t)__global_pointer$;
-    else if (pcb->type == USER_THREAD) {
+    } else if (pcb->type == USER_THREAD) {
         regs_context_t *cur_regs = (regs_context_t *)((*current_running)->kernel_sp + sizeof(switchto_context_t));
         pt_regs->regs[3] = cur_regs->regs[3];
     }
     pt_regs->regs[4] = (reg_t)pcb;
-    pt_regs->regs[10] = argc;
     pt_regs->sepc = entry_point;
-    pt_regs->sstatus = 0x40020;
+    pt_regs->sstatus = SR_SUM | SR_FS;
     pt_regs->sbadaddr = 0;
     pt_regs->scause = 0;
+    pt_regs->sscratch = (reg_t)pcb;
 
     switchto_context_t *sw_regs = (switchto_context_t *)(kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t));
-    sw_regs->regs[0] = (reg_t)ret_from_exception;
-    // sw_regs->regs[1] = pcb->user_sp;
+    sw_regs->regs[0] = (pcb->type == USER_PROCESS || pcb->type == USER_THREAD) ? (reg_t)&ret_from_exception : entry_point;
+    sw_regs->regs[1] = pcb->kernel_sp;
+    pcb->save_context = pt_regs;
+    pcb->switch_context = sw_regs;
 }
 
 void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb) {
     regs_context_t *pt_regs = (regs_context_t *)(kernel_stack - sizeof(regs_context_t));
     regs_context_t *cur_regs = (regs_context_t *)((*current_running)->kernel_sp + sizeof(switchto_context_t));
     ptr_t cur_address = get_user_address((*current_running)->pid);
-    ptr_t off = 0x1000 - 1;
-    char *p = (char *)(user_stack - 1);
-    char *q = (char *)(cur_address - 1);
-    // i is unsigned
-    // printk("here1\n");
-    for (ptr_t i = off + 1; i > 0; i--) {
-        *p = *q;
-        p--;
-        q--;
-    }
-    pcb->user_sp = (*current_running)->user_sp;
+    k_memcpy((uint8_t *)(user_stack - PAGE_SIZE), (uint8_t *)(cur_address - PAGE_SIZE), PAGE_SIZE - 1);
     pcb->kernel_sp = kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t);
-    for (int i = 0; i < 32; i++)
+    pcb->user_sp = (*current_running)->user_sp;
+
+    for (int i = 0; i < 32; i++) {
         pt_regs->regs[i] = cur_regs->regs[i];
+    }
     // tp
-    pt_regs->regs[4] = (reg_t)pcb;
     pt_regs->regs[2] = pcb->user_sp;
+    pt_regs->regs[4] = (reg_t)pcb;
     // a0
     pt_regs->regs[10] = 0;
     // pt_regs->regs[8] = user_stack;
@@ -84,7 +68,27 @@ void fork_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb) {
     pt_regs->sstatus = cur_regs->sstatus;
     pt_regs->sbadaddr = cur_regs->sbadaddr;
     pt_regs->scause = cur_regs->scause;
+    pt_regs->sscratch = (reg_t)pcb;
+
     switchto_context_t *sw_regs = (switchto_context_t *)(kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t));
     sw_regs->regs[0] = (reg_t)ret_from_exception;
     // sw_regs->regs[1] = pcb->user_sp;
+    pcb->save_context = pt_regs;
+    pcb->switch_context = sw_regs;
+}
+
+void clone_pcb_stack(ptr_t kernel_stack, ptr_t user_stack, pcb_t *pcb, unsigned long flags, void *tls) {
+    regs_context_t *pt_regs = (regs_context_t *)(kernel_stack - sizeof(regs_context_t));
+    switchto_context_t *sw_regs = (switchto_context_t *)(kernel_stack - sizeof(regs_context_t) - sizeof(switchto_context_t));
+    pcb->save_context = pt_regs;
+    pcb->switch_context = sw_regs;
+    pcb->kernel_sp = (uintptr_t)pcb->switch_context;
+    pcb->switch_context->regs[0] = (reg_t)&ret_from_exception;
+    pcb->switch_context->regs[1] = pcb->kernel_sp;
+    pcb->save_context->regs[2] = user_stack == USER_STACK_ADDR ? (*current_running)->save_context->regs[2] : user_stack;
+    if (flags & CLONE_SETTLS) {
+        pcb->save_context->regs[4] = (reg_t)tls;
+    }
+    pcb->save_context->regs[10] = 0;
+    pcb->save_context->sscratch = (reg_t)pcb;
 }
\ No newline at end of file
diff --git a/src/arch/riscv/kernel/sys/context.S b/src/arch/riscv/kernel/sys/context.S
index 0ad984d9952fb04983111dd60e736a4d2b998e90..e24d326a00213d7a248f94d8793155e3c5719b03 100644
--- a/src/arch/riscv/kernel/sys/context.S
+++ b/src/arch/riscv/kernel/sys/context.S
@@ -19,6 +19,7 @@
 _save_context:
   sd sp, PCB_USER_SP(tp)
   ld sp, PCB_KERNEL_SP(tp)
+  csrrw tp, CSR_SSCRATCH, tp
   addi sp, sp, SWITCH_TO_SIZE
 
   /* TODO: save all general purpose registers here! */
@@ -58,6 +59,8 @@ _save_context:
   SAVE(a0,SEPC)
   csrr a0, CSR_SCAUSE
   SAVE(a0,SCAUSE)
+  csrr a0, CSR_SSCRATCH
+  SAVE(a0,SSCRATCH)
   ld a0, PCB_USER_SP(tp)
   SAVE(a0,SP)
   /*
@@ -70,11 +73,20 @@ _save_context:
   li t0, SR_SUM | SR_FS
   //addi sp, sp, -(SWITCH_TO_SIZE)
   /* TODO: save sstatus, sepc, stval, scause and sscratch on user stack */
+  csrrw tp, CSR_SSCRATCH, tp
+  ld sp, PCB_KERNEL_SP(tp)
 .endm
 
 .macro RESTORE_CONTEXT
   ld sp, PCB_KERNEL_SP(tp)
   addi sp, sp, SWITCH_TO_SIZE
+  LOAD(s0,SSTATUS)
+  csrw CSR_SSTATUS, s0
+  LOAD(s0,SEPC)
+  csrw CSR_SEPC, s0
+  LOAD(s0, SSCRATCH)
+  csrw CSR_SSCRATCH, s0
+  csrrw tp, CSR_SSCRATCH, tp
   LOAD(ra,RA)
   LOAD(gp,GP)
   LOAD(tp,TP)
@@ -105,10 +117,6 @@ _save_context:
   LOAD(t4,T4)
   LOAD(t5,T5)
   LOAD(t6,T6)
-  LOAD(s0,SSTATUS)
-  csrw CSR_SSTATUS, s0
-  LOAD(s0,SEPC)
-  csrw CSR_SEPC, s0
   LOAD(s0,S0)
   LOAD(sp,SP)
   fence
@@ -121,27 +129,10 @@ _save_context:
 
 ENTRY(enable_preempt)
   jr ra
-  ld t1, current_running0
-  ld t0, PCB_PREEMPT_COUNT(t1)
-  beq t0, zero, do_enable
-  addi t0, t0, -1
-  sd t0, PCB_PREEMPT_COUNT(t1)
-  beq t0, zero, do_enable
-  jr ra
-do_enable:
-  not t0, x0
-  csrs CSR_SIE, t0
-  jr ra
 ENDPROC(enable_preempt)
 
 ENTRY(disable_preempt)
   jr ra
-  csrw CSR_SIE, zero
-  ld t1, current_running0
-  ld t0, PCB_PREEMPT_COUNT(t1)
-  addi t0, t0, 1
-  sd t0, PCB_PREEMPT_COUNT(t1)
-  jr ra
 ENDPROC(disable_preempt)
 
 ENTRY(enable_interrupt)
diff --git a/src/arch/riscv/sbi/common.c b/src/arch/riscv/sbi/common.c
index 9b15be2aa5ed5cdaba8cae4aa6f44cd71da0acbc..63da1232036ad992aae63364e37a6eae6e3c2950 100644
--- a/src/arch/riscv/sbi/common.c
+++ b/src/arch/riscv/sbi/common.c
@@ -1,8 +1,14 @@
 #include <asm/common.h>
 #include <asm/sbi.h>
 
-void port_write_ch(char ch) { sbi_console_putchar((int)ch); }
+void port_write_ch(char ch) {
+    sbi_console_putchar((int)ch);
+}
 
-void port_write(char *str) { sbi_console_putstr(str); }
+void port_write(char *str) {
+    sbi_console_putstr(str);
+}
 
-long sys_port_read() { return sbi_console_getchar(); }
+long sys_port_read() {
+    return sbi_console_getchar();
+}
diff --git a/src/drivers/screen.c b/src/drivers/screen.c
index 40f22012d36d362854d228cafc6ace2c5f60fd73..8bb359fd9fcdc2b19852f9a7ef2f34b2ed872f97 100644
--- a/src/drivers/screen.c
+++ b/src/drivers/screen.c
@@ -46,10 +46,11 @@ static void screen_write_ch(char ch) {
             k_screen_reflush();
             for (int i = start_line - 1; i < SCREEN_HEIGHT; i++) {
                 for (int j = 0; j < SCREEN_WIDTH; j++) {
-                    if (i == SCREEN_HEIGHT - 1)
+                    if (i == SCREEN_HEIGHT - 1) {
                         new_screen[i * SCREEN_WIDTH + j] = ' ';
-                    else
+                    } else {
                         new_screen[i * SCREEN_WIDTH + j] = old_screen[(i + 1) * SCREEN_WIDTH + j];
+                    }
                 }
             }
             (*current_running)->cursor_y = SCREEN_HEIGHT;
@@ -96,7 +97,7 @@ long sys_screen_move_cursor(int x, int y) {
 
 long sys_screen_write(char *buff) {
     int i = 0;
-    int l = strlen(buff);
+    int l = k_strlen(buff);
 
     for (i = 0; i < l; i++) {
         screen_write_ch(buff[i]);
@@ -133,7 +134,9 @@ long k_screen_reflush(void) {
     return 0;
 }
 
-void load_curpcb_cursor() { kernel_move_cursor((*current_running)->cursor_x, (*current_running)->cursor_y); }
+void load_curpcb_cursor() {
+    kernel_move_cursor((*current_running)->cursor_x, (*current_running)->cursor_y);
+}
 
 void kernel_move_cursor(int x, int y) {
     // \033[y;xH
diff --git a/src/fs/fs.c b/src/fs/fs.c
index 49d278dd96499c2efbd0d70a96c93f716da48cc5..1e026846f6698246f378177713796af99a83a4b6 100644
--- a/src/fs/fs.c
+++ b/src/fs/fs.c
@@ -119,8 +119,9 @@ int alloc_fid() {
     if (freenum > 0) {
         id = freefid[freenum];
         freenum--;
-    } else
+    } else {
         id = nowfid++;
+    }
     return id;
 }
 
@@ -141,12 +142,14 @@ int alloc_inode() {
             imap[id] = imap[id] | ((uint64_t)1 << (i % 64));
             inodeid = i;
             superblock.inode_used++;
-            if ((((superblock.inode_used - 1) * sizeof(inode_t)) % 512) + sizeof(inode_t) > 512 || (((superblock.inode_used - 1) * sizeof(inode_t)) % 512) == 0)
+            if ((((superblock.inode_used - 1) * sizeof(inode_t)) % 512) + sizeof(inode_t) > 512 || (((superblock.inode_used - 1) * sizeof(inode_t)) % 512) == 0) {
                 superblock.sector_used += 1;
+            }
             break;
         }
-        if ((i % 64) == 63)
+        if ((i % 64) == 63) {
             id++;
+        }
     }
     sbi_sd_write(kva2pa(FS_KERNEL_ADDR + iab_map_addr_offset), 1, superblock.imap_sec_offset + superblock.fs_start_sec);
     sbi_sd_write(kva2pa((long unsigned int)&superblock), 1, fs_start_sec + sb_sec_offset);
@@ -165,8 +168,9 @@ int alloc_block(inode_t *inode) {
             superblock.sector_used += 8;
             break;
         }
-        if ((i % 64) == 56)
+        if ((i % 64) == 56) {
             id++;
+        }
     }
     inode->sec_size += 8;
     sbi_sd_write(kva2pa(empty_block), 8, superblock.data_sec_offset + superblock.fs_start_sec + sectorid);
@@ -183,16 +187,18 @@ int look_up_1dir(char *name) {
 
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0) {
+        if (k_strcmp(dir->name, name) == 0) {
             flag = 1;
             break;
         }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0)
+    if (k_strcmp(dir->name, name) == 0) {
         flag = 1;
-    if (flag == 0)
+    }
+    if (flag == 0) {
         return -1;
+    }
 
     inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     inode += dir->inode_id;
@@ -209,7 +215,7 @@ int look_up_dir(const char *buff) {
     char name[20];
     int i = 0;
     int inodeid = nowinodeid;
-    int num = strlen(buff);
+    int num = k_strlen(buff);
 
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     inode_t *inode = &nowinode;
@@ -224,13 +230,15 @@ int look_up_dir(const char *buff) {
         i = k + 1;
 
         // file has no subdir
-        if (inode->mode == 1)
+        if (inode->mode == 1) {
             return -1;
+        }
         inodeid = look_up_1dir(name);
 
         // no file/dir matched
-        if (inodeid == -1)
+        if (inodeid == -1) {
             return -1;
+        }
         inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
         inode += inodeid;
     }
@@ -242,9 +250,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
     if (rpos_block < 11) {
         int point_num = rpos_block;
         if (inode->direct_block_pointers[point_num] == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 inode->direct_block_pointers[point_num] = alloc_block(inode);
             }
         }
@@ -255,19 +263,20 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
         int point1_num = (rpos_block - 11) % 1024;
 
         if (inode->indirect_block_pointers[point2_num] == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1)
+            } else if (mode == 1) {
                 inode->indirect_block_pointers[point2_num] = alloc_block(inode);
+            }
         }
         sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->indirect_block_pointers[point2_num]);
         int *p = (int *)(FS_KERNEL_ADDR + dir_addr_offset);
         p += point1_num;
 
         if (*p == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 *p = alloc_block(inode);
                 sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->indirect_block_pointers[point2_num]);
             }
@@ -280,19 +289,20 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
         int point1_num = (rpos_block - 11 - 1024 * 3) % 1024;
 
         if (inode->double_block_pointers[point3_num] == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1)
+            } else if (mode == 1) {
                 inode->double_block_pointers[point3_num] = alloc_block(inode);
+            }
         }
         sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->double_block_pointers[point3_num]);
         int *p = (int *)(FS_KERNEL_ADDR + dir_addr_offset);
         p += point2_num;
 
         if (*p == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 *p = alloc_block(inode);
                 sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->double_block_pointers[point3_num]);
             }
@@ -304,9 +314,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
         p += point1_num;
 
         if (*p == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 *p = alloc_block(inode);
                 sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + of2);
             }
@@ -320,19 +330,20 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
         int point1_num = (rpos_block - 11 - 1024 * 3 - 2 * 1024 * 1024) % 1024;
 
         if (inode->trible_block_pointers == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1)
+            } else if (mode == 1) {
                 inode->trible_block_pointers = alloc_block(inode);
+            }
         }
         sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->trible_block_pointers);
         int *p = (int *)(FS_KERNEL_ADDR + dir_addr_offset);
         p += point3_num;
 
         if (*p == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 *p = alloc_block(inode);
                 sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->trible_block_pointers);
             }
@@ -344,9 +355,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
         p += point2_num;
 
         if (*p == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 *p = alloc_block(inode);
                 sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + of2);
             }
@@ -358,9 +369,9 @@ int seek_pos(int rpos_block, int rpos_offset, inode_t *inode, int mode) {
         p += point1_num;
 
         if (*p == 0) {
-            if (mode == 0)
+            if (mode == 0) {
                 return -1;
-            else if (mode == 1) {
+            } else if (mode == 1) {
                 *p = alloc_block(inode);
                 sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + of1);
             }
@@ -377,12 +388,15 @@ void init_file(int inodeid) {
     inode->sec_size = 0;
     inode->mode = 1; // 0-directory, 1-file
     inode->link_num = 0;
-    for (int i = 0; i < 11; i++)
+    for (int i = 0; i < 11; i++) {
         inode->direct_block_pointers[i] = 0;
-    for (int i = 0; i < 3; i++)
+    }
+    for (int i = 0; i < 3; i++) {
         inode->indirect_block_pointers[i] = 0;
-    for (int i = 0; i < 2; i++)
+    }
+    for (int i = 0; i < 2; i++) {
         inode->double_block_pointers[i] = 0;
+    }
     inode->trible_block_pointers = 0;
 
     // no write, no need for data block
@@ -394,19 +408,21 @@ long sys_touch(const char *name) {
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0)
+        if (k_strcmp(dir->name, name) == 0) {
             return 0;
+        }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0)
+    if (k_strcmp(dir->name, name) == 0) {
         return 0;
+    }
     dir->last = 0;
     dir++;
     dir->inode_id = alloc_inode();
     init_file(dir->inode_id);
     dir->mode = 1;
     dir->last = 1;
-    strcpy(dir->name, name);
+    k_strcpy(dir->name, name);
 
     sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     return 1;
@@ -417,17 +433,19 @@ long sys_fopen(const char *name, int access) {
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0 && dir->mode == 1) {
+        if (k_strcmp(dir->name, name) == 0 && dir->mode == 1) {
             flag = 1;
             break;
         }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0 && dir->mode == 1)
+    if (k_strcmp(dir->name, name) == 0 && dir->mode == 1) {
         flag = 1;
+    }
     if (flag == 0) {
-        if (access == -1)
+        if (access == -1) {
             return -1;
+        }
         sys_touch(name);
         dir++;
     }
@@ -440,8 +458,9 @@ long sys_fopen(const char *name, int access) {
 }
 
 int fread(int fid, unsigned char *buff, int size) {
-    if (fd[fid].prive == O_WRONLY)
+    if (fd[fid].prive == O_WRONLY) {
         return -1;
+    }
     int rpos_block = fd[fid].pos_block;
     int rpos_offset = fd[fid].pos_offset;
 
@@ -453,8 +472,9 @@ int fread(int fid, unsigned char *buff, int size) {
     while (nowsize < size) {
         int offset = rpos_offset;
         int flag = seek_pos(rpos_block, rpos_offset, inode, 0);
-        if (flag == 0 || flag == -1)
+        if (flag == 0 || flag == -1) {
             return -1;
+        }
         src = (unsigned char *)(FS_KERNEL_ADDR + data_addr_offset + offset);
         while (rpos_offset < 512 * 8 && nowsize < size) {
             *(buff++) = *(src++);
@@ -476,8 +496,9 @@ int file_len = 0;
 
 int try_get_from_file(const char *file_name, unsigned char **binary, int *length) {
     int fid = sys_fopen(file_name, -1);
-    if (fid == -1)
+    if (fid == -1) {
         return 0;
+    }
     inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     inode += fd[fid].inodeid;
 
@@ -491,8 +512,9 @@ int try_get_from_file(const char *file_name, unsigned char **binary, int *length
 }
 
 long sys_fread(int fid, char *buff, int size) {
-    if (fd[fid].prive == O_WRONLY)
+    if (fd[fid].prive == O_WRONLY) {
         return -1;
+    }
     int rpos_block = fd[fid].pos_block;
     int rpos_offset = fd[fid].pos_offset;
 
@@ -504,8 +526,9 @@ long sys_fread(int fid, char *buff, int size) {
     while (nowsize < size) {
         int offset = rpos_offset;
         int flag = seek_pos(rpos_block, rpos_offset, inode, 0);
-        if (flag == 0 || flag == -1)
+        if (flag == 0 || flag == -1) {
             return -1;
+        }
         src = (char *)(FS_KERNEL_ADDR + data_addr_offset + offset);
         while (rpos_offset < 512 * 8 && nowsize < size) {
             *(buff++) = *(src++);
@@ -523,8 +546,9 @@ long sys_fread(int fid, char *buff, int size) {
 }
 
 long sys_fwrite(int fid, char *buff, int size) {
-    if (fd[fid].prive == O_RDONLY)
+    if (fd[fid].prive == O_RDONLY) {
         return -1;
+    }
     int rpos_block = fd[fid].pos_block;
     int rpos_offset = fd[fid].pos_offset;
 
@@ -567,11 +591,11 @@ void init_dir(int inodeid) {
 
     dentry_t *dentry = (dentry_t *)(FS_KERNEL_ADDR + data_addr_offset);
     dentry->inode_id = inodeid;
-    strcpy(dentry->name, ".");
+    k_strcpy(dentry->name, ".");
     dentry->last = 0;
     dentry++;
     dentry->inode_id = nowinodeid;
-    strcpy(dentry->name, "..");
+    k_strcpy(dentry->name, "..");
     dentry->last = 1;
 
     sbi_sd_write(kva2pa(FS_KERNEL_ADDR + inode_addr_offset), superblock.inode_sec_size, superblock.fs_start_sec + superblock.inode_sec_offset);
@@ -582,19 +606,21 @@ long sys_mkdir(const char *name) {
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0)
+        if (k_strcmp(dir->name, name) == 0) {
             return 0;
+        }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0)
+    if (k_strcmp(dir->name, name) == 0) {
         return 0;
+    }
     dir->last = 0;
     dir++;
     dir->inode_id = alloc_inode();
     init_dir(dir->inode_id);
     dir->mode = 0;
     dir->last = 1;
-    strcpy(dir->name, name);
+    k_strcpy(dir->name, name);
     sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), nowinode.sec_size, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     return 1;
 }
@@ -605,19 +631,23 @@ long sys_ln(const char *name, char *path) {
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir2_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir2_addr_offset);
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0)
+        if (k_strcmp(dir->name, name) == 0) {
             return 0;
+        }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0)
+    if (k_strcmp(dir->name, name) == 0) {
         return 0;
+    }
     int inodeid = look_up_dir(path);
-    if (inodeid == -1)
+    if (inodeid == -1) {
         return 0;
+    }
     inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     inode += inodeid;
-    if (inode->mode == 0)
+    if (inode->mode == 0) {
         return 0;
+    }
     inode->link_num++;
 
     dir->last = 0;
@@ -625,7 +655,7 @@ long sys_ln(const char *name, char *path) {
     dir->inode_id = inodeid;
     dir->mode = 1;
     dir->last = 1;
-    strcpy(dir->name, name);
+    k_strcpy(dir->name, name);
 
     sbi_sd_write(kva2pa(FS_KERNEL_ADDR + dir2_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + nowinode.direct_block_pointers[0]);
     return 1;
@@ -637,20 +667,24 @@ long sys_rmdir(const char *name) {
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     int dinode;
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0) {
+        if (k_strcmp(dir->name, name) == 0) {
             flag = 1;
             break;
         }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0)
+    if (k_strcmp(dir->name, name) == 0) {
         flag = 1;
-    if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
+    }
+    if (k_strcmp(name, ".") == 0 || k_strcmp(name, "..") == 0) {
         flag = 0;
-    if (flag == 0)
+    }
+    if (flag == 0) {
         return 0;
-    if (dir->mode == 1)
+    }
+    if (dir->mode == 1) {
         return 0; // file not dir
+    }
     dinode = dir->inode_id;
 
     if (dir->last) {
@@ -663,7 +697,7 @@ long sys_rmdir(const char *name) {
             p->inode_id = (p + 1)->inode_id;
             p->last = (p + 1)->last;
             p->mode = (p + 1)->mode;
-            strcpy(p->name, (p + 1)->name);
+            k_strcpy(p->name, (p + 1)->name);
             p++;
         }
     }
@@ -712,8 +746,9 @@ int getback_block(inode_t *inode) {
             getback_1block(data_sec_start, smap, &nowsec);
         }
     }
-    if (nowsec >= inode->sec_size)
+    if (nowsec >= inode->sec_size) {
         return nowsec;
+    }
     for (int i = 0; i < 3; i++) {
         pointer1_sec_start = inode->indirect_block_pointers[i];
         if (pointer1_sec_start != 0) {
@@ -725,8 +760,9 @@ int getback_block(inode_t *inode) {
                 if (p[j] != 0) {
                     getback_1block(p[j], smap, &nowsec);
                 }
-                if (nowsec >= inode->sec_size)
+                if (nowsec >= inode->sec_size) {
                     return nowsec;
+                }
             }
         }
     }
@@ -747,8 +783,9 @@ int getback_block(inode_t *inode) {
                         if (p2[k] != 0) {
                             getback_1block(p2[k], smap, &nowsec);
                         }
-                        if (nowsec >= inode->sec_size)
+                        if (nowsec >= inode->sec_size) {
                             return nowsec;
+                        }
                     }
                 }
             }
@@ -773,8 +810,9 @@ int getback_block(inode_t *inode) {
                             if (p3[m] != 0) {
                                 getback_1block(p3[m], smap, &nowsec);
                             }
-                            if (nowsec >= inode->sec_size)
+                            if (nowsec >= inode->sec_size) {
                                 return nowsec;
+                            }
                         }
                     }
                 }
@@ -790,18 +828,21 @@ long sys_rm(const char *name) {
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     int dinode;
     while (!(dir->last)) {
-        if (strcmp(dir->name, name) == 0) {
+        if (k_strcmp(dir->name, name) == 0) {
             flag = 1;
             break;
         }
         dir++;
     }
-    if (strcmp(dir->name, name) == 0)
+    if (k_strcmp(dir->name, name) == 0) {
         flag = 1;
-    if (flag == 0)
+    }
+    if (flag == 0) {
         return 0;
-    if (dir->mode == 0)
+    }
+    if (dir->mode == 0) {
         return 0; // dir not file
+    }
     dinode = dir->inode_id;
     if (dir->last) {
         dir--;
@@ -813,7 +854,7 @@ long sys_rm(const char *name) {
             p->inode_id = (p + 1)->inode_id;
             p->last = (p + 1)->last;
             p->mode = (p + 1)->mode;
-            strcpy(p->name, (p + 1)->name);
+            k_strcpy(p->name, (p + 1)->name);
             p++;
         }
     }
@@ -845,12 +886,15 @@ long sys_rm(const char *name) {
 void update_inode(inode_t *src, int id) {
     nowinode.mode = src->mode;
     nowinode.sec_size = src->sec_size;
-    for (int i = 0; i < 11; i++)
+    for (int i = 0; i < 11; i++) {
         nowinode.direct_block_pointers[i] = src->direct_block_pointers[i];
-    for (int i = 0; i < 3; i++)
+    }
+    for (int i = 0; i < 3; i++) {
         nowinode.indirect_block_pointers[i] = src->indirect_block_pointers[i];
-    for (int i = 0; i < 2; i++)
+    }
+    for (int i = 0; i < 2; i++) {
         nowinode.double_block_pointers[i] = src->double_block_pointers[i];
+    }
     nowinode.trible_block_pointers = src->trible_block_pointers;
     nowinodeid = id;
 }
@@ -858,22 +902,25 @@ void update_inode(inode_t *src, int id) {
 long sys_cd(const char *name) {
     int inodeid = 0;
     inodeid = look_up_dir(name);
-    if (inodeid == -1)
+    if (inodeid == -1) {
         return 0;
+    }
 
     // update nowinode
     inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     inode += inodeid;
-    if (inode->mode == 1)
+    if (inode->mode == 1) {
         return 0; // file
+    }
     update_inode(inode, inodeid);
     return 1;
 }
 
 int getwei(int a) {
     int num = 0;
-    if (a == 0)
+    if (a == 0) {
         return 1;
+    }
     while (a) {
         num++;
         a /= 10;
@@ -882,34 +929,40 @@ int getwei(int a) {
 }
 
 void printw(int num, int what) {
-    while (num--)
+    while (num--) {
         prints(" ");
+    }
     prints("%d", what);
 }
 
 long sys_ls(const char *name, int func) {
     int inodeid = look_up_dir(name);
-    if (inodeid == -1)
+    if (inodeid == -1) {
         return 0;
+    }
 
     dentry_t *dir = (dentry_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     inode += inodeid;
-    if (inode->mode == 1)
+    if (inode->mode == 1) {
         return 0;
+    }
 
     int len = 0;
     int num = 0;
-    if (func == 1)
+    if (func == 1) {
         prints("[%d] name        inode        ln           size(B)\n", num++);
+    }
     while (!(dir->last)) {
         prints("[%d] %s", num++, dir->name);
-        if (dir->mode == 0)
+        if (dir->mode == 0) {
             prints("/");
+        }
         if (func == 1) {
-            len = strlen(dir->name);
-            if (dir->mode == 0)
+            len = k_strlen(dir->name);
+            if (dir->mode == 0) {
                 len++;
+            }
             inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
             inode += dir->inode_id;
             len = 13 - len;
@@ -923,12 +976,14 @@ long sys_ls(const char *name, int func) {
         dir++;
     }
     prints("[%d] %s", num++, dir->name);
-    if (dir->mode == 0)
+    if (dir->mode == 0) {
         prints("/");
+    }
     if (func == 1) {
-        len = strlen(dir->name);
-        if (dir->mode == 0)
+        len = k_strlen(dir->name);
+        if (dir->mode == 0) {
             len++;
+        }
         inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
         inode += dir->inode_id;
         len = 13 - len;
@@ -944,12 +999,14 @@ long sys_ls(const char *name, int func) {
 
 long sys_cat(const char *name) {
     int inodeid = look_up_dir(name);
-    if (inodeid == -1)
+    if (inodeid == -1) {
         return 0;
+    }
     inode_t *inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     inode += inodeid;
-    if (inode->sec_size == 0 || inode->mode == 0)
+    if (inode->sec_size == 0 || inode->mode == 0) {
         return 0;
+    }
 
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + data_addr_offset), 8, superblock.data_sec_offset + superblock.fs_start_sec + inode->direct_block_pointers[0]);
 
@@ -957,8 +1014,9 @@ long sys_cat(const char *name) {
     int off = 0;
     int times = 1024;
     while (*c && (times--)) {
-        if (*c == '\n')
+        if (*c == '\n') {
             off++;
+        }
         prints("%c", *c);
         c++;
     }
@@ -983,12 +1041,13 @@ long sys_mkfs(int func) {
     // root occupy inode[0] and data[0-7]
     uint64_t *iabmap = (uint64_t *)(FS_KERNEL_ADDR + iab_map_addr_offset);
     for (int i = 0; i < iab_map_addr_size / 8; i++) {
-        if (i == 0)
+        if (i == 0) {
             iabmap[i] = 1;
-        else if (i == 64)
+        } else if (i == 64) {
             iabmap[i] = 0xff;
-        else
+        } else {
             iabmap[i] = 0;
+        }
     }
     inode_t *root_inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
     root_inode->link_num = 0;
@@ -998,12 +1057,12 @@ long sys_mkfs(int func) {
 
     dentry_t *root_dentry = (dentry_t *)(FS_KERNEL_ADDR + data_addr_offset);
     root_dentry->inode_id = 0;
-    strcpy(root_dentry->name, ".");
+    k_strcpy(root_dentry->name, ".");
     root_dentry->mode = 0;
     root_dentry->last = 0;
     root_dentry++;
     root_dentry->inode_id = 0;
-    strcpy(root_dentry->name, "..");
+    k_strcpy(root_dentry->name, "..");
     root_dentry->mode = 0;
     root_dentry->last = 1;
 
@@ -1052,7 +1111,7 @@ extern void map_fs_space();
 
 void init_fs() {
     map_fs_space();
-    memset((void *)empty_block, 0, 0x1000);
+    k_memset((void *)empty_block, 0, 0x1000);
 
     // main superblock and back-up superblock
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + dir_addr_offset), 1, fs_start_sec + sb_sec_offset);
@@ -1060,13 +1119,15 @@ void init_fs() {
     super_block_t *sb = (super_block_t *)(FS_KERNEL_ADDR + dir_addr_offset);
     super_block_t *sb2 = (super_block_t *)(FS_KERNEL_ADDR + dir_addr_offset + 512);
     // not inited, then initialize
-    if (sb->magic != magic_number && sb2->magic != magic_number)
+    if (sb->magic != magic_number && sb2->magic != magic_number) {
         sys_mkfs(-1);
+    }
     // make sure one of them can work
-    else if (sb->magic != magic_number && sb2->magic == magic_number)
+    else if (sb->magic != magic_number && sb2->magic == magic_number) {
         cpy_sb(1, sb2);
-    else
+    } else {
         cpy_sb(1, sb);
+    }
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + iab_map_addr_offset), superblock.imap_sec_size + superblock.smap_sec_size, superblock.imap_sec_offset + superblock.fs_start_sec);
     sbi_sd_read(kva2pa(FS_KERNEL_ADDR + inode_addr_offset), superblock.inode_sec_size, superblock.inode_sec_offset + superblock.fs_start_sec);
     inode_t *root_inode = (inode_t *)(FS_KERNEL_ADDR + inode_addr_offset);
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 840d56e113cca5b476e3ed477bff533a8dca0d43..052ec20ba1b91853215431748e59b4d1f09a5ee0 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -115,6 +115,8 @@ extern int nowfid;
 extern int freefid[20];
 extern int freenum;
 
+int try_get_from_file(const char *file_name, unsigned char **binary, int *length);
+
 void init_fs();
 int k_mkfs(int func);
 long sys_getcwd(const char *buf, unsigned long size);
@@ -125,11 +127,18 @@ long sys_unlinkat(int dfd, const char *pathname, int flag);
 long sys_linkat(int olddfd, const char *oldname, int newdfd, const char *newname, int flags);
 long sys_umount2(const char *name, int flags);
 long sys_mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, void *data);
-long sys_chdir(const char *filename);
-long sys_openat(int dfd, const char *filename, int flags, umode_t mode);
+long sys_chdir(const char *file_name);
+long sys_openat(int dfd, const char *file_name, int flags, umode_t mode);
 long sys_close(unsigned long fd);
 long sys_pipe2(int *fildes, int flags);
 long sys_getdents64(unsigned int fd, dirent64_t *dirent, unsigned int count);
 long sys_read(unsigned int fd, char *buf, size_t count);
 long sys_write(unsigned int fd, const char *buf, size_t count);
-long sys_fstat(unsigned int fd, kstat_t *statbuf);
\ No newline at end of file
+long sys_fstat(unsigned int fd, kstat_t *statbuf);
+
+void *sys_mmap(void *addr, size_t length, int prot, int flags,
+                  int fd, off_t offset);
+long sys_munmap(unsigned long addr, size_t len);
+long sys_mremap(unsigned long addr,
+			   unsigned long old_len, unsigned long new_len,
+			   unsigned long flags, unsigned long new_addr);
\ No newline at end of file
diff --git a/src/include/common/elf.h b/src/include/common/elf.h
index 6e4265db7d5c85b786a8bf9c71ff2e56936cc2fb..6020efc0813eb7b135b8b946b6f72694ce64f332 100644
--- a/src/include/common/elf.h
+++ b/src/include/common/elf.h
@@ -119,6 +119,15 @@ typedef struct elf64_phdr
     Elf64_Xword p_align;  /* Segment alignment, file & memory */
 } Elf64_Phdr;
 
+typedef struct ELF_info{
+    uint64_t text_begin;
+    uint64_t phoff;
+    uint64_t phent;
+    uint64_t phnum;
+    uint64_t entry;
+    uint64_t edata;
+} ELF_info_t;
+
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 static inline int is_elf_format(unsigned char *binary)
@@ -169,7 +178,7 @@ static inline uintptr_t load_elf(
                     unsigned char *bytes_of_page =
                         (unsigned char *)prepare_page_for_va(
                             (uintptr_t)(phdr->p_vaddr + i), pgdir);
-                    memcpy(
+                    k_memcpy(
                         bytes_of_page,
                         elf_binary + phdr->p_offset + i,
                         MIN(phdr->p_filesz - i, NORMAL_PAGE_SIZE));
diff --git a/src/include/common/types.h b/src/include/common/types.h
index 06a65abaacf91f5c498445c8df1bb86b0cae513e..eb0daf55b43737b61974b28adf05d25af5b79b4c 100644
--- a/src/include/common/types.h
+++ b/src/include/common/types.h
@@ -71,6 +71,7 @@ typedef __u32 u32;
 typedef int64_t s64;
 typedef uint64_t u64;
 
+typedef uint8_t byte_size_t;
 
 #ifndef __kernel_long_t
 typedef long		__kernel_long_t;
@@ -146,7 +147,7 @@ typedef __kernel_long_t	__kernel_time_t;
 typedef long long __kernel_time64_t;
 typedef __kernel_long_t	__kernel_clock_t;
 typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
+typedef int		__kernel_clock_ids_t;
 typedef char *		__kernel_caddr_t;
 typedef unsigned short	__kernel_uid16_t;
 typedef unsigned short	__kernel_gid16_t;
diff --git a/src/include/lib/math.h b/src/include/lib/math.h
new file mode 100644
index 0000000000000000000000000000000000000000..6905bf8ea086d1e0af0224eca37c6c3084ba5a9a
--- /dev/null
+++ b/src/include/lib/math.h
@@ -0,0 +1,7 @@
+#pragma once
+
+/* Rounding; only works for n = power of two */
+#define ROUND(a, n) (((((uint64_t)(a)) + (n)-1)) & ~((n)-1))
+#define ROUNDDOWN(a, n) (((uint64_t)(a)) & ~((n)-1))
+
+int k_min(int a, int b);
\ No newline at end of file
diff --git a/src/include/lib/string.h b/src/include/lib/string.h
index 2a8db624b3440f88dfeb1b6441c0db072592b629..1ea374481dffb67cad396a335e9996d529b5e361 100644
--- a/src/include/lib/string.h
+++ b/src/include/lib/string.h
@@ -2,10 +2,11 @@
 
 #include <common/types.h>
 
-void memcpy(uint8_t *dest, const uint8_t *src, uint32_t len);
-void memset(void *dest, uint8_t val, uint32_t len);
-void bzero(void *dest, uint32_t len);
-int strcmp(const char *str1, const char *str2);
-char *strcpy(char *dest, const char *src);
-char *strcat(char *dest, const char *src);
-int strlen(const char *src);
+void k_memcpy(uint8_t *dest, const uint8_t *src, uint32_t len);
+void k_memset(void *dest, uint8_t val, uint32_t len);
+void k_bzero(void *dest, uint32_t len);
+int k_strcmp(const char *str1, const char *str2);
+char *k_strcpy(char *dest, const char *src);
+char *k_strcat(char *dest, const char *src);
+int k_strlen(const char *src);
+int k_strlistlen(char *src[]);
\ No newline at end of file
diff --git a/src/include/os/cpu.h b/src/include/os/cpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..ecccd28f0ff3cbd5cfa57dd73061886bff711b42
--- /dev/null
+++ b/src/include/os/cpu.h
@@ -0,0 +1,4 @@
+#pragma once
+
+#define CPU_NUM 2
+#define CPU_SET_SIZE 1
\ No newline at end of file
diff --git a/src/include/os/mm.h b/src/include/os/mm.h
index 2d96b3f21a5d4085c112d04148ac00b32474ecaf..9a98c01e66368fd64561d48259fb06d3d10eadeb 100644
--- a/src/include/os/mm.h
+++ b/src/include/os/mm.h
@@ -23,34 +23,34 @@
 #define MAP_PRIVATE 0X02
 #define MAP_FAILED ((void *) -1)
 
-/* Rounding; only works for n = power of two */
-#define ROUND(a, n) (((((uint64_t)(a)) + (n)-1)) & ~((n)-1))
-#define ROUNDDOWN(a, n) (((uint64_t)(a)) & ~((n)-1))
+#define MAP_KERNEL 1
+#define MAP_USER 2
 
 typedef uint64_t PTE;
 extern ptr_t memCurr;
 extern int diskpg_num;
 extern uint64_t diskpg[1000];
 
-void movetodisk(uint64_t pg_kva, uint64_t user_va);
-void getbackdisk(uint64_t va, uint64_t new_addr);
+void k_move_to_disk(uint64_t pg_kva, uint64_t user_va);
+void k_get_back_disk(uint64_t va, uint64_t new_addr);
 void en_invalid(uint64_t pa_kva, PTE *pgdir);
-ptr_t allocmem(int numPage, uint64_t user_va);
-ptr_t allocPage(int numPage);
+ptr_t k_alloc_mem(int numPage, uint64_t user_va);
+ptr_t k_alloc_page(int numPage);
 void fork_pgtable(PTE *dest_pgdir, PTE *src_pgdir);
 void fork_page_helper(uintptr_t va, PTE *destpgdir, PTE *srcpgdir);
 uint64_t get_kva_from_va(uint64_t va, PTE *pgdir);
 long sys_getpa(uint64_t va);
 void map_kp(uint64_t va, uint64_t pa, PTE *pgdir);
 
-// ptr_t allocPage(int numPage);
-void freePage(ptr_t baseAddr, int numPage);
-void *kmalloc(size_t size);
+void k_free_page(ptr_t baseAddr, int numPage);
+void *k_malloc(size_t size);
 void share_pgtable(PTE *dest_pgdir, PTE *src_pgdir);
-uintptr_t alloc_page_helper(uintptr_t va, PTE *pgdir);
-long sys_shm_page_get(int key);
-long sys_shm_page_dt(uintptr_t addr);
+uintptr_t k_alloc_page_helper(uintptr_t va, PTE *pgdir);
+long shm_page_get(int key);
+long shm_page_dt(uintptr_t addr);
 void map(uint64_t va, uint64_t pa, PTE *pgdir);
 void getback_page(int pid);
 PTE *get_kva(PTE entry);
 void cancelpg(PTE *pgdir);
+
+long sys_brk(unsigned long brk);
\ No newline at end of file
diff --git a/src/include/os/pcb.h b/src/include/os/pcb.h
index 02a5d527ddaa73b7441f2d8414c7310dd694cee3..cfa28d34a0df5fa16f44874b7e39ef8e328a0481 100644
--- a/src/include/os/pcb.h
+++ b/src/include/os/pcb.h
@@ -1,9 +1,11 @@
 #pragma once
 
 #include <asm/context.h>
-#include <common/types.h>
+#include <common/elf.h>
 #include <lib/list.h>
+#include <os/cpu.h>
 #include <os/mm.h>
+#include <os/sync.h>
 #include <os/time.h>
 
 #define NUM_MAX_PRCESS 16
@@ -31,17 +33,34 @@
 #define	PRIO_PGRP	1
 #define	PRIO_USER	2
 
-#define ENQUEUE_LIST                0
-#define ENQUEUE_PCB                 1
-#define DEQUEUE_LIST                0
-#define DEQUEUE_WAITLIST            1
-#define DEQUEUE_WAITLIST_DESTROY    2
-#define DEQUEUE_LIST_STRATEGY       3
-
-#define UNBLOCK_TO_LIST_FRONT       0
-#define UNBLOCK_TO_LIST_BACK        1
-#define UNBLOCK_ONLY                2
-#define UNBLOCK_TO_LIST_STRATEGY    3
+/*
+ * cloning flags:
+ */
+#define CSIGNAL		0x000000ff	/* signal mask to be sent at exit */
+#define CLONE_VM	0x00000100	/* set if VM shared between processes */
+#define CLONE_FS	0x00000200	/* set if fs info shared between processes */
+#define CLONE_FILES	0x00000400	/* set if open files shared between processes */
+#define CLONE_SIGHAND	0x00000800	/* set if signal handlers and blocked signals shared */
+#define CLONE_PIDFD	0x00001000	/* set if a pidfd should be placed in parent */
+#define CLONE_PTRACE	0x00002000	/* set if we want to let tracing continue on the child too */
+#define CLONE_VFORK	0x00004000	/* set if the parent wants the child to wake it up on mm_release */
+#define CLONE_PARENT	0x00008000	/* set if we want to have the same parent as the cloner */
+#define CLONE_THREAD	0x00010000	/* Same thread group? */
+#define CLONE_NEWNS	0x00020000	/* New mount namespace group */
+#define CLONE_SYSVSEM	0x00040000	/* share system V SEM_UNDO semantics */
+#define CLONE_SETTLS	0x00080000	/* create a new TLS for the child */
+#define CLONE_PARENT_SETTID	0x00100000	/* set the TID in the parent */
+#define CLONE_CHILD_CLEARTID	0x00200000	/* clear the TID in the child */
+#define CLONE_DETACHED		0x00400000	/* Unused, ignored */
+#define CLONE_UNTRACED		0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
+#define CLONE_CHILD_SETTID	0x01000000	/* set the TID in the child */
+#define CLONE_NEWCGROUP		0x02000000	/* New cgroup namespace */
+#define CLONE_NEWUTS		0x04000000	/* New utsname namespace */
+#define CLONE_NEWIPC		0x08000000	/* New ipc namespace */
+#define CLONE_NEWUSER		0x10000000	/* New user namespace */
+#define CLONE_NEWPID		0x20000000	/* New pid namespace */
+#define CLONE_NEWNET		0x40000000	/* New network namespace */
+#define CLONE_IO		0x80000000	/* Clone io context */
 
 typedef void (*void_task)();
 
@@ -51,26 +70,58 @@ typedef struct prior
     uint64_t last_sched_time;
 } prior_t;
 
-typedef enum {
+typedef enum task_status {
     TASK_BLOCKED,
     TASK_RUNNING,
     TASK_READY,
-    TASK_ZOMBIE,
     TASK_EXITED,
 } task_status_t;
 
-typedef enum {
-    ENTER_ZOMBIE_ON_EXIT,
-    AUTO_CLEANUP_ON_EXIT,
-} spawn_mode_t;
-
-typedef enum {
+typedef enum task_type {
     KERNEL_PROCESS,
     KERNEL_THREAD,
     USER_PROCESS,
     USER_THREAD,
 } task_type_t;
 
+typedef enum enqueue_way {
+    ENQUEUE_LIST,
+    ENQUEUE_TIMER_LIST,
+} enqueue_way_t;
+
+typedef enum dequeue_way {
+    DEQUEUE_LIST,
+    DEQUEUE_WAITLIST,
+    DEQUEUE_WAITLIST_DESTROY,
+    DEQUEUE_LIST_STRATEGY,
+} dequeue_way_t;
+
+typedef enum unblock_way {
+    UNBLOCK_TO_LIST_FRONT,
+    UNBLOCK_TO_LIST_BACK,
+    UNBLOCK_ONLY,
+    UNBLOCK_TO_LIST_STRATEGY,
+} unblock_way_t;
+
+typedef struct rusage {
+	__kernel_timeval_t ru_utime;	/* user time used */
+	__kernel_timeval_t ru_stime;	/* system time used */
+	__kernel_long_t	ru_maxrss;	/* maximum resident set size */
+	__kernel_long_t	ru_ixrss;	/* integral shared memory size */
+	__kernel_long_t	ru_idrss;	/* integral unshared data size */
+	__kernel_long_t	ru_isrss;	/* integral unshared stack size */
+	__kernel_long_t	ru_minflt;	/* page reclaims */
+	__kernel_long_t	ru_majflt;	/* page faults */
+	__kernel_long_t	ru_nswap;	/* swaps */
+	__kernel_long_t	ru_inblock;	/* block input operations */
+	__kernel_long_t	ru_oublock;	/* block output operations */
+	__kernel_long_t	ru_msgsnd;	/* messages sent */
+	__kernel_long_t	ru_msgrcv;	/* messages received */
+	__kernel_long_t	ru_nsignals;	/* signals received */
+	__kernel_long_t	ru_nvcsw;	/* voluntary context switches */
+	__kernel_long_t	ru_nivcsw;	/* involuntary " */
+} rusage_t;
+
 /* Process Control Block */
 typedef struct pcb {
     /* register context */
@@ -78,33 +129,34 @@ typedef struct pcb {
     reg_t kernel_sp;
     reg_t user_sp;
 
-    // count the number of disable_preempt
-    // enable_preempt enables CSR_SIE only when preempt_count == 0
-    reg_t preempt_count;
-
-    ptr_t kernel_stack_base;
-    ptr_t user_stack_base;
-
     /* previous, next pointer */
     list_node_t list;
     list_head wait_list;
+
+    regs_context_t *save_context;
+    switchto_context_t *switch_context;
+
+    bool in_use;
+    ELF_info_t elf;
+
     /* process id */
     pid_t pid;          // real offset of pcb[]
     pid_t fpid;         // threads' fpid is process pid
     pid_t tid;
+    uint32_t *clear_ctid;
     pid_t father_pid;
-    pid_t child_pid[NUM_MAX_CHILD];
+    pid_t child_pids[NUM_MAX_CHILD];
     int child_num;
     int *child_stat_addrs[NUM_MAX_CHILD];
     int threadsum;
-    int threadid[NUM_MAX_CHILD_THREADS];
+    int thread_ids[NUM_MAX_CHILD_THREADS];
 
     /* kernel/user thread/process */
     task_type_t type;
 
     /* BLOCK | READY | RUNNING | ZOMBIE */
     task_status_t status;
-    spawn_mode_t mode;
+    int exit_status;
 
     /* cursor position */
     int cursor_x;
@@ -112,48 +164,24 @@ typedef struct pcb {
 
     prior_t priority;
 
-    int locksum;
-    int lockid[NUM_MAX_LOCK];
+    uint8_t core_mask[CPU_SET_SIZE];
+    
+    uint64_t pgdir;
 
-    int mboxsum;
-    int mboxid[NUM_MAX_MBOX];
+    int locksum;
+    int lock_ids[NUM_MAX_LOCK];
 
-    int core_mask;
-    uint64_t pgdir;
-    int port;
+    pcb_mbox_t mbox;
 
     /* time */
-    __kernel_time_t stime;
-    __kernel_time_t stime_last;     // last time into kernel
-    __kernel_time_t utime;
-    __kernel_time_t utime_last;     // last time out kernel
+    __kernel_timeval_t stime_last;     // last time into kernel
+    __kernel_timeval_t utime_last;     // last time out kernel
     pcbtimer_t timer;
-} pcb_t;
-
-/* task information, used to init PCB */
-typedef struct task_info {
-    ptr_t entry_point;
-    task_type_t type;
-} task_info_t;
+    __kernel_clock_t dead_child_stime;
+    __kernel_clock_t dead_child_utime;
 
-typedef struct rusage {
-	__kernel_timeval_t ru_utime;	/* user time used */
-	__kernel_timeval_t ru_stime;	/* system time used */
-	__kernel_long_t	ru_maxrss;	/* maximum resident set size */
-	__kernel_long_t	ru_ixrss;	/* integral shared memory size */
-	__kernel_long_t	ru_idrss;	/* integral unshared data size */
-	__kernel_long_t	ru_isrss;	/* integral unshared stack size */
-	__kernel_long_t	ru_minflt;	/* page reclaims */
-	__kernel_long_t	ru_majflt;	/* page faults */
-	__kernel_long_t	ru_nswap;	/* swaps */
-	__kernel_long_t	ru_inblock;	/* block input operations */
-	__kernel_long_t	ru_oublock;	/* block output operations */
-	__kernel_long_t	ru_msgsnd;	/* messages sent */
-	__kernel_long_t	ru_msgrcv;	/* messages received */
-	__kernel_long_t	ru_nsignals;	/* signals received */
-	__kernel_long_t	ru_nvcsw;	/* voluntary context switches */
-	__kernel_long_t	ru_nivcsw;	/* involuntary " */
-} rusage_t;
+    rusage_t resources;
+} pcb_t;
 
 
 /* current running task PCB */
@@ -162,9 +190,6 @@ extern pcb_t *volatile current_running1;
 extern pcb_t **volatile current_running;
 /* ready queue to run */
 extern list_head ready_queue;
-// pcb_t * volatile (*current_running)[NR_CPUS];
-extern pid_t process_id;
-extern int allocpid;
 
 extern pcb_t pcb[NUM_MAX_TASK];
 // pcb_t kernel_pcb[NR_CPUS];
@@ -173,41 +198,31 @@ extern const ptr_t pid0_stack2;
 extern pcb_t pid0_pcb;
 extern pcb_t pid0_pcb2;
 
-extern int freepidnum;
-extern int nowpid;
-extern int glmask;
-extern int glvalid;
-
 extern pid_t freepid[NUM_MAX_TASK];
 
-pid_t nextpid();
-
-void init_pcb();
-int check_pcb(int cpuid);
-
-void switch_to(pcb_t *prev, pcb_t *next);
+void k_init_pcb();
+extern void switch_to(pcb_t *prev, pcb_t *next);
 long k_scheduler(void);
+void k_block(list_head *, list_head *queue, enqueue_way_t way);
+void k_unblock(list_head *, list_head *, unblock_way_t way);
+long k_getpid(void);
+
 long sys_sched_yield(void);
 long sys_nanosleep(nanotime_val_t *rqtp, nanotime_val_t *rmtp);
-void check_sleeping();
-
-void k_block(list_head *, list_head *queue);
-void k_unblock(list_head *, list_head *, int way);
-long k_taskset(int pid, int mask);
-
-long sys_spawn(task_info_t *task, void *arg, spawn_mode_t mode);
-long sys_fork(int prior);
-// long sys_execve(const char *filename, const char **argv, const char **envp);
-// long sys_clone(int (*fn)(void *), void *stack, int flags, void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid);
+long sys_spawn(const char *file_name);
+long sys_fork(void);
+long sys_exec(const char *file_name, const char *argv[], const char *envp[]);
+long sys_execve(const char *file_name, const char *argv[], const char *envp[]);
+long sys_clone(unsigned long flags, void *stack, void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid);
 long sys_kill(pid_t pid);
 long sys_exit(int error_code);
 long sys_wait4(pid_t pid, int *stat_addr, int options, rusage_t *ru);
 long sys_process_show();
-long sys_exec(const char *file_name, int argc, char **argv);
-long sys_show_exec();
 long sys_setpriority(int which, int who, int niceval);
 long sys_getpriority(int which, int who);
 long sys_getpid(void);
 long sys_getppid(void);
-
-long sys_mthread_create(pid_t *thread, void (*start_routine)(void *), void *arg);
\ No newline at end of file
+long sys_sched_setaffinity(pid_t pid, unsigned int len,
+					const uint8_t *user_mask_ptr);
+long sys_sched_getaffinity(pid_t pid, unsigned int len,
+					uint8_t *user_mask_ptr);
\ No newline at end of file
diff --git a/src/include/os/sync.h b/src/include/os/sync.h
index c645ed747900caa4725123c469d62f907877d3ea..a89dcc752bd90af2c5db2c4c910c9034706cedbb 100644
--- a/src/include/os/sync.h
+++ b/src/include/os/sync.h
@@ -6,6 +6,10 @@
 #define MBOX_NAME_LEN 64
 #define MBOX_MSG_MAX_LEN 128
 #define MBOX_MAX_USER 10
+
+#define PCB_MBOX_MAX_MSG_NUM 16
+#define PCB_MBOX_MSG_MAX_LEN 256
+
 typedef struct basic_info{
     int id;
     int initialized;
@@ -44,12 +48,19 @@ typedef struct mbox{
     int cited_pid[MBOX_MAX_USER];
 } mbox_t;
 
-typedef struct mbox_arg{
+typedef struct mbox_arg {
     void *msg;
     int msg_length;
     int sleep_operation;
 } mbox_arg_t;
 
+typedef struct pcb_mbox {
+    int pcb_i;
+    char buff[PCB_MBOX_MAX_MSG_NUM][PCB_MBOX_MSG_MAX_LEN];
+    int read_head, write_head;
+    int used_units;
+} pcb_mbox_t;
+
 int k_commop(void *key_id, void *arg, int op);
 
 int k_semaphore_init(int *key, int sem);
@@ -70,7 +81,11 @@ int k_barrier_destroy(int *key);
 
 int k_mbox_open(char *name);
 int k_mbox_close();
-int k_mbox_send(int key, mbox_arg_t *arg);
-int k_mbox_recv(int key, mbox_arg_t *arg);
+int k_mbox_send(int key, mbox_t *target, mbox_arg_t *arg);
+int k_mbox_recv(int key, mbox_t *target, mbox_arg_t *arg);
 int k_mbox_try_send(int key, mbox_arg_t *arg);
-int k_mbox_try_recv(int key, mbox_arg_t *arg);
\ No newline at end of file
+int k_mbox_try_recv(int key, mbox_arg_t *arg);
+
+void k_pcb_mbox_init(pcb_mbox_t *target, int owner_id);
+int sys_mailread(void* buf, int len);
+int sys_mailwrite(int pid, void* buf, int len);
\ No newline at end of file
diff --git a/src/include/os/time.h b/src/include/os/time.h
index 59db138599e434a7565834eb5502f08aa3242fef..f6e0be430eeac39ddbb3119e5166a2cfedae9360 100644
--- a/src/include/os/time.h
+++ b/src/include/os/time.h
@@ -28,8 +28,8 @@ typedef struct timezone {
 
 typedef struct pcbtimer {
 	bool initialized;
-    nanotime_val_t time;
     nanotime_val_t start_time;
+    nanotime_val_t end_time;
     nanotime_val_t *remain_time;
 } pcbtimer_t;
 
@@ -43,12 +43,16 @@ long get_ticks(void);
 void nano_u_time_converter(nanotime_val_t *nanotime, time_val_t *utime, bool direction);
 
 void get_nanotime(nanotime_val_t *ntimebuf);
+uint64_t get_ticks_from_nanotime(nanotime_val_t *ntimebuf);
 void copy_nanotime(nanotime_val_t *src, nanotime_val_t *dst);
 void minus_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *res);
+void add_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *res);
 int cmp_nanotime(nanotime_val_t *first, nanotime_val_t *sec);
 void get_utime(time_val_t *ntimebuf);
+uint64_t get_ticks_from_time(time_val_t *timebuf);
 void copy_utime(time_val_t *src, time_val_t *dst);
 void minus_utime(time_val_t *first, time_val_t *sec, time_val_t *res);
+void add_utime(time_val_t *first, time_val_t *sec, time_val_t *res);
 int cmp_utime(time_val_t *first, time_val_t *sec);
 
 long sys_time(__kernel_time_t *tloc);
diff --git a/src/init/main.c b/src/init/main.c
index 3ce28e38dab910ff3a3a69a227275b79d4ae01bf..758aa00271c7dc8c09087f8c45ad30494c2d4261 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -17,6 +17,7 @@
 int main() {
     int id = get_current_cpu_id();
     if (id == 1) {
+        (*current_running) = get_current_running();
         setup_exception();
         cancelpg(pa2kva(PGDIR_PA));
         sbi_set_timer(0);
@@ -27,7 +28,7 @@ int main() {
 
     // init Process Control Block (-_-!)
 
-    init_pcb();
+    k_init_pcb();
 
     // printk("> [INIT] PCB initialization succeeded.\n\r");
 
diff --git a/src/kernel/irq/irq.c b/src/kernel/irq/irq.c
index e6fed17eecee15551e59007a137abbd9f9590360..dfe8e2e88bd5af693836bac409845f2695a42ce8 100644
--- a/src/kernel/irq/irq.c
+++ b/src/kernel/irq/irq.c
@@ -36,6 +36,9 @@ void init_syscall(void) {
     // syscall[SYS_read] = (long (*)())sys_read;
     // syscall[SYS_write] = (long (*)())sys_write;
     // syscall[SYS_fstat] = (long (*)())sys_fstat;
+    // syscall[SYS_munmap] = (long (*)())sys_munmap;
+    // syscall[SYS_mremap] = (long (*)())sys_mremap;
+    // syscall[SYS_mmap] = (long (*)())sys_mmap;
     // Terminal
     syscall[SYS_uname] = (long (*)())sys_uname;
     // Functions
@@ -43,12 +46,12 @@ void init_syscall(void) {
     syscall[SYS_times] = (long (*)())sys_times;
     syscall[SYS_time] = (long (*)())sys_time;
     syscall[SYS_gettimeofday] = (long (*)())sys_gettimeofday;
-    // syscall[SYS_mailread] = (long (*)())sys_mailread;
-    // syscall[SYS_mailwrite] = (long (*)())sys_mailwrite;
+    syscall[SYS_mailread] = (long (*)())sys_mailread;
+    syscall[SYS_mailwrite] = (long (*)())sys_mailwrite;
     // Process & Threads
     syscall[SYS_exit] = (long (*)())sys_exit;
-    // syscall[SYS_clone] = (long (*)())sys_clone;
-    // syscall[SYS_execve] = (long (*)())sys_execve;
+    syscall[SYS_clone] = (long (*)())sys_clone;
+    syscall[SYS_execve] = (long (*)())sys_execve;
     syscall[SYS_wait4] = (long (*)())sys_wait4;
     syscall[SYS_spawn] = (long (*)())sys_spawn;
     syscall[SYS_sched_yield] = (long (*)())sys_sched_yield;
@@ -56,10 +59,10 @@ void init_syscall(void) {
     syscall[SYS_get_mempolicy] = (long (*)())sys_getpriority;
     syscall[SYS_getpid] = (long (*)())sys_getpid;
     syscall[SYS_getppid] = (long (*)())sys_getppid;
+    syscall[SYS_sched_setaffinity] = (long (*)())sys_sched_setaffinity;
+
     // Memory
-    // syscall[SYS_brk] = (long (*)())sys_brk;
-    // syscall[SYS_munmap] = (long (*)())sys_munmap;
-    // syscall[SYS_mmap] = (long (*)())sys_mmap;
+    syscall[SYS_brk] = (long (*)())sys_brk;
 }
 
 void reset_irq_timer() {
@@ -74,9 +77,12 @@ void interrupt_helper(regs_context_t *regs, uint64_t stval, uint64_t cause, uint
     lock_kernel();
     // call corresponding handler by the value of `cause`
     (*current_running) = get_current_running();
-    long ticks = get_ticks();
-    (*current_running)->utime += (ticks - (*current_running)->utime_last);
-    (*current_running)->stime_last = ticks;
+    time_val_t now;
+    get_utime(&now);
+    time_val_t last_run;
+    minus_utime(&now, &(*current_running)->utime_last, &last_run);
+    add_utime(&last_run, &(*current_running)->resources.ru_utime, &(*current_running)->resources.ru_utime);
+    copy_utime(&now, &(*current_running)->stime_last);
     uint64_t check = cause;
     // if(check>>63 && check%16!=5)
     //{
@@ -88,36 +94,41 @@ void interrupt_helper(regs_context_t *regs, uint64_t stval, uint64_t cause, uint
     } else {
         exc_table[cause](regs, stval, cause, cpuid);
     }
-    ticks = get_ticks();
-    (*current_running)->utime_last = ticks;
-    (*current_running)->stime += (ticks - (*current_running)->stime_last);
+    get_utime(&now);
+    copy_utime(&now, &(*current_running)->utime_last);
+    minus_utime(&now, &(*current_running)->stime_last, &last_run);
+    add_utime(&last_run, &(*current_running)->resources.ru_stime, &(*current_running)->resources.ru_stime);
     unlock_kernel();
 }
 
-void handle_int(regs_context_t *regs, uint64_t interrupt, uint64_t cause, uint64_t cpuid) { reset_irq_timer(); }
+void handle_int(regs_context_t *regs, uint64_t interrupt, uint64_t cause, uint64_t cpuid) {
+    reset_irq_timer();
+}
 
 PTE *check_pf(uint64_t va, PTE *pgdir) {
     va &= VA_MASK;
     uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS);
     uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS));
     uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
-    if (pgdir[vpn2] == 0)
+    if (pgdir[vpn2] == 0) {
         return 0;
+    }
     PTE *pmd = get_kva(pgdir[vpn2]);
-    if (pmd[vpn1] == 0)
+    if (pmd[vpn1] == 0) {
         return 0;
+    }
     PTE *pld = get_kva(pmd[vpn1]);
-    if (pld[vpn0] == 0)
+    if (pld[vpn0] == 0) {
         return 0;
+    }
     return &pld[vpn0];
 }
 
 void handle_disk(uint64_t stval, PTE *pte_addr) {
     pcb_t *cur = *current_running;
-    allocpid = cur->pid;
-    uint64_t newmem_addr = allocmem(1, stval);
+    uint64_t newmem_addr = k_alloc_mem(1, stval);
     map(stval, kva2pa(newmem_addr), (pa2kva(cur->pgdir << 12)));
-    getbackdisk(stval, newmem_addr);
+    k_get_back_disk(stval, newmem_addr);
     (*pte_addr) = (*pte_addr) | 1;
 }
 
@@ -129,26 +140,25 @@ void handle_pf(regs_context_t *regs, uint64_t stval, uint64_t cause, uint64_t cp
         PTE va_pte = *pte_addr;
         if (cause == EXCC_STORE_PAGE_FAULT) {
             // child process
-            allocpid = cur->pid;
             if (cur->father_pid != cur->pid) {
                 fork_page_helper(stval, (pa2kva(cur->pgdir << 12)), (pa2kva(pcb[cur->father_pid].pgdir << 12)));
             } else {
                 // father process
                 for (int i = 0; i < cur->child_num; i++) {
-                    fork_page_helper(stval, (pa2kva(pcb[cur->child_pid[i]].pgdir << 12)), (pa2kva(cur->pgdir << 12)));
+                    fork_page_helper(stval, (pa2kva(pcb[cur->child_pids[i]].pgdir << 12)), (pa2kva(cur->pgdir << 12)));
                 }
             }
             *pte_addr = (*pte_addr) | (3 << 6);
             *pte_addr = (*pte_addr) | ((uint64_t)1 << 2);
-        } else if (cause == EXCC_INST_PAGE_FAULT)
+        } else if (cause == EXCC_INST_PAGE_FAULT) {
             *pte_addr = (*pte_addr) | (3 << 6);
-        else if ((((va_pte >> 6) & 1) == 0) && (cause == EXCC_LOAD_PAGE_FAULT))
+        } else if ((((va_pte >> 6) & 1) == 0) && (cause == EXCC_LOAD_PAGE_FAULT)) {
             *pte_addr = (*pte_addr) | ((uint64_t)1 << 6);
-        else if ((va_pte & 1) == 0) // physical frame was on disk
+        } else if ((va_pte & 1) == 0) { // physical frame was on disk
             handle_disk(stval, pte_addr);
+        }
     } else { // No virtual-physical map
-        allocpid = cur->pid;
-        alloc_page_helper(stval, (pa2kva(cur->pgdir << 12)));
+        k_alloc_page_helper(stval, (pa2kva(cur->pgdir << 12)));
         local_flush_tlb_all();
     }
 }
diff --git a/src/kernel/mm/mm.c b/src/kernel/mm/mm.c
index b3da2df8892327509a1e34f7592e46a71673ef37..0fe9938da056d33ca7103e0992ddc787b9a21667 100644
--- a/src/kernel/mm/mm.c
+++ b/src/kernel/mm/mm.c
@@ -1,7 +1,9 @@
 #include <asm/pgtable.h>
 #include <asm/sbi.h>
+#include <common/elf.h>
 #include <drivers/screen.h>
 #include <lib/assert.h>
+#include <lib/math.h>
 #include <os/mm.h>
 #include <os/pcb.h>
 #include <os/smp.h>
@@ -36,8 +38,9 @@ PTE *get_kva(PTE entry) {
 }
 
 void getback_page(int pid) {
-    if (freepg_num >= 999)
+    if (freepg_num >= 999) {
         return;
+    }
     for (int i = 1; i <= allpg[pid][0]; i++) {
         freepg_num++;
         freepg[freepg_num] = allpg[pid][i];
@@ -52,10 +55,11 @@ void getback_page(int pid) {
 }
 
 // start block = 250
-void movetodisk(uint64_t pg_kva, uint64_t user_va) {
+void k_move_to_disk(uint64_t pg_kva, uint64_t user_va) {
     // one block = 512B = 0.5KB
-    if (diskpg_num >= 999)
+    if (diskpg_num >= 999) {
         assert(0);
+    }
     sys_screen_move_cursor(1, 5);
     prints("[k] From 0x%x to disk sector %d, for user_vaddr 0x%x\n", pg_kva, START_BLOCK + diskpg_num * 2, user_va);
 
@@ -66,7 +70,7 @@ void movetodisk(uint64_t pg_kva, uint64_t user_va) {
     clear_pgdir(pg_kva);
 }
 
-void getbackdisk(uint64_t user_va, uint64_t new_addr) {
+void k_get_back_disk(uint64_t user_va, uint64_t new_addr) {
     int flag = 0;
     for (int i = 0; i < diskpg_num; i++) {
         if (diskpg[i] == user_va) {
@@ -78,8 +82,9 @@ void getbackdisk(uint64_t user_va, uint64_t new_addr) {
             break;
         }
     }
-    if (flag == 0)
+    if (flag == 0) {
         assert(0);
+    }
 }
 
 void en_invalid(uint64_t va, PTE *pgdir) {
@@ -87,26 +92,31 @@ void en_invalid(uint64_t va, PTE *pgdir) {
     uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS);
     uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS));
     uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
-    if (pgdir[vpn2] == 0)
+    if (pgdir[vpn2] == 0) {
         assert(0);
+    }
     PTE *pmd = get_kva(pgdir[vpn2]);
-    if (pmd[vpn1] == 0)
+    if (pmd[vpn1] == 0) {
         assert(0);
+    }
     PTE *pld = get_kva(pmd[vpn1]);
     pld[vpn0] = (pld[vpn0] >> 1) << 1;
 }
 
-ptr_t allocmem(int numPage, uint64_t user_va) {
+ptr_t k_alloc_mem(int numPage, uint64_t user_va) {
     ptr_t ret;
+    int allocpid = (*current_running)->pid;
     if (allmem[allocpid][0] >= MAXPAGES) {
         // no enough page allowed
         ret = allmem[allocpid][STARTPAGE];
-        movetodisk(allmem[allocpid][STARTPAGE], alluserva[allocpid][STARTPAGE]);
+        k_move_to_disk(allmem[allocpid][STARTPAGE], alluserva[allocpid][STARTPAGE]);
         en_invalid(alluserva[allocpid][STARTPAGE], (pa2kva(pcb[allocpid].pgdir << 12)));
-        for (int i = STARTPAGE; i < allmem[allocpid][0]; i++)
+        for (int i = STARTPAGE; i < allmem[allocpid][0]; i++) {
             allmem[allocpid][i] = allmem[allocpid][i + 1];
-        for (int i = STARTPAGE; i < alluserva[allocpid][0]; i++)
+        }
+        for (int i = STARTPAGE; i < alluserva[allocpid][0]; i++) {
             alluserva[allocpid][i] = alluserva[allocpid][i + 1];
+        }
         allmem[allocpid][allmem[allocpid][0]] = ret;
         alluserva[allocpid][alluserva[allocpid][0]] = user_va;
         return ret;
@@ -119,8 +129,9 @@ ptr_t allocmem(int numPage, uint64_t user_va) {
         freepg_num--;
     }
     if (allocpid != 0) {
-        if (allmem[allocpid][0] >= MAXPAGES)
+        if (allmem[allocpid][0] >= MAXPAGES) {
             return ret;
+        }
         allmem[allocpid][0]++;
         allmem[allocpid][allmem[allocpid][0]] = ret;
         alluserva[allocpid][0]++;
@@ -130,7 +141,7 @@ ptr_t allocmem(int numPage, uint64_t user_va) {
     return ret;
 }
 // return kva
-ptr_t allocPage(int numPage) {
+ptr_t k_alloc_page(int numPage) {
     ptr_t ret;
     if (freepg_num == 0) {
         ret = ROUND(memCurr, PAGE_SIZE);
@@ -139,9 +150,11 @@ ptr_t allocPage(int numPage) {
         ret = freepg[freepg_num];
         freepg_num--;
     }
+    int allocpid = (*current_running)->pid;
     if (allocpid != 0) {
-        if (allpg[allocpid][0] >= 98)
+        if (allpg[allocpid][0] >= 98) {
             return ret;
+        }
         allpg[allocpid][0]++;
         allpg[allocpid][allpg[allocpid][0]] = ret;
     }
@@ -149,27 +162,31 @@ ptr_t allocPage(int numPage) {
     return ret;
 }
 
-void *kmalloc(size_t size) {
+void k_free_page(ptr_t baseAddr, int numPage) {}
+
+void *k_malloc(size_t size) {
     ptr_t ret = ROUND(memCurr, 4);
     memCurr = ret + size;
     return (void *)ret;
 }
 
 uint64_t alloc_newva() {
+    int allocpid = (*current_running)->pid;
     for (uint64_t i = 0x100000; i < 0x1000000; i += 0x1000) {
         int flag = 1;
         for (int j = 1; j <= alluserva[allocpid][0]; j++) {
-            if (i == alluserva[allocpid][j])
+            if (i == alluserva[allocpid][j]) {
                 flag = 0;
+            }
         }
-        if (flag)
+        if (flag) {
             return i;
+        }
     }
     return 0;
 }
 
-long sys_shm_page_get(int key) {
-    allocpid = (*current_running)->pid;
+long shm_page_get(int key) {
     for (int i = 0; i < shm_num; i++) {
         if (shm_all[i].key == key && shm_all[i].pro_num != 0) {
             map(shm_all[i].uva, kva2pa(shm_all[i].kva), (pa2kva((*current_running)->pgdir << 12)));
@@ -184,19 +201,20 @@ long sys_shm_page_get(int key) {
             break;
         }
     }
-    allocpid = (*current_running)->pid;
-    if (num == -1)
+    if (num == -1) {
         num = shm_num;
+    }
     shm_all[num].key = key;
     shm_all[num].uva = alloc_newva();
-    shm_all[num].kva = alloc_page_helper(shm_all[num].uva, (pa2kva((*current_running)->pgdir << 12)));
+    shm_all[num].kva = k_alloc_page_helper(shm_all[num].uva, (pa2kva((*current_running)->pgdir << 12)));
     shm_all[num].pro_num = 1;
-    if (num == shm_num)
+    if (num == shm_num) {
         shm_num++;
+    }
     return shm_all[num].uva;
 }
 
-long sys_shm_page_dt(uintptr_t addr) {
+long shm_page_dt(uintptr_t addr) {
     for (int i = 0; i < shm_num; i++) {
         if (shm_all[i].uva == addr) {
             uint64_t va = addr;
@@ -205,11 +223,13 @@ long sys_shm_page_dt(uintptr_t addr) {
             uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS);
             uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS));
             uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
-            if (pgdir[vpn2] == 0)
+            if (pgdir[vpn2] == 0) {
                 assert(0);
+            }
             PTE *pmd = get_kva(pgdir[vpn2]);
-            if (pmd[vpn1] == 0)
+            if (pmd[vpn1] == 0) {
                 assert(0);
+            }
             PTE *pld = get_kva(pmd[vpn1]);
             pld[vpn0] = 0;
             // cancel finished
@@ -238,7 +258,7 @@ void share_pgtable(PTE *dest_pgdir, PTE *src_pgdir) {
 }
 
 void fork_pgtable(PTE *dest_pgdir, PTE *src_pgdir) {
-    uint64_t sva = USER_STACK_ADDR - 0x1000;
+    uint64_t sva = USER_STACK_ADDR - PAGE_SIZE;
     sva &= VA_MASK;
     uint64_t va = 0;
     // kernel not to clear write bit
@@ -278,30 +298,33 @@ void fork_pgtable(PTE *dest_pgdir, PTE *src_pgdir) {
 }
 
 void fork_page_helper(uintptr_t va, PTE *destpgdir, PTE *srcpgdir) {
-    uint64_t dest_kva = alloc_page_helper(va, destpgdir);
+    uint64_t dest_kva = k_alloc_page_helper(va, destpgdir);
     va &= VA_MASK;
     uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS);
     uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS));
     uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
-    if (srcpgdir[vpn2] == 0)
+    if (srcpgdir[vpn2] == 0) {
         assert(0);
+    }
     PTE *pmd = get_kva(srcpgdir[vpn2]);
-    if (pmd[vpn1] == 0)
+    if (pmd[vpn1] == 0) {
         assert(0);
+    }
     PTE *pld = get_kva(pmd[vpn1]);
     uint64_t src_kva = (uint64_t)get_kva(pld[vpn0]);
 
     unsigned char *src = (unsigned char *)src_kva;
     unsigned char *dest = (unsigned char *)dest_kva;
-    for (int i = 0; i < 0x1000; i++)
+    for (int i = 0; i < 0x1000; i++) {
         dest[i] = src[i];
+    }
 }
 
 /* allocate physical page for `va`, mapping it into `pgdir`,
    return the kernel virtual address for the page.
    */
-uintptr_t alloc_page_helper(uintptr_t va, PTE *pgdir) {
-    uint64_t kva = allocmem(1, va);
+uintptr_t k_alloc_page_helper(uintptr_t va, PTE *pgdir) {
+    uint64_t kva = k_alloc_mem(1, va);
     uint64_t pa = kva2pa(kva);
     map(va, pa, pgdir);
     return kva;
@@ -312,11 +335,13 @@ uint64_t get_kva_from_va(uint64_t va, PTE *pgdir) {
     uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS);
     uint64_t vpn1 = (vpn2 << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT + PPN_BITS));
     uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
-    if (pgdir[vpn2] == 0)
+    if (pgdir[vpn2] == 0) {
         assert(0);
+    }
     PTE *pmd = get_kva(pgdir[vpn2]);
-    if (pmd[vpn1] == 0)
+    if (pmd[vpn1] == 0) {
         assert(0);
+    }
     PTE *pld = get_kva(pmd[vpn1]);
     return (uint64_t)get_kva(pld[vpn0]);
 }
@@ -338,13 +363,13 @@ void map_kp(uint64_t va, uint64_t pa, PTE *pgdir) {
     uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
     if (pgdir[vpn2] == 0) {
         // alloc a new second-level page directory
-        set_pfn(&pgdir[vpn2], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT);
+        set_pfn(&pgdir[vpn2], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT);
         set_attribute(&pgdir[vpn2], _PAGE_PRESENT);
         clear_pgdir((uintptr_t)get_kva(pgdir[vpn2]));
     }
     PTE *pmd = get_kva(pgdir[vpn2]);
     if (pmd[vpn1] == 0) {
-        set_pfn(&pmd[vpn1], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT);
+        set_pfn(&pmd[vpn1], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT);
         set_attribute(&pmd[vpn1], _PAGE_PRESENT);
         clear_pgdir((uintptr_t)get_kva(pmd[vpn1]));
     }
@@ -374,13 +399,13 @@ void map(uint64_t va, uint64_t pa, PTE *pgdir) {
     uint64_t vpn0 = ((va >> (NORMAL_PAGE_SHIFT + PPN_BITS)) << PPN_BITS) ^ (va >> (NORMAL_PAGE_SHIFT));
     if (pgdir[vpn2] == 0) {
         // alloc a new second-level page directory
-        set_pfn(&pgdir[vpn2], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT);
+        set_pfn(&pgdir[vpn2], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT);
         set_attribute(&pgdir[vpn2], _PAGE_PRESENT);
         clear_pgdir((uintptr_t)get_kva(pgdir[vpn2]));
     }
     PTE *pmd = get_kva(pgdir[vpn2]);
     if (pmd[vpn1] == 0) {
-        set_pfn(&pmd[vpn1], kva2pa(allocPage(1)) >> NORMAL_PAGE_SHIFT);
+        set_pfn(&pmd[vpn1], kva2pa(k_alloc_page(1)) >> NORMAL_PAGE_SHIFT);
         set_attribute(&pmd[vpn1], _PAGE_PRESENT);
         clear_pgdir((uintptr_t)get_kva(pmd[vpn1]));
     }
@@ -401,4 +426,77 @@ void cancelpg(PTE *pgdir) {
         uint64_t vpn2 = va >> (NORMAL_PAGE_SHIFT + PPN_BITS + PPN_BITS);
         pgdir[vpn2] = 0;
     }
+}
+
+/* allocate physical page for `va`, mapping it into `pgdir`,
+   return the kernel virtual address for the page.
+   */
+
+uint32_t check_page_map(uintptr_t vta, uintptr_t pgdir) {
+    uint64_t vpn[] = {
+        (vta >> 12) & ~(~0 << 9), // vpn0
+        (vta >> 21) & ~(~0 << 9), // vpn1
+        (vta >> 30) & ~(~0 << 9)  // vpn2
+    };
+    PTE *page_base = (uint64_t *)pgdir;
+    PTE *second_page = NULL;
+    PTE *third_page = NULL;
+    if (((page_base[vpn[2]]) & _PAGE_PRESENT) == 0) {
+        return 1;
+    } else {
+        second_page = (PTE *)pa2kva((get_pfn(page_base[vpn[2]]) << NORMAL_PAGE_SHIFT));
+    }
+
+    if (((second_page[vpn[1]]) & _PAGE_PRESENT) == 0) {
+        return 1;
+    } else {
+        third_page = (PTE *)pa2kva((get_pfn(second_page[vpn[1]]) << NORMAL_PAGE_SHIFT));
+    }
+
+    if ((third_page[vpn[0]] & _PAGE_PRESENT) == 0) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+uintptr_t free_page_helper(uintptr_t va, uintptr_t pgdir) {
+    uint64_t vpn[] = {(va >> 12) & ~(~0 << 9), (va >> 21) & ~(~0 << 9), (va >> 30) & ~(~0 << 9)};
+    PTE *page_base = (uint64_t *)pgdir;
+    PTE *second_page = NULL;
+    PTE *third_page = NULL;
+    if ((page_base[vpn[2]] & _PAGE_PRESENT )== 0) {
+        return -1;
+    }
+    second_page = (PTE *)pa2kva((get_pfn(page_base[vpn[2]]) << NORMAL_PAGE_SHIFT));
+    if ((second_page[vpn[1]] & _PAGE_PRESENT) == 0) {
+        return -1;
+    }
+    third_page = (PTE *)pa2kva((get_pfn(second_page[vpn[1]]) << NORMAL_PAGE_SHIFT));
+    k_free_page(get_kva_of(va, pgdir), 1);
+    third_page[vpn[0]] = 0;
+    return 0;
+}
+
+long sys_brk(unsigned long brk) {
+    if (brk > ROUND((*current_running)->user_sp, NORMAL_PAGE_SIZE)) {
+        return -EINVAL;
+    }
+    if (brk == 0) {
+        return (*current_running)->elf.edata;
+    }
+    if (brk < (*current_running)->elf.edata) {
+        for (uintptr_t iterator = brk; iterator < (*current_running)->elf.edata; iterator += NORMAL_PAGE_SIZE) {
+            if (get_kva_of(iterator, (*current_running)->pgdir)) {
+                free_page_helper(iterator, (*current_running)->pgdir);
+            }
+        }
+    } else {
+        for (uintptr_t iterator = (*current_running)->elf.edata; iterator < brk; iterator += NORMAL_PAGE_SIZE) {
+            k_alloc_page_helper(iterator, (pa2kva((*current_running)->pgdir << 12)));
+            local_flush_tlb_all();
+        }
+    }
+    (*current_running)->elf.edata = brk;
+    return brk;
 }
\ No newline at end of file
diff --git a/src/kernel/sync/lock.c b/src/kernel/sync/lock.c
index 4073590bb005abe3711cfdc0043c17deec589452..a9cdad9e51d343649204953451085d857f68dad8 100644
--- a/src/kernel/sync/lock.c
+++ b/src/kernel/sync/lock.c
@@ -6,16 +6,22 @@
 int first_time = 1;
 mutex_lock_t *locks[LOCK_NUM];
 
-void spin_lock_init(spin_lock_t *lock) { lock->flag = UNLOCKED; }
+void spin_lock_init(spin_lock_t *lock) {
+    lock->flag = UNLOCKED;
+}
 
-int spin_lock_try_acquire(spin_lock_t *lock) { return atomic_swap_d(LOCKED, (ptr_t)&lock->flag); }
+int spin_lock_try_acquire(spin_lock_t *lock) {
+    return atomic_swap_d(LOCKED, (ptr_t)&lock->flag);
+}
 
 void spin_lock_acquire(spin_lock_t *lock) {
     while (spin_lock_try_acquire(lock) == LOCKED)
         ;
 }
 
-void spin_lock_release(spin_lock_t *lock) { lock->flag = UNLOCKED; }
+void spin_lock_release(spin_lock_t *lock) {
+    lock->flag = UNLOCKED;
+}
 
 long k_mutex_lock_op(int *key, int op) {
     if (op == 0) {
@@ -44,7 +50,7 @@ static inline int find_lock() {
 long k_mutex_lock_init(int *key) {
     if (first_time) {
         for (int i = 0; i < LOCK_NUM; i++) {
-            locks[i] = (mutex_lock_t *)kmalloc(sizeof(mutex_lock_t));
+            locks[i] = (mutex_lock_t *)k_malloc(sizeof(mutex_lock_t));
             locks[i]->initialized = 0;
         }
         first_time = 0;
@@ -78,10 +84,10 @@ long k_mutex_lock_acquire(int key) {
     if (locks[key]->lock.flag == 0) {
         locks[key]->lock.flag = 1;
         locks[key]->lock.guard = 0;
-        (*current_running)->lockid[(*current_running)->locksum++] = key + 1;
+        (*current_running)->lock_ids[(*current_running)->locksum++] = key + 1;
         return locks[key]->lock_id;
     } else {
-        k_block(&(*current_running)->list, &locks[key]->block_queue);
+        k_block(&(*current_running)->list, &locks[key]->block_queue, ENQUEUE_LIST);
         locks[key]->lock.guard = 0;
         k_scheduler();
         return -2;
@@ -93,7 +99,7 @@ long k_mutex_lock_release(int key) {
         return -1;
     }
     if ((*current_running)->locksum) {
-        (*current_running)->lockid[--(*current_running)->locksum] = 0;
+        (*current_running)->lock_ids[--(*current_running)->locksum] = 0;
     }
     while (atomic_cmpxchg(UNGUARDED, GUARDED, (ptr_t) & (locks[key]->lock.guard)) == GUARDED) {
         ;
@@ -112,9 +118,9 @@ long k_mutex_lock_destroy(int *key) {
         return -1;
     }
     while ((*current_running)->locksum) {
-        (*current_running)->lockid[--(*current_running)->locksum] = 0;
+        (*current_running)->lock_ids[--(*current_running)->locksum] = 0;
     }
-    memset(locks[*key - 1], 0, sizeof(locks[*key]));
+    k_memset(locks[*key - 1], 0, sizeof(mutex_lock_t *));
     *key = 0;
     return 0;
 }
diff --git a/src/kernel/sync/sync.c b/src/kernel/sync/sync.c
index d30614a0f30e346f7d81c12d16e5f90cd8044ed8..e797e31e4f33fd0faeaeeb723a6b187679ba365d 100644
--- a/src/kernel/sync/sync.c
+++ b/src/kernel/sync/sync.c
@@ -1,3 +1,4 @@
+#include <lib/math.h>
 #include <lib/string.h>
 #include <os/lock.h>
 #include <os/pcb.h>
@@ -85,11 +86,11 @@ int k_commop(void *key_id, void *arg, int op) {
     case 7:
         return k_mbox_open((char *)key_id);
     case 8:
-        return k_mbox_close();
+        return k_mbox_close((char *)key_id);
     case 9:
-        return k_mbox_send(*key - 1, (mbox_arg_t *)arg);
+        return k_mbox_send(*key - 1, NULL, (mbox_arg_t *)arg);
     case 10:
-        return k_mbox_recv(*key - 1, (mbox_arg_t *)arg);
+        return k_mbox_recv(*key - 1, NULL, (mbox_arg_t *)arg);
     case 11:
         return k_mbox_try_send(*key - 1, (mbox_arg_t *)arg);
     case 12:
@@ -104,7 +105,7 @@ int k_commop(void *key_id, void *arg, int op) {
 int k_semaphore_init(int *key, int sem) {
     if (sem_first_time) {
         for (int i = 0; i < COMM_NUM; i++) {
-            sem_list[i] = (Semaphore_t *)kmalloc(sizeof(Semaphore_t));
+            sem_list[i] = (Semaphore_t *)k_malloc(sizeof(Semaphore_t));
             sem_list[i]->sem_info.initialized = 0;
         }
         sem_first_time = 0;
@@ -133,7 +134,7 @@ int k_semaphore_p(int key) {
     }
     sem_list[key]->sem--;
     if (sem_list[key]->sem < 0) {
-        k_block(&(*current_running)->list, &sem_list[key]->wait_queue);
+        k_block(&(*current_running)->list, &sem_list[key]->wait_queue, ENQUEUE_LIST);
         k_scheduler();
     }
     return 0;
@@ -154,7 +155,7 @@ int k_semaphore_destroy(int *key) {
     if (!sem_list[*key - 1]->sem_info.initialized) {
         return -1;
     }
-    memset(sem_list[*key - 1], 0, sizeof(sem_list[*key - 1]));
+    k_memset(sem_list[*key - 1], 0, sizeof(Semaphore_t *));
     *key = 0;
     return 0;
 }
@@ -162,7 +163,7 @@ int k_semaphore_destroy(int *key) {
 int k_cond_init(int *key) {
     if (cond_first_time) {
         for (int i = 0; i < COMM_NUM; i++) {
-            cond_list[i] = (cond_t *)kmalloc(sizeof(cond_t));
+            cond_list[i] = (cond_t *)k_malloc(sizeof(cond_t));
             cond_list[i]->cond_info.initialized = 0;
         }
         cond_first_time = 0;
@@ -190,7 +191,7 @@ int k_cond_wait(int key) {
         return -1;
     }
     cond_list[key]->num_wait++;
-    k_block(&(*current_running)->list, &cond_list[key]->wait_queue);
+    k_block(&(*current_running)->list, &cond_list[key]->wait_queue, ENQUEUE_LIST);
     k_scheduler();
     return 0;
 }
@@ -221,7 +222,7 @@ int k_cond_destroy(int *key) {
     if (!cond_list[*key - 1]->cond_info.initialized) {
         return -1;
     }
-    memset(cond_list[*key - 1], 0, sizeof(cond_list[*key]));
+    k_memset(cond_list[*key - 1], 0, sizeof(cond_t *));
     *key = 0;
     return 0;
 }
@@ -229,7 +230,7 @@ int k_cond_destroy(int *key) {
 int k_barrier_init(int *key, int total) {
     if (barrier_first_time) {
         for (int i = 0; i < COMM_NUM; i++) {
-            barrier_list[i] = (barrier_t *)kmalloc(sizeof(barrier_t));
+            barrier_list[i] = (barrier_t *)k_malloc(sizeof(barrier_t));
             barrier_list[i]->barrier_info.initialized = 0;
         }
         barrier_first_time = 0;
@@ -272,7 +273,7 @@ int k_barrier_destroy(int *key) {
         return -1;
     }
     k_cond_destroy(&barrier_list[*key - 1]->cond_id);
-    memset(barrier_list[*key - 1], 0, sizeof(barrier_list[*key - 1]));
+    k_memset(barrier_list[*key - 1], 0, sizeof(barrier_t *));
     *key = 0;
     return 0;
 }
@@ -281,7 +282,7 @@ int k_mbox_open(char *name) {
     int operator= sys_getpid();
     if (mbox_first_time) {
         for (int i = 0; i < COMM_NUM; i++) {
-            mbox_list[i] = (mbox_t *)kmalloc(sizeof(mbox_t));
+            mbox_list[i] = (mbox_t *)k_malloc(sizeof(mbox_t));
             mbox_list[i]->mailbox_info.initialized = 0;
         }
         mbox_first_time = 0;
@@ -290,9 +291,8 @@ int k_mbox_open(char *name) {
         return -2;
     }
     for (int i = 0; i < COMM_NUM; i++) {
-        if (mbox_list[i]->mailbox_info.initialized && strcmp(mbox_list[i]->name, name) == 0) {
+        if (mbox_list[i]->mailbox_info.initialized && k_strcmp(mbox_list[i]->name, name) == 0) {
             mbox_list[i]->cited_pid[mbox_list[i]->cited_num++] = operator;
-            pcb[operator-1].mboxid[pcb[operator-1].mboxsum++] = i + 1;
             return i + 1;
         }
     }
@@ -302,84 +302,92 @@ int k_mbox_open(char *name) {
     }
     mbox_list[mbox_i]->mailbox_info.id = mbox_i + 1;
     mbox_list[mbox_i]->mailbox_info.initialized = 1;
-    strcpy(mbox_list[mbox_i]->name, name);
-    memset(mbox_list[mbox_i]->buff, 0, sizeof(mbox_list[mbox_i]->buff));
-    mbox_list[mbox_i]->read_head = 0;
-    mbox_list[mbox_i]->write_tail = 0;
-    mbox_list[mbox_i]->used_units = 0;
-    mbox_list[mbox_i]->full_cond_id = 0;
-    mbox_list[mbox_i]->empty_cond_id = 0;
+    k_strcpy(mbox_list[mbox_i]->name, name);
+    // k_memset(mbox_list[mbox_i]->buff, 0, sizeof(mbox_list[mbox_i]->buff));
+    // mbox_list[mbox_i]->read_head = 0;
+    // mbox_list[mbox_i]->write_tail = 0;
+    // mbox_list[mbox_i]->used_units = 0;
+    // mbox_list[mbox_i]->full_cond_id = 0;
+    // mbox_list[mbox_i]->empty_cond_id = 0;
     k_cond_init(&mbox_list[mbox_i]->full_cond_id);
     k_cond_init(&mbox_list[mbox_i]->empty_cond_id);
-    memset(mbox_list[mbox_i]->cited_pid, 0, sizeof(mbox_list[mbox_i]->cited_pid));
-    mbox_list[mbox_i]->cited_num = 0;
+    // k_memset(mbox_list[mbox_i]->cited_pid, 0, sizeof(mbox_list[mbox_i]->cited_pid));
+    // mbox_list[mbox_i]->cited_num = 0;
     mbox_list[mbox_i]->cited_pid[mbox_list[mbox_i]->cited_num++] = operator;
-    pcb[operator-1].mboxid[pcb[operator-1].mboxsum++] = mbox_i + 1;
     return mbox_i + 1;
 }
 
-int k_mbox_close() {
+int k_mbox_close(int mbox_id) {
     int operator= sys_getpid();
-    for(int i = 0; i < pcb[operator-1].mboxsum; i++){
-        mbox_list[pcb[operator-1].mboxid[i] - 1]->cited_num--;
-        if(mbox_list[pcb[operator-1].mboxid[i] - 1]->cited_num == 0){
-            k_cond_destroy(&mbox_list[pcb[operator-1].mboxid[i] - 1]->full_cond_id);
-            k_cond_destroy(&mbox_list[pcb[operator-1].mboxid[i] - 1]->empty_cond_id);
-            memset(mbox_list[pcb[operator-1].mboxid[i] - 1],0,sizeof(mbox_list[pcb[operator-1].mboxid[i] - 1]));
+    mbox_t *target = mbox_list[mbox_id];
+    for (int i = 0; i < target->cited_num; i++) {
+        if (target->cited_pid[i] == operator) {
+            target->cited_pid[i] = 0;
         }
     }
+    if (!target->cited_num) {
+        k_cond_destroy(&target->full_cond_id);
+        k_cond_destroy(&target->empty_cond_id);
+        k_memset((void *)target, 0, sizeof(mbox_t));
+    }
     return 0;
 }
 
-int k_mbox_send(int key, mbox_arg_t *arg) {
-    if (!mbox_list[key]->mailbox_info.initialized) {
+int k_mbox_send(int key, mbox_t *target, mbox_arg_t *arg) {
+    if (!target) {
+        target = mbox_list[key];
+    }
+    if (!target->mailbox_info.initialized) {
         return -1;
     }
     if (arg->sleep_operation == 1 && k_mbox_try_send(key, arg) < 0) {
         return -2;
     }
     int blocked_time = 0;
-    while (arg->msg_length > MBOX_MSG_MAX_LEN - mbox_list[key]->used_units) {
+    while (arg->msg_length > MBOX_MSG_MAX_LEN - target->used_units) {
         blocked_time++;
-        k_cond_wait(mbox_list[key]->full_cond_id - 1);
+        k_cond_wait(target->full_cond_id - 1);
     }
-    int left_space = MBOX_MSG_MAX_LEN - (mbox_list[key]->write_tail + arg->msg_length);
+    int left_space = MBOX_MSG_MAX_LEN - (target->write_tail + arg->msg_length);
     if (left_space < 0) {
-        memcpy((uint8_t *)mbox_list[key]->buff + mbox_list[key]->write_tail, arg->msg, MBOX_MSG_MAX_LEN - mbox_list[key]->write_tail);
-        memcpy((uint8_t *)mbox_list[key]->buff, arg->msg + MBOX_MSG_MAX_LEN - mbox_list[key]->write_tail, -left_space);
-        mbox_list[key]->write_tail = -left_space;
+        k_memcpy((uint8_t *)target->buff + target->write_tail, arg->msg, MBOX_MSG_MAX_LEN - target->write_tail);
+        k_memcpy((uint8_t *)target->buff, arg->msg + MBOX_MSG_MAX_LEN - target->write_tail, -left_space);
+        target->write_tail = -left_space;
     } else {
-        memcpy((uint8_t *)mbox_list[key]->buff + mbox_list[key]->write_tail, arg->msg, arg->msg_length);
-        mbox_list[key]->write_tail += arg->msg_length;
+        k_memcpy((uint8_t *)target->buff + target->write_tail, arg->msg, arg->msg_length);
+        target->write_tail += arg->msg_length;
     }
-    mbox_list[key]->used_units += arg->msg_length;
-    k_cond_broadcast(mbox_list[key]->empty_cond_id - 1);
+    target->used_units += arg->msg_length;
+    k_cond_broadcast(target->empty_cond_id - 1);
     return blocked_time;
 }
 
-int k_mbox_recv(int key, mbox_arg_t *arg) {
-    if (!mbox_list[key]->mailbox_info.initialized) {
+int k_mbox_recv(int key, mbox_t *target, mbox_arg_t *arg) {
+    if (!target) {
+        target = mbox_list[key];
+    }
+    if (!target->mailbox_info.initialized) {
         return -1;
     }
     if (arg->sleep_operation == 1 && k_mbox_try_recv(key, arg) < 0) {
         return -2;
     }
     int blocked_time = 0;
-    while (arg->msg_length > mbox_list[key]->used_units) {
+    while (arg->msg_length > target->used_units) {
         blocked_time++;
-        k_cond_wait(mbox_list[key]->empty_cond_id - 1);
+        k_cond_wait(target->empty_cond_id - 1);
     }
-    int left_space = MBOX_MSG_MAX_LEN - (mbox_list[key]->read_head + arg->msg_length);
+    int left_space = MBOX_MSG_MAX_LEN - (target->read_head + arg->msg_length);
     if (left_space < 0) {
-        memcpy((uint8_t *)arg->msg, (const uint8_t *)mbox_list[key]->buff + mbox_list[key]->read_head, MBOX_MSG_MAX_LEN - mbox_list[key]->read_head);
-        memcpy((uint8_t *)arg->msg + MBOX_MSG_MAX_LEN - mbox_list[key]->read_head, (const uint8_t *)mbox_list[key]->buff, -left_space);
-        mbox_list[key]->read_head = -left_space;
+        k_memcpy((uint8_t *)arg->msg, (const uint8_t *)target->buff + target->read_head, MBOX_MSG_MAX_LEN - target->read_head);
+        k_memcpy((uint8_t *)arg->msg + MBOX_MSG_MAX_LEN - target->read_head, (const uint8_t *)target->buff, -left_space);
+        target->read_head = -left_space;
     } else {
-        memcpy((uint8_t *)arg->msg, (const uint8_t *)mbox_list[key]->buff + mbox_list[key]->read_head, arg->msg_length);
-        mbox_list[key]->read_head += arg->msg_length;
+        k_memcpy((uint8_t *)arg->msg, (const uint8_t *)target->buff + target->read_head, arg->msg_length);
+        target->read_head += arg->msg_length;
     }
-    mbox_list[key]->used_units -= arg->msg_length;
-    k_cond_broadcast(mbox_list[key]->full_cond_id - 1);
+    target->used_units -= arg->msg_length;
+    k_cond_broadcast(target->full_cond_id - 1);
     return blocked_time;
 }
 
@@ -401,4 +409,44 @@ int k_mbox_try_recv(int key, mbox_arg_t *arg) {
         return -2;
     }
     return 0;
+}
+
+void k_pcb_mbox_init(pcb_mbox_t *target, int owner_id) {
+    k_memset((void *)&(target), 0, sizeof(pcb_mbox_t));
+    target->pcb_i = owner_id;
+}
+
+int sys_mailread(void *buf, int len) {
+    pcb_mbox_t *target = &(*current_running)->mbox;
+    if (len == 0) {
+        if (target->used_units) {
+            return 0;
+        } else {
+            return -1;
+        }
+    } else if (len > PCB_MBOX_MSG_MAX_LEN) {
+        len = PCB_MBOX_MSG_MAX_LEN;
+    }
+    int str_len = k_strlen((const char *)target->buff[target->read_head]);
+    k_memcpy((uint8_t *)buf, (uint8_t *)target->buff[target->read_head], k_min(len, str_len));
+    target->read_head = (target->read_head + 1) % PCB_MBOX_MAX_MSG_NUM;
+    target->used_units--;
+    return len;
+}
+
+int sys_mailwrite(int pid, void *buf, int len) {
+    pcb_mbox_t *target = &(*current_running)->mbox;
+    if (len == 0) {
+        if (target->used_units == PCB_MBOX_MAX_MSG_NUM) {
+            return -1;
+        } else {
+            return 0;
+        }
+    } else if (len > PCB_MBOX_MSG_MAX_LEN) {
+        len = PCB_MBOX_MSG_MAX_LEN;
+    }
+    k_memcpy((uint8_t *)target->buff[target->write_head], (uint8_t *)buf, len);
+    target->write_head = (target->write_head + 1) % PCB_MBOX_MAX_MSG_NUM;
+    target->used_units++;
+    return len;
 }
\ No newline at end of file
diff --git a/src/kernel/sys/cpu.c b/src/kernel/sys/cpu.c
new file mode 100644
index 0000000000000000000000000000000000000000..cf8f5463d222f84a024360962e84c6539c700996
--- /dev/null
+++ b/src/kernel/sys/cpu.c
@@ -0,0 +1 @@
+#include <os/cpu.h>
\ No newline at end of file
diff --git a/src/kernel/sys/sys.c b/src/kernel/sys/info.c
similarity index 77%
rename from src/kernel/sys/sys.c
rename to src/kernel/sys/info.c
index 427d217e877b7e8b32f958069d8b64ce33b0b7ef..09d9a0f608ae63b032232adb268dfc44d358b836 100644
--- a/src/kernel/sys/sys.c
+++ b/src/kernel/sys/info.c
@@ -4,6 +4,6 @@
 uname_t uname_550w = {.sysname = "MOSS", .nodename = "oscomp", .release = "1.0.0", .version = "#1", .machine = "550W", .domainname = "bluespace.moss.com"};
 
 long sys_uname(uname_t *dest) {
-    memcpy((uint8_t *)dest, (uint8_t *)&uname_550w, sizeof(uname_550w));
+    k_memcpy((uint8_t *)dest, (uint8_t *)&uname_550w, sizeof(uname_t));
     return 0;
 }
\ No newline at end of file
diff --git a/src/kernel/sys/pcb.c b/src/kernel/sys/pcb.c
index f33bdd53d5cd5deeb6cce6947a26d1bd518c83db..f382bcde6802d1df959b1128f885cf5d5b547fa0 100644
--- a/src/kernel/sys/pcb.c
+++ b/src/kernel/sys/pcb.c
@@ -3,22 +3,16 @@
 #include <asm/stack.h>
 #include <common/elf.h>
 #include <drivers/screen.h>
-#include <lib/list.h>
+#include <fs/fs.h>
+#include <lib/math.h>
 #include <lib/stdio.h>
 #include <lib/string.h>
 #include <os/irq.h>
 #include <os/lock.h>
 #include <os/pcb.h>
 #include <os/smp.h>
-#include <os/time.h>
 #include <user/user_programs.h>
 
-pid_t process_id = 1;
-int allocpid = 0;
-
-list_node_t *avalable0[20];
-list_node_t *avalable1[20];
-
 pcb_t *volatile current_running0;
 pcb_t *volatile current_running1;
 pcb_t **volatile current_running;
@@ -29,80 +23,112 @@ pcb_t pcb[NUM_MAX_TASK];
 
 const ptr_t pid0_stack = INIT_KERNEL_STACK + PAGE_SIZE * 3 - 112 - 288;
 const ptr_t pid0_stack2 = INIT_KERNEL_STACK + PAGE_SIZE * 4 - 112 - 288;
-pcb_t pid0_pcb = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack, .user_sp = (ptr_t)pid0_stack, .preempt_count = 0};
-pcb_t pid0_pcb2 = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack2, .user_sp = (ptr_t)pid0_stack2, .preempt_count = 0};
-
-int freepidnum = 0;
-int nowpid = 1;
-int glmask = 3;
-int glvalid = 0;
+pcb_t pid0_pcb = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack, .user_sp = (ptr_t)pid0_stack};
+pcb_t pid0_pcb2 = {.pid = 0, .kernel_sp = (ptr_t)pid0_stack2, .user_sp = (ptr_t)pid0_stack2};
 
 pid_t freepid[NUM_MAX_TASK];
 
 pid_t nextpid() {
-    if (freepidnum != 0)
-        return freepid[freepidnum--];
-    else
-        return nowpid++;
+    for (int i = 0; i < NUM_MAX_TASK; i++) {
+        if (!pcb[i].in_use) {
+            return i;
+        }
+    }
+    while (true) {
+        return nextpid();
+    }
 }
 
-unsigned x = 0;
+void init_pcb_i(int pcb_i, task_type_t type, int pid, int fpid, int tid, int father_pid, uint8_t core_mask) {
+    init_list_head(&pcb[pcb_i].wait_list);
+    pcb[pcb_i].in_use = TRUE;
+    pcb[pcb_i].pid = pid;
+    pcb[pcb_i].fpid = fpid;
+    pcb[pcb_i].tid = tid;
+    pcb[pcb_i].father_pid = father_pid;
+    pcb[pcb_i].child_num = 0;
+    k_memset((void *)pcb[pcb_i].child_pids, 0, sizeof(pcb[pcb_i].child_pids));
+    k_memset((void *)pcb[pcb_i].child_stat_addrs, 0, sizeof(pcb[pcb_i].child_stat_addrs));
+    pcb[pcb_i].child_num = 0;
+    pcb[pcb_i].threadsum = 0;
+    k_memset((void *)pcb[pcb_i].thread_ids, 0, sizeof(pcb[pcb_i].child_pids));
+    pcb[pcb_i].type = type;
+    pcb[pcb_i].status = TASK_READY;
+    pcb[pcb_i].cursor_x = 1;
+    pcb[pcb_i].cursor_y = 1;
+    pcb[pcb_i].priority.priority = 1;
+    pcb[pcb_i].priority.last_sched_time = 0;
+    pcb[pcb_i].core_mask[0] = core_mask;
+    pcb[pcb_i].locksum = 0;
+    k_pcb_mbox_init(&pcb[pcb_i].mbox, pcb_i);
+    k_memset((void *)&(pcb[pcb_i].stime_last), 0, sizeof(__kernel_time_t));
+    k_memset((void *)&(pcb[pcb_i].utime_last), 0, sizeof(__kernel_time_t));
+    k_memset((void *)&(pcb[pcb_i].timer), 0, sizeof(pcbtimer_t));
+    pcb[pcb_i].dead_child_stime = 0;
+    pcb[pcb_i].dead_child_utime = 0;
+    k_memset((void *)&(pcb[pcb_i].resources), 0, sizeof(rusage_t));
+}
 
-extern int check_wait_recv(int num_packet);
+void init_user_stack(ptr_t *user_stack_kva, ptr_t *user_stack, const char *argv[], const char *envp[], const char *file_name) {
+    int argc = k_strlistlen((char **)argv);
+    int envpc = k_strlistlen((char **)envp);
+    int total_length = (argc + envpc + 3) * sizeof(uintptr_t *);
+    int pointers_length = total_length;
+    for (int i = 0; i < argc; i++) {
+        total_length += (k_strlen(argv[i]) + 1);
+    }
+    for (int i = 0; i < envpc; i++) {
+        total_length += (k_strlen(envp[i]) + 1);
+    }
+    total_length += (k_strlen(file_name) + 1);
+    total_length = ROUND(total_length, 0x100);
+    uintptr_t kargv_pointer = (uintptr_t)user_stack_kva - total_length;
+    intptr_t kargv = kargv_pointer + pointers_length;
+
+    /* 1. store argc in the lowest */
+    *((int *)kargv_pointer) = argc;
+    kargv_pointer += sizeof(uint64_t);
+
+    /* 2. save argv pointer in 2nd lowest and argv in lowest strings */
+    uintptr_t new_argv = (uintptr_t)user_stack - total_length + pointers_length;
+    for (int i = 0; i < argc; i++) {
+        *((uintptr_t *)kargv_pointer + i) = new_argv;
+        k_strcpy((char *)kargv, argv[i]);
+        new_argv += (k_strlen(argv[i]) + 1);
+        kargv += (k_strlen(argv[i]) + 1);
+    }
+    *((uintptr_t *)kargv_pointer + argc) = 0;
+    kargv_pointer += (argc + 1) * sizeof(uintptr_t);
+
+    /* 3. save envp pointer in 3rd lowest and envp in 2nd lowest strings */
+    for (int i = 0; i < envpc; i++) {
+        *((uintptr_t *)kargv_pointer + i) = new_argv;
+        k_strcpy((char *)kargv, envp[i]);
+        new_argv += k_strlen(envp[i]) + 1;
+        kargv += k_strlen(envp[i]) + 1;
+    }
+    *((uintptr_t *)kargv_pointer + envpc) = 0;
 
-void mysrand(unsigned seed) { x = seed; }
+    /* 4. save file_name */
+    k_strcpy((char *)kargv, file_name);
+    new_argv = new_argv + k_strlen(file_name) + 1;
+    kargv += k_strlen(file_name) + 1;
 
-int myrand() {
-    long long tmp = 0x5deece66dll * x + 0xbll;
-    x = tmp & 0x7fffffff;
-    return x;
+    /* now user_sp is user_stack - total_length */
+    user_stack_kva -= total_length;
+    user_stack -= total_length;
 }
 
-void init_pcb() {
-    allocpid = 0;
+void k_init_pcb() {
+    k_memset(&pcb, 0, sizeof(pcb));
     for (int i = 0; i < NUM_MAX_TASK; i++) {
         pcb[i].status = TASK_EXITED;
-        pcb[i].stime = 0;
-        pcb[i].stime_last = 0;
-        pcb[i].utime = 0;
-        pcb[i].utime_last = 0;
-        memset(&pcb[i].timer, 0, sizeof(pcb[i].timer));
-    }
-    pcb[0].type = USER_PROCESS;
-    pcb[0].pid = 0;
-    pcb[0].fpid = 0;
-    pcb[0].tid = 0;
-    pcb[0].threadsum = 0;
-    pcb[0].status = TASK_READY;
-    pcb[0].cursor_x = 1;
-    pcb[0].cursor_y = 1;
-    pcb[0].priority.priority = 0;
-    pcb[0].priority.last_sched_time = 0;
-    pcb[0].mode = AUTO_CLEANUP_ON_EXIT;
-    pcb[0].wait_list.next = &pcb[0].wait_list;
-    pcb[0].wait_list.prev = &pcb[0].wait_list;
-    pcb[0].core_mask = 3;
-    pcb[0].locksum = 0;
-    pcb[0].child_num = 0;
-    pcb[0].father_pid = 0;
-    ptr_t kernel_stack = get_kernel_address(0);
-    ptr_t user_stack = kernel_stack - 0x2000;
-    allocpid = 0;
-    PTE *pgdir = (PTE *)allocPage(1);
-    clear_pgdir((uintptr_t)pgdir);
-    int len = 0;
-    unsigned char *binary = NULL;
-    get_elf_file("shell", &binary, &len);
-    share_pgtable(pgdir, pa2kva(PGDIR_PA));
-    void_task test_shell = (void_task)load_elf(binary, len, (ptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))alloc_page_helper);
-    map(USER_STACK_ADDR - 0x1000, kva2pa(user_stack), pgdir);
-    init_pcb_stack(kernel_stack, USER_STACK_ADDR, (ptr_t)test_shell, &pcb[0], 0, NULL);
-    pcb[0].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT;
+    }
     current_running0 = &pid0_pcb;
-    list_add_tail(&(pcb[0].list), &ready_queue);
     current_running1 = &pid0_pcb2;
-    timers.next = &timers;
-    timers.prev = &timers;
+    (*current_running) = get_current_running();
+    init_list_head(&timers);
+    sys_spawn("shell");
 }
 
 long sys_setpriority(int which, int who, int niceval) {
@@ -117,10 +143,10 @@ long sys_setpriority(int which, int who, int niceval) {
     case PRIO_PGRP:
         (*current_running)->priority.priority = niceval;
         for (int i = 0; i < (*current_running)->child_num; i++) {
-            pcb[(*current_running)->child_pid[i]].priority.priority = niceval;
+            pcb[(*current_running)->child_pids[i]].priority.priority = niceval;
         }
         for (int i = 0; i < (*current_running)->threadsum; i++) {
-            pcb[(*current_running)->threadid[i]].priority.priority = niceval;
+            pcb[(*current_running)->thread_ids[i]].priority.priority = niceval;
         }
         break;
     case PRIO_USER:
@@ -156,7 +182,7 @@ pcb_t *choose_sched_task(list_head *queue) {
     int cpu_id = get_current_cpu_id();
     while (list_iterator->next != queue) {
         pcb_iterator = list_entry(list_iterator, pcb_t, list);
-        if (!(pcb_iterator->core_mask & (0x1 << cpu_id))) {
+        if (!(pcb_iterator->core_mask[cpu_id / 8] & (0x1 << (cpu_id % 8)))) {
             continue;
         }
         cur_priority = cal_priority(cur_time, pcb_iterator->priority.last_sched_time, pcb_iterator->priority.priority);
@@ -170,23 +196,21 @@ pcb_t *choose_sched_task(list_head *queue) {
     return max_one;
 }
 
-void enqueue(list_head *new, list_head *head, int target) {
-    switch (target) {
+void enqueue(list_head *new, list_head *head, enqueue_way_t way) {
+    switch (way) {
     case ENQUEUE_LIST:
         list_add_tail(new, head);
-        break;
-    case ENQUEUE_PCB:
-    {
-        pcb_t *curr = list_entry(new, pcb_t, list);
-        list_head *insert_point = head->next;
-        pcb_t *iterator = list_entry(insert_point, pcb_t, list);
-        // use >= because of FIFO
-        while (iterator->priority.priority >= curr->priority.priority && insert_point != &ready_queue) {
-            insert_point = insert_point->next;
-            iterator = list_entry(insert_point, pcb_t, list);
+    case ENQUEUE_TIMER_LIST: {
+        pcb_t *new_inserter = list_entry(new, pcb_t, list);
+        list_head *iterator_list = timers.next;
+        pcb_t *iterator_pcb = NULL;
+        while (iterator_list != &timers) {
+            iterator_pcb = list_entry(iterator_list, pcb_t, list);
+            if (cmp_nanotime(&iterator_pcb->timer.end_time, &new_inserter->timer.end_time) >= 0) {
+                break;
+            }
         }
-        // for head add to tail, for common position add to front
-        list_add_tail(&(curr->list), insert_point);
+        list_add_tail(new, iterator_list);
         break;
     }
     default:
@@ -194,7 +218,7 @@ void enqueue(list_head *new, list_head *head, int target) {
     }
 }
 
-pcb_t *dequeue(list_head *queue, int target) {
+pcb_t *dequeue(list_head *queue, dequeue_way_t target) {
     // plain and simple way
     pcb_t *ret = NULL;
     switch (target) {
@@ -209,7 +233,7 @@ pcb_t *dequeue(list_head *queue, int target) {
     case DEQUEUE_WAITLIST_DESTROY:
         ret = list_entry(queue->next, pcb_t, wait_list);
         list_del(&(ret->wait_list));
-        memset(&ret->timer, 0, sizeof(ret->timer));
+        k_memset(&ret->timer, 0, sizeof(pcbtimer_t));
         list_init_with_null(&ret->wait_list);
         break;
     case DEQUEUE_LIST_STRATEGY:
@@ -222,7 +246,7 @@ pcb_t *dequeue(list_head *queue, int target) {
     return ret;
 }
 
-bool check_empty(int cpu_mask) {
+bool check_empty(int cpuid) {
     if (list_is_empty(&ready_queue)) {
         return TRUE;
     } else {
@@ -230,7 +254,7 @@ bool check_empty(int cpu_mask) {
         pcb_t *iterator = NULL;
         while (node != &ready_queue) {
             iterator = list_entry(node, pcb_t, list);
-            if (iterator->core_mask & cpu_mask) {
+            if (iterator->core_mask[cpuid / 8] & (0x1 << (cpuid % 8))) {
                 return FALSE;
             }
             node = node->next;
@@ -239,13 +263,40 @@ bool check_empty(int cpu_mask) {
     }
 }
 
+long sys_nanosleep(nanotime_val_t *rqtp, nanotime_val_t *rmtp) {
+    (*current_running)->timer.initialized = true;
+    get_nanotime(&(*current_running)->timer.start_time);
+    add_nanotime(rqtp, &(*current_running)->timer.start_time, &(*current_running)->timer.end_time);
+    (*current_running)->timer.remain_time = rmtp;
+    k_block(&((*current_running)->list), &timers, ENQUEUE_TIMER_LIST);
+    k_scheduler();
+    return 0;
+}
+
+void check_sleeping() {
+    list_node_t *q;
+    nanotime_val_t now_time;
+    list_head *p = timers.next;
+    get_nanotime(&now_time);
+    while (p != &timers) {
+        pcb_t *p_pcb = list_entry(p, pcb_t, list);
+        if (cmp_nanotime(&now_time, &p_pcb->timer.end_time) >= 0) {
+            q = p->next;
+            k_unblock(p, &ready_queue, UNBLOCK_TO_LIST_STRATEGY);
+            p = q;
+        } else {
+            break;
+        }
+    }
+}
+
 long k_scheduler(void) {
     if (!list_is_empty(&timers)) {
         check_sleeping();
     }
     pcb_t *curr = (*current_running);
     int cpuid = get_current_cpu_id();
-    bool ready_queue_empty = check_empty(0x1 << cpuid);
+    bool ready_queue_empty = check_empty(cpuid);
     if (ready_queue_empty && curr->pid != 0 && curr->status == TASK_RUNNING) {
         return 0;
     } else if (ready_queue_empty) {
@@ -262,7 +313,7 @@ long k_scheduler(void) {
         (*current_running) = curr;
     }
     if (curr->status == TASK_RUNNING && curr->pid != 0) {
-        enqueue(&curr->list, &ready_queue, ENQUEUE_PCB);
+        enqueue(&curr->list, &ready_queue, ENQUEUE_LIST);
     }
     pcb_t *next_pcb = dequeue(&ready_queue, DEQUEUE_LIST_STRATEGY);
     pcb_move_cursor(screen_cursor_x, screen_cursor_y);
@@ -285,59 +336,28 @@ long sys_sched_yield(void) {
     return k_scheduler();
 }
 
-long sys_nanosleep(nanotime_val_t *rqtp, nanotime_val_t *rmtp) {
-    (*current_running)->timer.initialized = true;
-    copy_nanotime(&(*current_running)->timer.time, rqtp);
-    get_nanotime(&(*current_running)->timer.start_time);
-    k_block(&((*current_running)->list), &timers);
-    k_scheduler();
-    // note: you can assume: 1 second = `timebase` ticks
-    // 1. block the (*current_running)
-    // 2. create a timer which calls `do_unblock` when timeout
-    // 3. reschedule because the (*current_running) is blocked.
-    return 0;
-}
-
-void check_sleeping() {
-    list_node_t *q;
-    nanotime_val_t now_time;
-    list_head *p = timers.next;
-    while (p != &timers) {
-        get_nanotime(&now_time);
-        nanotime_val_t res_time;
-        pcb_t *p_pcb = list_entry(p, pcb_t, list);
-        minus_nanotime(&now_time, &p_pcb->timer.start_time, &res_time);
-        if (cmp_nanotime(&res_time, &p_pcb->timer.time) >= 0) {
-            q = p->next;
-            k_unblock(p, &ready_queue, UNBLOCK_TO_LIST_STRATEGY);
-            p = q;
-        } else
-            p = p->next;
-    }
-}
-
-void k_block(list_node_t *pcb_node, list_head *queue) {
-    list_add_tail(pcb_node, queue);
+void k_block(list_node_t *pcb_node, list_head *queue, enqueue_way_t way) {
+    enqueue(pcb_node, queue, way);
     (*current_running)->status = TASK_BLOCKED;
 }
 
-void k_unblock(list_head *from_queue, list_head *to_queue, int way) {
+void k_unblock(list_head *from_queue, list_head *to_queue, unblock_way_t way) {
     // TODO: unblock the `pcb` from the block queue
     pcb_t *fetch_pcb = NULL;
     switch (way) {
     case UNBLOCK_TO_LIST_FRONT:
-        fetch_pcb = dequeue(from_queue->prev, 0);
+        fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST);
         list_add(&fetch_pcb->list, to_queue);
         break;
     case UNBLOCK_TO_LIST_BACK:
-        fetch_pcb = dequeue(from_queue->prev, 0);
+        fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST);
         list_add_tail(&fetch_pcb->list, to_queue);
         break;
     case UNBLOCK_ONLY:
-        fetch_pcb = dequeue(from_queue->prev, 0);
+        fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST);
         break;
     case UNBLOCK_TO_LIST_STRATEGY:
-        fetch_pcb = dequeue(from_queue->prev, 2);
+        fetch_pcb = dequeue(from_queue->prev, DEQUEUE_LIST_STRATEGY);
         list_add_tail(&fetch_pcb->list, to_queue);
         break;
     default:
@@ -346,91 +366,76 @@ void k_unblock(list_head *from_queue, list_head *to_queue, int way) {
     fetch_pcb->status = TASK_READY;
 }
 
-long k_taskset(int pid, int mask) {
-    int id = get_current_cpu_id();
-    if (pid == 0) {
-        if (mask != 3 && mask != 1 + id) {
-            glmask = mask;
-            glvalid = 1;
-            return 1;
-        } else
-            glvalid = 0;
+long sys_sched_setaffinity(pid_t pid, unsigned int len, const byte_size_t *user_mask_ptr) {
+    if (pid > NUM_MAX_TASK) {
+        return -EINVAL;
     }
-    pcb_t *target = &pcb[pid];
-    if (pid > NUM_MAX_TASK || target->status == TASK_EXITED || target->status == TASK_ZOMBIE)
-        return 0;
-    target->core_mask = mask;
-    return 1;
+    pcb_t *target = pid ? &pcb[pid] : (*current_running);
+    if (target->status == TASK_EXITED) {
+        return -EINVAL;
+    }
+    int core_len = CPU_SET_SIZE;
+    int copy_len = k_min(core_len, len);
+    k_memcpy(target->core_mask, user_mask_ptr, copy_len);
+    return 0;
+}
+
+long sys_sched_getaffinity(pid_t pid, unsigned int len, uint8_t *user_mask_ptr) {
+    if (pid > NUM_MAX_TASK) {
+        return -EINVAL;
+    }
+    pcb_t *target = pid ? &pcb[pid] : (*current_running);
+    if (target->status == TASK_EXITED) {
+        return -EINVAL;
+    }
+    int core_len = CPU_SET_SIZE;
+    int copy_len = k_min(core_len, len);
+    k_memcpy(user_mask_ptr, target->core_mask, copy_len);
+    return 0;
 }
 
-long sys_spawn(task_info_t *info, void *arg, spawn_mode_t mode) {
+long sys_spawn(const char *file_name) {
     int i = nextpid();
-    pcb[i].type = info->type;
-    pcb[i].pid = i;
-    pcb[i].status = TASK_READY;
-    pcb[i].cursor_x = 1;
-    pcb[i].cursor_y = 1;
-    pcb[i].priority.priority = 0;
-    pcb[i].priority.last_sched_time = 0;
-    pcb[i].mode = mode;
-    pcb[i].wait_list.next = &pcb[i].wait_list;
-    pcb[i].wait_list.prev = &pcb[i].wait_list;
-    pcb[i].pgdir = 0;
-    if (glvalid)
-        pcb[i].core_mask = glmask;
-    else
-        pcb[i].core_mask = (*current_running)->core_mask;
-    pcb[i].locksum = 0;
+
+    init_pcb_i(i, USER_PROCESS, i, i, 0, 0, (*current_running)->core_mask[0]);
+
     ptr_t kernel_stack = get_kernel_address(i);
-    ptr_t user_stack = kernel_stack - 0x1000;
-    /* TODO: use glibc argument passing standards to restructure */
-    /* 1, arg is wrong, only for passing compilation */
-    init_pcb_stack(kernel_stack, user_stack, (uintptr_t)(info->entry_point), &pcb[i], (uint64_t)arg, NULL);
+    ptr_t user_stack_kva = kernel_stack - PAGE_SIZE;
+    PTE *pgdir = (PTE *)k_alloc_page(1);
+    clear_pgdir((uintptr_t)pgdir);
+    share_pgtable(pgdir, pa2kva(PGDIR_PA));
+    pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT;
+
+    int len = 0;
+    unsigned char *binary = NULL;
+    get_elf_file(file_name, &binary, &len);
+    share_pgtable(pgdir, pa2kva(PGDIR_PA));
+    void_task process = (void_task)load_elf(binary, len, (ptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))k_alloc_page_helper);
+    map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pgdir);
+
+    init_pcb_stack(kernel_stack, user_stack_kva, (uintptr_t)(process), &pcb[i]);
     list_add_tail(&pcb[i].list, &ready_queue);
     return i;
 }
 
-long sys_fork(int prior) {
-
-    pid_t fpid = (*current_running)->pid;
+long sys_fork() {
     int i = nextpid();
+    pid_t fpid = (*current_running)->pid;
+
+    init_pcb_i(i, USER_PROCESS, i, i, 0, fpid, (*current_running)->core_mask[0]);
 
-    pcb[fpid].child_pid[pcb[fpid].child_num] = i;
+    pcb[fpid].child_pids[pcb[fpid].child_num] = i;
     pcb[fpid].child_num++;
-    pcb[i].father_pid = fpid;
-    pcb[i].tid = 0;
-    pcb[i].fpid = i;
-    pcb[i].type = USER_PROCESS;
-    pcb[i].pid = i;
-    pcb[i].status = TASK_READY;
-    pcb[i].cursor_x = 1;
-    pcb[i].cursor_y = 1;
-    // pcb[i].priority = prior;
-    pcb[i].priority.priority = 0;
-    pcb[i].priority.last_sched_time = 0;
-    pcb[i].mode = ENTER_ZOMBIE_ON_EXIT;
-    // pcb[i].mode = AUTO_CLEANUP_ON_EXIT;
-    pcb[i].wait_list.next = &pcb[i].wait_list;
-    pcb[i].wait_list.prev = &pcb[i].wait_list;
-    pcb[i].threadsum = 0;
-    pcb[i].locksum = 0;
-    pcb[i].child_num = 0;
-    if (glvalid)
-        pcb[i].core_mask = glmask;
-    else
-        pcb[i].core_mask = (*current_running)->core_mask;
 
     ptr_t kernel_stack_kva = get_kernel_address(i);
-    ptr_t user_stack_kva = kernel_stack_kva - 0x2000;
-
-    allocpid = i;
-    PTE *pgdir = (PTE *)allocPage(1);
+    ptr_t user_stack_kva = kernel_stack_kva - PAGE_SIZE;
+    PTE *pgdir = (PTE *)k_alloc_page(1);
     clear_pgdir((ptr_t)pgdir);
-
-    fork_pcb_stack(kernel_stack_kva, kernel_stack_kva - 0x1000, &pcb[i]);
-    fork_pgtable(pgdir, (pa2kva(pcb[fpid].pgdir << 12)));
     share_pgtable(pgdir, pa2kva(PGDIR_PA));
-    map(USER_STACK_ADDR - 0x1000, kva2pa(user_stack_kva), pgdir);
+
+    fork_pcb_stack(kernel_stack_kva, user_stack_kva, &pcb[i]);
+    fork_pgtable(pgdir, (pa2kva((*current_running)->pgdir << NORMAL_PAGE_SHIFT)));
+    map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pgdir);
 
     pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT;
 
@@ -438,42 +443,37 @@ long sys_fork(int prior) {
     return i;
 }
 
-long sys_exit(int error_code) {
-    pcb_t *father = &pcb[(*current_running)->father_pid];
-    if (father->child_stat_addrs[(*current_running)->pid]) {
-        *father->child_stat_addrs[(*current_running)->pid] = error_code;
-    }
-    return sys_kill((*current_running)->pid);
-}
-
 long sys_kill(pid_t pid) {
-    pid -= 1;
-    if (pid < 1 || pid >= NUM_MAX_TASK) {
-        return -1;
+    if (pid < 0 || pid >= NUM_MAX_TASK) {
+        return -EINVAL;
     }
     pcb_t *target = &pcb[pid];
     if (target->pid == 0) {
-        return -1;
+        return -EINVAL;
     }
 
     // realease lock
     for (int i = 0; i < target->locksum; i++) {
-        k_mutex_lock_release(target->lockid[i] - 1);
-    }
-    if (target->mode == ENTER_ZOMBIE_ON_EXIT) {
-        // wake up parent
-        if (target->father_pid > 0) {
-            pcb_t *parent = &pcb[target->father_pid];
-            if (!parent->timer.initialized) {
-                k_unblock(&parent->list, &ready_queue, UNBLOCK_TO_LIST_STRATEGY);
+        k_mutex_lock_release(target->lock_ids[i] - 1);
+    }
+    if (target->father_pid > 0) {
+        pcb_t *parent = &pcb[target->father_pid];
+        if (!parent->timer.initialized) {
+            k_unblock(&parent->list, &ready_queue, UNBLOCK_TO_LIST_STRATEGY);
+        }
+        for (int i = 0; i < NUM_MAX_CHILD; i++) {
+            if (parent->child_pids[i] == pid) {
+                parent->child_pids[i] = 0;
+                break;
             }
         }
-        target->status = TASK_ZOMBIE;
-    } else if (target->mode == AUTO_CLEANUP_ON_EXIT) {
-        target->pid = 0;
-        target->status = TASK_EXITED;
-        if(pcb[pid].type!=USER_THREAD)
-            getback_page(pid);
+        parent->dead_child_stime += get_ticks_from_time(&target->resources.ru_stime);
+        parent->dead_child_utime += get_ticks_from_time(&target->resources.ru_utime);
+    }
+    target->pid = 0;
+    target->status = TASK_EXITED;
+    if (pcb[pid].type != USER_THREAD) {
+        getback_page(pid);
     }
     // give up its sons
     for (int i = 0; i < NUM_MAX_TASK; i++) {
@@ -481,25 +481,39 @@ long sys_kill(pid_t pid) {
             pcb[i].father_pid = target->father_pid;
         }
     }
-    if (target->list.next)
+    if (target->list.next) {
         list_del(&target->list);
-    if ((*current_running)->pid == pid + 1 || (*current_running)->pid == 0 || target->mode == AUTO_CLEANUP_ON_EXIT) {
+    }
+    target->exit_status = -1;
+    if ((*current_running)->pid == pid + 1 || (*current_running)->pid == 0) {
         k_scheduler();
     }
     return 0;
 }
 
+long sys_exit(int error_code) {
+    if ((*current_running)->father_pid > 0) {
+        pcb_t *father = &pcb[(*current_running)->father_pid];
+        if (father->child_stat_addrs[(*current_running)->pid]) {
+            *father->child_stat_addrs[(*current_running)->pid] = error_code;
+        }
+    }
+    sys_kill((*current_running)->pid);
+    (*current_running)->exit_status = error_code;
+    return 0;
+}
+
 long sys_wait4(pid_t pid, int *stat_addr, int options, rusage_t *ru) {
     pcb_t *target = &pcb[pid];
-    while (target->status != TASK_EXITED && target->status != TASK_ZOMBIE) {
-        k_block(&(*current_running)->list, &target->wait_list);
+    while (target->status != TASK_EXITED) {
+        k_block(&(*current_running)->list, &target->wait_list, ENQUEUE_LIST);
         k_scheduler();
     }
-    if (target->status == TASK_ZOMBIE) {
-        freepidnum++;
-        freepid[freepidnum] = pid;
-        target->status = TASK_EXITED;
+    target->status = TASK_EXITED;
+    if (stat_addr) {
+        *stat_addr = (target->exit_status << 8);
     }
+    k_memcpy((uint8_t *)ru, (uint8_t *)&target->resources, sizeof(rusage_t));
     return 1;
 }
 
@@ -507,8 +521,9 @@ long sys_process_show() {
     int num = 0;
     for (int i = 0; i < NUM_MAX_TASK; i++) {
         if (pcb[i].status != TASK_EXITED) {
-            if (num == 0)
+            if (num == 0) {
                 prints("[PROCESS TABLE]\n");
+            }
             prints("[%d] PID : %d, TID : %d", num, pcb[i].fpid,
                    pcb[i].tid); // pcb[i].tid
             switch (pcb[i].status) {
@@ -518,19 +533,19 @@ long sys_process_show() {
             case TASK_BLOCKED:
                 sys_screen_write(" STATUS : BLOCKED");
                 break;
-            case TASK_ZOMBIE:
-                sys_screen_write(" STATUS : ZOMBIE");
-                break;
             case TASK_READY:
                 sys_screen_write(" STATUS : READY");
                 break;
+            case TASK_EXITED:
+                sys_screen_write(" STATUS : EXITED");
+                break;
             default:
                 break;
             }
-            prints(" MASK : 0x%d", pcb[i].core_mask);
+            prints(" MASK : 0x%x", (int)pcb[i].core_mask[0]);
             if (pcb[i].status == TASK_RUNNING) {
                 sys_screen_write(" on Core ");
-                switch (pcb[i].core_mask) {
+                switch (pcb[i].core_mask[0]) {
                 case 1:
                     sys_screen_write("0\n");
                     break;
@@ -538,104 +553,116 @@ long sys_process_show() {
                     sys_screen_write("1\n");
                     break;
                 case 3:
-                    if (&pcb[i] == current_running0)
+                    if (&pcb[i] == current_running0) {
                         sys_screen_write("0\n");
-                    else if (&pcb[i] == current_running1)
+                    } else if (&pcb[i] == current_running1) {
                         sys_screen_write("1\n");
+                    }
                     break;
                 default:
                     break;
                 }
-            } else
+            } else {
                 sys_screen_write("\n");
+            }
             num++;
         }
     }
     return num + 1;
 }
 
-extern int try_get_from_file(const char *file_name, unsigned char **binary, int *length);
-long sys_exec(const char *name, int argc, char **argv) {
+long exec(int pid, const char *file_name, const char *argv[], const char *envp[]) {
     int len = 0;
     unsigned char *binary = NULL;
     /* TODO: use FAT32 disk to read program */
-    if (get_elf_file(name, &binary, &len) == 0) {
-        if (try_get_from_file(name, &binary, &len) == 0)
+    if (get_elf_file(file_name, &binary, &len) == 0) {
+        if (try_get_from_file(file_name, &binary, &len) == 0) {
             return 0;
+        }
     }
-    int i = nextpid();
-    pcb[i].fpid = i;
-    pcb[i].type = USER_PROCESS;
-    pcb[i].pid = i;
-    pcb[i].tid = 0;
-    pcb[i].threadsum = 0;
-    pcb[i].status = TASK_READY;
-    pcb[i].cursor_x = 1;
-    pcb[i].cursor_y = 1;
-    pcb[i].priority.priority = 0;
-    pcb[i].priority.last_sched_time = 0;
-    pcb[i].mode = AUTO_CLEANUP_ON_EXIT;
-    pcb[i].wait_list.next = &pcb[i].wait_list;
-    pcb[i].wait_list.prev = &pcb[i].wait_list;
-    pcb[i].locksum = 0;
-    pcb[i].child_num = 0;
-    pcb[i].father_pid = i;
-    if (glvalid)
-        pcb[i].core_mask = glmask;
-    else
-        pcb[i].core_mask = (*current_running)->core_mask;
+    int i = pid;
+
+    init_pcb_i(i, USER_PROCESS, i, i, 0, i, (*current_running)->core_mask[0]);
+
     ptr_t kernel_stack_kva = get_kernel_address(i);
-    ptr_t user_stack_kva = kernel_stack_kva - 0x2000;
-    allocpid = i;
-    PTE *pgdir = (PTE *)allocPage(1);
+    ptr_t user_stack_kva = kernel_stack_kva - PAGE_SIZE;
+    ptr_t user_stack = USER_STACK_ADDR;
+
+    PTE *pgdir = (PTE *)k_alloc_page(1);
     clear_pgdir((uintptr_t)pgdir);
     share_pgtable(pgdir, pa2kva(PGDIR_PA));
-    void_task test_task = (void_task)load_elf(binary, len, (uintptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))alloc_page_helper);
-    map(USER_STACK_ADDR - 0x1000, kva2pa(user_stack_kva), pgdir);
-    init_pcb_stack(kernel_stack_kva, USER_STACK_ADDR, (ptr_t)test_task, &pcb[i], argc, argv);
+    void_task test_task = (void_task)load_elf(binary, len, (uintptr_t)pgdir, (uintptr_t(*)(uintptr_t, uintptr_t))k_alloc_page_helper);
+    map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pgdir);
     pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT;
+
+    init_user_stack(&user_stack_kva, &user_stack, argv, envp, file_name);
+
+    init_pcb_stack(kernel_stack_kva, user_stack, (ptr_t)test_task, &pcb[i]);
+
     list_add_tail(&pcb[i].list, &ready_queue);
     return i;
 }
 
-long sys_getpid() { return (*current_running)->fpid; }
+long sys_exec(const char *file_name, const char *argv[], const char *envp[]) {
+    return exec(nextpid(), file_name, argv, envp);
+}
 
-long sys_getppid() { return (*current_running)->father_pid; }
+long sys_execve(const char *file_name, const char *argv[], const char *envp[]) {
+    int ret;
+    ret = exec((*current_running)->pid, file_name, argv, envp);
+    if (ret) {
+        k_scheduler();
+    }
+    return ret;
+}
 
-long sys_mthread_create(pid_t *thread, void (*start_routine)(void *), void *arg) {
-    pid_t fpid = (*current_running)->pid;
+long sys_clone(unsigned long flags, void *stack, void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid) {
     int i = nextpid();
-    pcb[fpid].threadid[pcb[fpid].threadsum] = i;
-    pcb[fpid].threadsum++;
-    pcb[i].father_pid = i;
-    pcb[i].tid = pcb[fpid].threadsum;
-    pcb[i].fpid = fpid;
-    pcb[i].type = USER_THREAD;
-    pcb[i].pid = i;
-    pcb[i].status = TASK_READY;
-    pcb[i].cursor_x = 1;
-    pcb[i].cursor_y = 1;
-    pcb[i].priority.priority = 0;
-    pcb[i].priority.last_sched_time = 0;
-    // pcb[i].mode = ENTER_ZOMBIE_ON_EXIT;
-    pcb[i].mode = AUTO_CLEANUP_ON_EXIT;
-    pcb[i].wait_list.next = &pcb[i].wait_list;
-    pcb[i].wait_list.prev = &pcb[i].wait_list;
-    pcb[i].threadsum = 0;
-    pcb[i].locksum = 0;
-    pcb[i].child_num = 0;
-    if (glvalid)
-        pcb[i].core_mask = glmask;
-    else
-        pcb[i].core_mask = (*current_running)->core_mask;
+    pid_t fpid = (*current_running)->pid;
+
+    init_pcb_i(i, USER_PROCESS, i, i, 0, fpid, (*current_running)->core_mask[0]);
+    if (flags & CLONE_CHILD_SETTID) {
+        *(int *)child_tid = pcb[i].tid;
+    }
+    if (flags & CLONE_PARENT_SETTID) {
+        *(int *)parent_tid = pcb[i].tid;
+    }
+    if (flags & CLONE_CHILD_CLEARTID) {
+        pcb[i].clear_ctid = (uint32_t *)child_tid;
+    }
+
+    pcb[fpid].child_pids[pcb[fpid].child_num] = i;
+    pcb[fpid].child_num++;
+
     ptr_t kernel_stack_kva = get_kernel_address(i);
-    ptr_t user_stack_kva = kernel_stack_kva - 0x2000;
-    uint64_t user_stack_uva = USER_STACK_ADDR + 0x1000 * pcb[fpid].threadsum + 0x1000;
-    pcb[i].pgdir = pcb[fpid].pgdir;
-    map(user_stack_uva - 0x1000, kva2pa(user_stack_kva), (pa2kva(pcb[i].pgdir << 12)));
-    init_pcb_stack(kernel_stack_kva, (ptr_t)user_stack_uva, (ptr_t)start_routine, &pcb[i], (uint64_t)arg, NULL);
-    // add pcb to the ready
+    ptr_t user_stack_kva = kernel_stack_kva - PAGE_SIZE;
+    ptr_t user_stack = (ptr_t)stack ? (ptr_t)stack : USER_STACK_ADDR;
+
+    if (flags & CLONE_VM) {
+        pcb[i].pgdir = (*current_running)->pgdir;
+        fork_pgtable((PTE *)(pcb[i].pgdir << NORMAL_PAGE_SHIFT), (pa2kva((*current_running)->pgdir << NORMAL_PAGE_SHIFT)));
+    } else {
+        PTE *pgdir = (PTE *)k_alloc_page(1);
+        clear_pgdir((ptr_t)pgdir);
+        share_pgtable(pgdir, pa2kva(PGDIR_PA));
+        pcb[i].pgdir = kva2pa((uintptr_t)pgdir) >> NORMAL_PAGE_SHIFT;
+    }
+    k_memcpy((uint8_t *)&pcb[i].elf, (uint8_t *)&(*current_running)->elf, sizeof(ELF_info_t));
+
+    clone_pcb_stack(kernel_stack_kva, user_stack, &pcb[i], flags, tls);
+    map(USER_STACK_ADDR - PAGE_SIZE, kva2pa(user_stack_kva - PAGE_SIZE), pa2kva(pcb[i].pgdir << NORMAL_PAGE_SHIFT));
     list_add_tail(&pcb[i].list, &ready_queue);
-    *thread = i;
-    return 1;
+    return i;
+}
+
+long k_getpid(void) {
+    return (*current_running)->fpid;
+}
+
+long sys_getpid() {
+    return k_getpid();
+}
+
+long sys_getppid() {
+    return (*current_running)->father_pid;
 }
\ No newline at end of file
diff --git a/src/kernel/sys/smp.c b/src/kernel/sys/smp.c
index 306f1ae16941e54753d0cbb4b96eeb8562cd9e45..6c8ea73591120c6416371c18053a55a980c4afdb 100644
--- a/src/kernel/sys/smp.c
+++ b/src/kernel/sys/smp.c
@@ -5,15 +5,23 @@
 
 spin_lock_t kernel_lock;
 
-void smp_init() { spin_lock_init(&kernel_lock); }
+void smp_init() {
+    spin_lock_init(&kernel_lock);
+}
 
 void wakeup_other_hart() {
     sbi_send_ipi(NULL);
     __asm__ __volatile__("csrw sip, zero\n\t");
 }
 
-void lock_kernel() { spin_lock_acquire(&kernel_lock); }
+void lock_kernel() {
+    spin_lock_acquire(&kernel_lock);
+}
 
-void unlock_kernel() { spin_lock_release(&kernel_lock); }
+void unlock_kernel() {
+    spin_lock_release(&kernel_lock);
+}
 
-pcb_t *get_current_running() { return get_current_cpu_id() ? current_running1 : current_running0; }
+pcb_t *get_current_running() {
+    return get_current_cpu_id() ? current_running1 : current_running0;
+}
diff --git a/src/kernel/sys/time.c b/src/kernel/sys/time.c
index 7e3f8ae3fb6f676f10237377cf88cce5f32badc3..f7fdd4794369fde2d27c1b9866728e9675ec4913 100644
--- a/src/kernel/sys/time.c
+++ b/src/kernel/sys/time.c
@@ -15,9 +15,13 @@ long get_ticks() {
     return time_elapsed;
 }
 
-uint64_t get_timer() { return get_ticks() / time_base; }
+uint64_t get_timer() {
+    return get_ticks() / time_base;
+}
 
-uint64_t get_time_base() { return time_base; }
+uint64_t get_time_base() {
+    return time_base;
+}
 
 void nano_u_time_converter(nanotime_val_t *nanotime, time_val_t *utime, bool direction) {
     if (direction) {
@@ -35,6 +39,11 @@ void get_nanotime(nanotime_val_t *ntimebuf) {
     ntimebuf->nsec = ((ticks % time_base) * 1e9) / time_base;
 }
 
+uint64_t get_ticks_from_nanotime(nanotime_val_t *ntimebuf) {
+    uint64_t ticks = (ntimebuf->sec * 1e9 + ntimebuf->nsec) * 1e9 / time_base;
+    return ticks;
+}
+
 void copy_nanotime(nanotime_val_t *dst, nanotime_val_t *src) {
     dst->sec = src->sec;
     dst->nsec = src->nsec;
@@ -50,6 +59,12 @@ void minus_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *
     }
 }
 
+void add_nanotime(nanotime_val_t *first, nanotime_val_t *sec, nanotime_val_t *res) {
+    int nsec = first->nsec + sec->nsec;
+    res->nsec = nsec % (int)1e9;
+    res->sec = first->sec + sec->sec + nsec / (int)1e9;
+}
+
 int cmp_nanotime(nanotime_val_t *first, nanotime_val_t *sec) {
     if (first->sec == sec->sec) {
         if (first->nsec > sec->nsec) {
@@ -72,6 +87,11 @@ void get_utime(time_val_t *utimebuf) {
     utimebuf->usec = ((ticks % time_base) * 1e6) / time_base;
 }
 
+uint64_t get_ticks_from_time(time_val_t *ntimebuf) {
+    uint64_t ticks = (ntimebuf->sec * 1e6 + ntimebuf->usec) * 1e6 / time_base;
+    return ticks;
+}
+
 void copy_utime(time_val_t *dst, time_val_t *src) {
     dst->sec = src->sec;
     dst->usec = src->usec;
@@ -87,6 +107,12 @@ void minus_utime(time_val_t *first, time_val_t *sec, time_val_t *res) {
     }
 }
 
+void add_utime(time_val_t *first, time_val_t *sec, time_val_t *res) {
+    int usec = first->usec + sec->usec;
+    res->usec = usec % (int)1e6;
+    res->sec = first->sec + sec->sec + usec / (int)1e6;
+}
+
 int cmp_utime(time_val_t *first, time_val_t *sec) {
     if (first->sec == sec->sec) {
         if (first->usec > sec->usec) {
@@ -110,11 +136,16 @@ long sys_time(__kernel_time_t *tloc) {
 }
 
 long sys_times(tms_t *tbuf) {
-    tbuf->tms_stime = (*current_running)->stime;
-    tbuf->tms_utime = (*current_running)->utime;
+    tbuf->tms_stime = get_ticks_from_time(&(*current_running)->resources.ru_stime);
+    tbuf->tms_utime = get_ticks_from_time(&(*current_running)->resources.ru_utime);
+    tbuf->tms_cstime = (*current_running)->dead_child_stime;
+    tbuf->tms_cutime = (*current_running)->dead_child_utime;
     for (int i = 0; i < (*current_running)->child_num; i++) {
-        tbuf->tms_cstime += pcb[(*current_running)->child_pid[i]].stime;
-        tbuf->tms_cutime += pcb[(*current_running)->child_pid[i]].utime;
+        if ((*current_running)->child_pids[i] == 0) {
+            continue;
+        }
+        tbuf->tms_cstime += get_ticks_from_time(&pcb[(*current_running)->child_pids[i]].resources.ru_stime);
+        tbuf->tms_cutime += get_ticks_from_time(&pcb[(*current_running)->child_pids[i]].resources.ru_utime);
     }
     return get_ticks();
 }
diff --git a/src/libs/math.c b/src/libs/math.c
new file mode 100644
index 0000000000000000000000000000000000000000..65898b53dcc39e6f34b9ec16585a4aeb8e7f28ce
--- /dev/null
+++ b/src/libs/math.c
@@ -0,0 +1,8 @@
+#include <lib/math.h>
+
+int k_min(int a, int b) {
+    if (a < b) {
+        return a;
+    }
+    return b;
+}
\ No newline at end of file
diff --git a/src/libs/printk.c b/src/libs/printk.c
index 179ad6ef69fe4871b5202fe0dbdf87f0a82fc4b7..7d31439561e760f0751a06f5150e440c9182ccc6 100644
--- a/src/libs/printk.c
+++ b/src/libs/printk.c
@@ -7,8 +7,9 @@
 
 static unsigned int mini_strlen(const char *s) {
     unsigned int len = 0;
-    while (s[len] != '\0')
+    while (s[len] != '\0') {
         len++;
+    }
     return len;
 }
 
@@ -18,8 +19,9 @@ static unsigned int mini_itoa(long value, unsigned int radix, unsigned int upper
     unsigned int i, len;
 
     /* No support for unusual radixes. */
-    if (radix > 16)
+    if (radix > 16) {
         return 0;
+    }
 
     if (value < 0 && !unsig) {
         negative = 1;
@@ -42,11 +44,13 @@ static unsigned int mini_itoa(long value, unsigned int radix, unsigned int upper
         }
     } while (value != 0);
 
-    for (i = (pbuffer - buffer); i < zero_pad; i++)
+    for (i = (pbuffer - buffer); i < zero_pad; i++) {
         *(pbuffer++) = '0';
+    }
 
-    if (negative)
+    if (negative) {
         *(pbuffer++) = '-';
+    }
 
     *(pbuffer) = '\0';
 
@@ -68,8 +72,9 @@ struct mini_buff {
 };
 
 static int _putc(int ch, struct mini_buff *b) {
-    if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len)
+    if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len) {
         return 0;
+    }
     *(b->pbuffer++) = ch;
     *(b->pbuffer) = '\0';
     return 1;
@@ -78,12 +83,14 @@ static int _putc(int ch, struct mini_buff *b) {
 static int _puts(char *s, unsigned int len, struct mini_buff *b) {
     unsigned int i;
 
-    if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len)
+    if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len) {
         len = b->buffer_len - (b->pbuffer - b->buffer) - 1;
+    }
 
     /* Copy to buffer */
-    for (i = 0; i < len; i++)
+    for (i = 0; i < len; i++) {
         *(b->pbuffer++) = s[i];
+    }
     *(b->pbuffer) = '\0';
 
     return len;
@@ -99,11 +106,12 @@ static int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt
     b.buffer_len = buffer_len;
 
     while ((ch = *(fmt++))) {
-        if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len)
+        if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len) {
             break;
-        if (ch != '%')
+        }
+        if (ch != '%') {
             _putc(ch, &b);
-        else {
+        } else {
             char zero_pad = 0;
             int longflag = 0;
             char *ptr;
@@ -114,8 +122,9 @@ static int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt
             /* Zero padding requested */
             if (ch == '0') {
                 while ((ch = *(fmt++))) {
-                    if (ch == '\0')
+                    if (ch == '\0') {
                         goto end;
+                    }
                     if (ch >= '0' && ch <= '9') {
                         zero_pad = zero_pad * 10 + ch - '0';
                     } else {
@@ -179,7 +188,6 @@ static int _vprint(const char *fmt, va_list _va, void (*output)(char *)) {
 
     buff[ret] = '\0';
 
-    disable_preempt();
     output(buff);
     /*for (int i = 0; i < ret; ++i) {
         if (buff[i] == '\n') {
@@ -190,12 +198,13 @@ static int _vprint(const char *fmt, va_list _va, void (*output)(char *)) {
             (*current_running)->cursor_x++;
         }
     }*/
-    enable_preempt();
 
     return ret;
 }
 
-int vprintk(const char *fmt, va_list _va) { return _vprint(fmt, _va, port_write); }
+int vprintk(const char *fmt, va_list _va) {
+    return _vprint(fmt, _va, port_write);
+}
 
 int printk(const char *fmt, ...) {
     __asm__ __volatile__("csrr x0, sscratch\n");
@@ -209,7 +218,9 @@ int printk(const char *fmt, ...) {
     return ret;
 }
 
-int vprints(const char *fmt, va_list _va) { return _vprint(fmt, _va, (void (*)(char *))sys_screen_write); }
+int vprints(const char *fmt, va_list _va) {
+    return _vprint(fmt, _va, (void (*)(char *))sys_screen_write);
+}
 
 int prints(const char *fmt, ...) {
     int ret = 0;
diff --git a/src/libs/string.c b/src/libs/string.c
index acb7da1875ddfb42e31b280f448a63eff0bb7041..46f848374321cdb1aafda0f46fe11245f80b409d 100644
--- a/src/libs/string.c
+++ b/src/libs/string.c
@@ -1,19 +1,18 @@
 #include <lib/string.h>
 
-int strlen(const char *src) {
+int k_strlen(const char *src) {
     int i;
-    for (i = 0; src[i] != '\0'; i++) {
-    }
+    for (i = 0; src[i] != '\0'; i++) {}
     return i;
 }
 
-void memcpy(uint8_t *dest, const uint8_t *src, uint32_t len) {
+void k_memcpy(uint8_t *dest, const uint8_t *src, uint32_t len) {
     for (; len != 0; len--) {
         *dest++ = *src++;
     }
 }
 
-void memset(void *dest, uint8_t val, uint32_t len) {
+void k_memset(void *dest, uint8_t val, uint32_t len) {
     uint8_t *dst = (uint8_t *)dest;
 
     for (; len != 0; len--) {
@@ -21,9 +20,11 @@ void memset(void *dest, uint8_t val, uint32_t len) {
     }
 }
 
-void bzero(void *dest, uint32_t len) { memset(dest, 0, len); }
+void k_bzero(void *dest, uint32_t len) {
+    k_memset(dest, 0, len);
+}
 
-int strcmp(const char *str1, const char *str2) {
+int k_strcmp(const char *str1, const char *str2) {
     while (*str1 && *str2) {
         if (*str1 != *str2) {
             return (*str1) - (*str2);
@@ -34,7 +35,7 @@ int strcmp(const char *str1, const char *str2) {
     return (*str1) - (*str2);
 }
 
-char *strcpy(char *dest, const char *src) {
+char *k_strcpy(char *dest, const char *src) {
     char *tmp = dest;
 
     while (*src) {
@@ -46,7 +47,7 @@ char *strcpy(char *dest, const char *src) {
     return tmp;
 }
 
-char *strcat(char *dest, const char *src) {
+char *k_strcat(char *dest, const char *src) {
     char *tmp = dest;
 
     while (*dest != '\0') {
@@ -60,3 +61,13 @@ char *strcat(char *dest, const char *src) {
 
     return tmp;
 }
+
+int k_strlistlen(char *src[]) {
+    int num = 0;
+    if (src) {
+        while (src[num]) {
+            num++;
+        }
+    }
+    return num;
+}
\ No newline at end of file
diff --git a/src/user/user_programs.c b/src/user/user_programs.c
index ead83f4ceed6abcbcf705382c24d9f36d0ecc405..7171b3b6fecd65c125c2d42b8c5563ce037fd8f2 100644
--- a/src/user/user_programs.c
+++ b/src/user/user_programs.c
@@ -2284,7 +2284,7 @@ int _length___test_test_all_elf = 61944;
 ElfFile elf_files[8] = {{.file_name = "shell", .file_content = _elf___test_test_shell_elf, .file_length = &_length___test_test_shell_elf}, {.file_name = "fs", .file_content = _elf___test_test_fs_elf, .file_length = &_length___test_test_fs_elf}, {.file_name = "bigfile", .file_content = _elf___test_test_bigfile_elf, .file_length = &_length___test_test_bigfile_elf}, {.file_name = "emo", .file_content = _elf___test_emo_elf, .file_length = &_length___test_emo_elf}, {.file_name = "multi", .file_content = _elf___test_test_multi_elf, .file_length = &_length___test_test_multi_elf}, {.file_name = "check", .file_content = _elf___test_check_elf, .file_length = &_length___test_check_elf}, {.file_name = "fly", .file_content = _elf___test_fly_elf, .file_length = &_length___test_fly_elf}, {.file_name = "all", .file_content = _elf___test_test_all_elf, .file_length = &_length___test_test_all_elf}};
 int get_elf_file(const char *file_name, unsigned char **binary, int *length) {
     for (int i = 0; i < 8; ++i) {
-        if (strcmp(elf_files[i].file_name, file_name) == 0) {
+        if (k_strcmp(elf_files[i].file_name, file_name) == 0) {
             *binary = elf_files[i].file_content;
             *length = *elf_files[i].file_length;
             return 1;