diff --git a/codes/fat32-fuse/fat32.img b/codes/fat32-fuse/fat32.img
index 0362402dac04a1769ba8202e15cb554892e58e54..4a960b697f0ca3a5ee136c63e3438d75e2f7eaf1 100755
Binary files a/codes/fat32-fuse/fat32.img and b/codes/fat32-fuse/fat32.img differ
diff --git a/codes/os/Makefile b/codes/os/Makefile
index 62be84690f4ab6d80f8ad5912459f4aabbfdc5b5..0196f25eb0348fc4a18ffec2bee04212e7d4d2eb 100755
--- a/codes/os/Makefile
+++ b/codes/os/Makefile
@@ -40,10 +40,10 @@ DISASM ?= -x
 build: env $(KERNEL_BIN)
 
 env:
-#(rustup target list | grep "riscv64imac-unknown-none-elf (installed)") || rustup target add $(TARGET)
-#cargo install cargo-binutils
-#rustup component add rust-src
-#rustup component add llvm-tools-preview
+	(rustup target list | grep "riscv64imac-unknown-none-elf (installed)") || rustup target add $(TARGET)
+	cargo install cargo-binutils
+	rustup component add rust-src
+	rustup component add llvm-tools-preview
 
 #(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add $(TARGET)
 #cargo install cargo-binutils
diff --git a/codes/os/src/fs/stdio.rs b/codes/os/src/fs/stdio.rs
index eab8d7182b336118e1b82b30827639575aed1822..a3e6fadcf38d2c74d3234ce5bd3f8d2dd4d429f1 100755
--- a/codes/os/src/fs/stdio.rs
+++ b/codes/os/src/fs/stdio.rs
@@ -27,10 +27,14 @@ impl File for Stdin {
     fn readable(&self) -> bool { true }
     fn writable(&self) -> bool { false }
     fn read(&self, mut user_buf: UserBuffer) -> usize {
-        assert_eq!(user_buf.len(), 1);
+        //assert_eq!(user_buf.len(), 1);
         let lock = STDINLOCK.lock();
         // busy loop
         let mut c: usize;
+        let mut count = 0;
+        if user_buf.len() > 1{
+            return 0;
+        }
         loop {
             c = console_getchar();
             if c == 0 {
@@ -41,8 +45,36 @@ impl File for Stdin {
             }
         }
         let ch = c as u8;
-        unsafe { user_buf.buffers[0].as_mut_ptr().write_volatile(ch); }
-        1
+        unsafe { 
+            user_buf.buffers[0].as_mut_ptr().write_volatile(ch); 
+            //user_buf.write_at(count, ch);
+        }
+        return 1
+        /* 
+        loop {
+            if count == user_buf.len(){
+                break;
+            }
+            loop {
+                c = console_getchar();
+                if c == 0 {
+                    suspend_current_and_run_next();
+                    continue;
+                } else {
+                    break;
+                }
+            }
+            let ch = c as u8;
+            if ch as char == '\n' {
+                break;
+            }
+            unsafe { 
+                //user_buf.buffers[0].as_mut_ptr().write_volatile(ch); 
+                user_buf.write_at(count, ch);
+            }
+            count += 1;
+        }
+        count*/
     }
     fn write(&self, _user_buf: UserBuffer) -> usize {
         panic!("Cannot write to stdin!");
diff --git a/codes/os/src/mm/page_table.rs b/codes/os/src/mm/page_table.rs
index 26ace70b99443e0993c9a462020953c52ada4f57..3006abe27ada460ce03a83a4f8b1d12ce56faca8 100755
--- a/codes/os/src/mm/page_table.rs
+++ b/codes/os/src/mm/page_table.rs
@@ -374,6 +374,22 @@ impl UserBuffer {
         return len;
     }
 
+    pub fn write_at(&mut self, offset:usize, char:u8)->isize{
+        if offset > self.len() {
+            return -1
+        }
+        let mut head = 0;
+        for b in self.buffers.iter_mut() {
+            if offset > head && offset < head + b.len() {
+                (**b)[offset - head] = char;
+                //b.as_mut_ptr()
+            } else {
+                head += b.len();
+            }
+        }
+        0
+    }
+
     // 将UserBuffer的数据读入一个Buffer,返回读取长度
     pub fn read(&self, buff:&mut [u8])->usize{
         let len = self.len().min(buff.len());
diff --git a/codes/user/src/bin/user_shell.rs b/codes/user/src/bin/user_shell.rs
index 3cc524fcb46216f5c6cab106ed49437ca29f873b..4085f6c6db32cf60f7da7745437c9e16d5adafaf 100755
--- a/codes/user/src/bin/user_shell.rs
+++ b/codes/user/src/bin/user_shell.rs
@@ -401,49 +401,60 @@ impl ArgMachine{
         println!("!!!!!!!!!AUTORUN!!!!!!!!!");
         let mut testsuits :Vec<&str>= Vec::new();
         // testsuits.push("sh\0");
-        //testsuits.push("echo\0 \"#### independent command test\"\0");
-        //testsuits.push("basename\0 /aaa/bbb\0");
-        //testsuits.push("cal\0");
-        //testsuits.push("clear\0");
-        //testsuits.push("expr\0 1\0 +\0 1\0");
-        //testsuits.push("pwd\0");
-        //testsuits.push("dirname\0 /aaa/bbb\0");
-        //testsuits.push("du\0");
-        //testsuits.push("uptime\0");
-        //testsuits.push("date\0");
-        //testsuits.push("false\0");
-        //testsuits.push("true\0");
-        //testsuits.push("uname\0");
-        //testsuits.push("printf\0 \"abc\n\"\0");
-        //testsuits.push("kill\0 10\0");
-        //testsuits.push("echo\0 \"#### file opration test\"\0");
-        //testsuits.push("touch\0 test.txt\0");
-        //testsuits.push("echo\0 \"hello world\"\0 >>\0 test.txt\0");
-        //testsuits.push("tail\0 test.txt\0");
-        //testsuits.push("cat\0 test.txt\0");
-        //testsuits.push("cut\0 -c\0 3\0 test.txt\0");
-        //testsuits.push("od\0 test.txt\0");
-        //testsuits.push("head\0 test.txt\0");
-        //testsuits.push("hexdump\0 -C\0 test.txt\0");
-        //testsuits.push("md5sum\0 test.txt\0");
-        //testsuits.push("strings\0 test.txt\0");
-        //testsuits.push("wc\0 test.txt\0");
-        //testsuits.push("find\0 -name\0 \"busybox_cmd.txt\"\0");  
-        //testsuits.push("dmesg\0");
-        //testsuits.push("echo\0 \"ccccccc\"\0 >>\0 test.txt\0");
-        //testsuits.push("echo\0 \"bbbbbbb\"\0 >>\0 test.txt\0");
-        //testsuits.push("echo\0 \"aaaaaaa\"\0 >>\0 test.txt\0");
-        //testsuits.push("echo\0 \"2222222\"\0 >>\0 test.txt\0");
-        //testsuits.push("echo\0 \"1111111\"\0 >>\0 test.txt\0");
-        //testsuits.push("echo\0 \"bbbbbbb\"\0 >>\0 test.txt\0");
-        //testsuits.push("stat\0 test.txt\0");//?
-        //testsuits.push("grep\0 hello\0 busybox_cmd.txt\0");  //ok
-        //testsuits.push("mkdir\0 test_dir\0");
-        //testsuits.push("mv\0 test_dir\0 test\0"); 
-        //testsuits.push("rmdir\0 test\0"); 
-        //testsuits.push("which\0 ls\0");
+        testsuits.push("echo\0 \"#### independent command test\"\0");
+        testsuits.push("basename\0 /aaa/bbb\0");
+        testsuits.push("cal\0");
+        testsuits.push("clear\0");
+        testsuits.push("expr\0 1\0 +\0 1\0");
+        testsuits.push("pwd\0");
+        testsuits.push("dirname\0 /aaa/bbb\0");
+        testsuits.push("du\0");
+        testsuits.push("uptime\0");
+        testsuits.push("date\0");
+        testsuits.push("false\0");
+        testsuits.push("true\0");
+        testsuits.push("uname\0");
+        testsuits.push("printf\0 \"abc\n\"\0");
+        testsuits.push("kill\0 10\0");
+        testsuits.push("echo\0 \"#### file opration test\"\0");
+        testsuits.push("touch\0 test.txt\0");
+        testsuits.push("echo\0 \"hello world\"\0 >>\0 test.txt\0");
+        testsuits.push("tail\0 test.txt\0");
+        testsuits.push("cat\0 test.txt\0");
+        testsuits.push("cut\0 -c\0 3\0 test.txt\0");
+        testsuits.push("od\0 test.txt\0");
+        testsuits.push("head\0 test.txt\0");
+        testsuits.push("hexdump\0 -C\0 test.txt\0");
+        testsuits.push("md5sum\0 test.txt\0");
+        testsuits.push("strings\0 test.txt\0");
+        testsuits.push("wc\0 test.txt\0");
+        testsuits.push("find\0 -name\0 \"busybox_cmd.txt\"\0");  
+        testsuits.push("dmesg\0");
+        testsuits.push("echo\0 \"ccccccc\"\0 >>\0 test.txt\0");
+        testsuits.push("echo\0 \"bbbbbbb\"\0 >>\0 test.txt\0");
+        testsuits.push("echo\0 \"aaaaaaa\"\0 >>\0 test.txt\0");
+        testsuits.push("echo\0 \"2222222\"\0 >>\0 test.txt\0");
+        testsuits.push("echo\0 \"1111111\"\0 >>\0 test.txt\0");
+        testsuits.push("echo\0 \"bbbbbbb\"\0 >>\0 test.txt\0");
+        testsuits.push("stat\0 test.txt\0");//?
+        testsuits.push("grep\0 hello\0 busybox_cmd.txt\0");  //ok
+        testsuits.push("mkdir\0 test_dir\0");
+        testsuits.push("mv\0 test_dir\0 test\0"); 
+        testsuits.push("rmdir\0 test\0"); 
+        testsuits.push("which\0 ls\0");
         testsuits.push("cp\0 busybox_cmd.txt\0 busybox_cmd.bak\0");
         testsuits.push("rm\0 busybox_cmd.bak\0");
+        testsuits.push("rm\0 test.txt\0");    //ok    
+        // lua: all pass
+        testsuits.push("date.lua\0");
+        testsuits.push("file_io.lua\0");
+        testsuits.push("random.lua\0");
+        testsuits.push("remove.lua\0");
+        testsuits.push("sin30.lua\0");
+        testsuits.push("max_min.lua\0");
+        testsuits.push("round_num.lua\0");
+        testsuits.push("sort.lua\0");
+        testsuits.push("strings.lua\0");
         
         //half
         testsuits.push("ls\0");
@@ -452,22 +463,25 @@ impl ArgMachine{
         testsuits.push("sleep\0 1\0");
         
         //fail
-        //testsuits.push("sh\0");
-        testsuits.push("sort\0 test.txt\0 |\0 ./busybox uniq\0");
-        testsuits.push("df\0");
-        
-        testsuits.push("[\0 -f\0 test.txt\0 ]\0");
-        //testsuits.push("more\0 test.txt\0");
-        
-        
-        testsuits.push("rm\0 test.txt\0");    //ok           
-        testsuits.push("free\0");
-        testsuits.push("hwclock\0");
-        testsuits.push("ps\0");
-        
+        //testsuits.push("sort\0 test.txt\0 |\0 ./busybox uniq\0");
+        //testsuits.push("df\0");     
+        //testsuits.push("[\0 -f\0 test.txt\0 ]\0");
+        ////testsuits.push("more\0 test.txt\0");
+        //testsuits.push("free\0");
+        //testsuits.push("hwclock\0");
+        //testsuits.push("ps\0");
 
         for programname_op in testsuits.iter(){
-            let exec_op = String::from("busybox\0 ") + programname_op;
+            let mut is_lua = false;
+            let exec_path = {
+                if programname_op.contains("lua") {
+                    is_lua = true;
+                    String::from("lua\0")
+                } else {
+                    String::from("busybox\0")
+                }
+            };
+            let exec_op = exec_path.clone() + " " + programname_op;
             // let exec_op = String::from("") + programname_op;
             let mut exit_code = 0;
             let args: Vec<&str> = exec_op.as_str().split(' ').collect();
@@ -483,7 +497,7 @@ impl ArgMachine{
             // print!("ars:{:?}",args);
             let pid = fork();
             if pid == 0 {
-                if exec("busybox\0", args_addr.as_slice()) == -1 {
+                if exec(exec_path.as_str(), args_addr.as_slice()) == -1 {
                     println!("Error when executing autorun_testsuites!");
                     shutdown();
                 }
@@ -492,10 +506,18 @@ impl ArgMachine{
                 waitpid(pid as usize, &mut exit_code);
                 let result = str::replace(*programname_op,"\0","");
                 if result != "false" && exit_code != 0{
-                    println!("testcase {} fail", programname_op);
+                    if is_lua {
+                        println!("testcase lua {} fail", result);
+                    } else {
+                        println!("testcase busybox {} fail", result);
+                    }   
                 }
                 else{
-                    println!("testcase {} success", programname_op);
+                    if is_lua {
+                        println!("testcase lua {} success", result);
+                    } else {
+                        println!("testcase busybox {} success", result);
+                    }   
                 }
             }
         }