From 731d6319e43985ca0e9a616ab4ed49230aaa325e Mon Sep 17 00:00:00 2001
From: WangRunji <wangrunji0408@163.com>
Date: Fri, 18 May 2018 11:49:27 +0800
Subject: [PATCH] Can load user programs from sfs.img (hard linked).

---
 Cargo.toml               |   1 +
 Makefile                 |   3 +++
 src/fs.rs                |  50 +++++++++++++++++++++++++++++++++++++
 src/lib.rs               |   4 +++
 src/process/mod.rs       |  52 +++++++++++++++------------------------
 src/process/process.rs   |  28 ++++++++++-----------
 src/process/processor.rs |  19 +++++++-------
 user/hello.o             | Bin 40914 -> 0 bytes
 8 files changed, 102 insertions(+), 55 deletions(-)
 create mode 100644 src/fs.rs
 delete mode 100644 user/hello.o

diff --git a/Cargo.toml b/Cargo.toml
index ba3cd0d..a27d98d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,6 +25,7 @@ linked_list_allocator = "0.5.0"
 redox_syscall = "0.1.37"
 xmas-elf = "0.6"
 arrayvec = { version = "0.4.7", default-features = false }
+simple-filesystem = { path = "../simple-filesystem" }
 
 [build-dependencies]
 cc = "1.0"
diff --git a/Makefile b/Makefile
index f3c31ae..9db3fe0 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,9 @@ clean:
 run: $(iso)
 	@qemu-system-$(arch) $(qemu_opts) || [ $$? -eq 11 ] # run qemu and assert it exit 11
 
+debug: $(iso)
+	@qemu-system-$(arch) $(qemu_opts) -s -S &
+
 iso: $(iso)
 
 build: iso
diff --git a/src/fs.rs b/src/fs.rs
new file mode 100644
index 0000000..e53a2d4
--- /dev/null
+++ b/src/fs.rs
@@ -0,0 +1,50 @@
+use simple_filesystem::*;
+use alloc::boxed::Box;
+use process;
+
+extern {
+    fn _binary_user_sfs_img_start();
+    fn _binary_user_sfs_img_end();
+    fn _binary_user_forktest_start();
+    fn _binary_user_forktest_end();
+}
+
+struct MemBuf(&'static [u8]);
+
+impl MemBuf {
+    unsafe fn new(begin: unsafe extern fn(), end: unsafe extern fn()) -> Self {
+        use core::slice;
+        MemBuf(slice::from_raw_parts(begin as *const u8, end as usize - begin as usize))
+    }
+}
+
+impl Device for MemBuf {
+    fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option<usize> {
+        let slice = self.0;
+        let len = buf.len().min(slice.len() - offset);
+        buf[..len].copy_from_slice(&slice[offset..offset + len]);
+        Some(len)
+    }
+    fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option<usize> {
+        None
+    }
+}
+
+pub fn load_sfs() {
+    let slice = unsafe { MemBuf::new(_binary_user_sfs_img_start, _binary_user_sfs_img_end) };
+    let sfs = SimpleFileSystem::open(Box::new(slice)).unwrap();
+    let root = sfs.root_inode();
+    let files = root.borrow().list().unwrap();
+    debug!("Loading programs: {:?}", files);
+
+    for name in files.iter().filter(|&f| f != "." && f != "..") {
+        static mut BUF: [u8; 64 << 12] = [0; 64 << 12];
+        let file = root.borrow().lookup(name.as_str()).unwrap();
+        let len = file.borrow().read_at(0, unsafe { &mut BUF }).unwrap();
+        process::add_user_process(name.as_str(), unsafe { &BUF[..len] });
+    }
+
+    process::add_user_process("forktest", unsafe { MemBuf::new(_binary_user_forktest_start, _binary_user_forktest_end).0 });
+
+    process::print();
+}
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index 919c604..181b54b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -34,6 +34,7 @@ extern crate bit_field;
 extern crate syscall as redox_syscall;
 extern crate xmas_elf;
 extern crate arrayvec;
+extern crate simple_filesystem;
 
 #[macro_use]    // print!
 mod io;
@@ -45,6 +46,7 @@ mod macros;
 mod consts;
 mod process;
 mod syscall;
+mod fs;
 
 #[allow(dead_code)]
 #[cfg(target_arch = "x86_64")]
@@ -81,6 +83,8 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! {
 //    arch::smp::start_other_cores(&acpi, &mut memory_controller);
     process::init(memory_controller);
 
+    fs::load_sfs();
+
     unsafe{ arch::interrupt::enable(); }
 
     // 直接进入用户态暂不可用:内核代码用户不可访问
diff --git a/src/process/mod.rs b/src/process/mod.rs
index a838c6b..15bb749 100644
--- a/src/process/mod.rs
+++ b/src/process/mod.rs
@@ -1,6 +1,7 @@
 use memory::MemoryController;
 use spin::{Once, Mutex};
 use core::slice;
+use alloc::String;
 
 use self::process::*;
 use self::processor::*;
@@ -15,48 +16,20 @@ mod processor;
 /// * Debug: 用于Debug输出
 use arch::interrupt::TrapFrame;
 
-// TODO: 使用宏来更优雅地导入符号,现在会有编译错误
-//
-//    #![feature(concat_idents)]
-//
-//    macro_rules! binary_symbol {
-//        ($name: ident) => {
-//            extern {
-//                fn concat_idents!(_binary_user_, $name, _start)();
-//                fn concat_idents!(_binary_user_, $name, _end)();
-//            }
-//        };
-//    }
-//
-//    binary_symbol!(forktest);
-
-#[cfg(feature = "link_user_program")]
-extern {
-    fn _binary_user_forktest_start();
-    fn _binary_user_forktest_end();
-    fn _binary_hello_start();
-    fn _binary_hello_end();
-}
-
-
 pub fn init(mut mc: MemoryController) {
     PROCESSOR.call_once(|| {Mutex::new({
         let initproc = Process::new_init(&mut mc);
         let idleproc = Process::new("idle", idle_thread, &mut mc);
-        #[cfg(feature = "link_user_program")]
-//        let forktest = Process::new_user(_binary_user_forktest_start as usize,
-//                                         _binary_user_forktest_end as usize, &mut mc);
-        let hello = Process::new_user(_binary_hello_start as usize,
-                                      _binary_hello_end as usize, &mut mc);
-        let mut processor = Processor::new(mc);
+        let mut processor = Processor::new();
         processor.add(initproc);
         processor.add(idleproc);
-        processor.add(hello);
         processor
     })});
+    MC.call_once(|| Mutex::new(mc));
 }
 
 static PROCESSOR: Once<Mutex<Processor>> = Once::new();
+static MC: Once<Mutex<MemoryController>> = Once::new();
 
 /// Called by timer handler in arch
 /// 设置rsp,指向接下来要执行线程的 内核栈顶
@@ -77,7 +50,10 @@ extern fn idle_thread() {
 
 /// Fork the current process
 pub fn sys_fork(tf: &TrapFrame) -> i32 {
-    PROCESSOR.try().unwrap().lock().fork(tf);
+    let mut processor = PROCESSOR.try().unwrap().lock();
+    let mut mc = MC.try().unwrap().lock();
+    let new = processor.current().fork(tf, &mut mc);
+    processor.add(new);
     0
 }
 
@@ -99,4 +75,16 @@ pub fn sys_exit(rsp: &mut usize, error_code: usize) -> i32 {
     processor.schedule(rsp);
     processor.exit(pid, error_code);
     0
+}
+
+pub fn add_user_process(name: &str, data: &[u8]) {
+    let mut processor = PROCESSOR.try().unwrap().lock();
+    let mut mc = MC.try().unwrap().lock();
+    let mut new = Process::new_user(data, &mut mc);
+    new.name = String::from(name);
+    processor.add(new);
+}
+
+pub fn print() {
+    debug!("{:#x?}", *PROCESSOR.try().unwrap().lock());
 }
\ No newline at end of file
diff --git a/src/process/process.rs b/src/process/process.rs
index 03291ef..7dd18d6 100644
--- a/src/process/process.rs
+++ b/src/process/process.rs
@@ -2,13 +2,12 @@ use super::*;
 use memory::{self, Stack, InactivePageTable};
 use xmas_elf::{ElfFile, program::{Flags, ProgramHeader}, header::HeaderPt2};
 use core::slice;
-use alloc::rc::Rc;
-use rlibc::memcpy;
+use alloc::{rc::Rc, String};
 
 #[derive(Debug)]
 pub struct Process {
     pub(in process) pid: Pid,
-                    name: &'static str,
+    pub(in process) name: String,
                     kstack: Stack,
     pub(in process) memory_set: Option<MemorySet>,
     pub(in process) page_table: Option<InactivePageTable>,
@@ -26,14 +25,14 @@ pub enum Status {
 
 impl Process {
     /// Make a new kernel thread
-    pub fn new(name: &'static str, entry: extern fn(), mc: &mut MemoryController) -> Self {
+    pub fn new(name: &str, entry: extern fn(), mc: &mut MemoryController) -> Self {
         let kstack = mc.alloc_stack(7).unwrap();
         let tf = TrapFrame::new_kernel_thread(entry, kstack.top());
         let rsp = kstack.push_at_top(tf);
 
         Process {
             pid: 0,
-            name,
+            name: String::from(name),
             kstack,
             memory_set: None,
             page_table: None,
@@ -49,7 +48,7 @@ impl Process {
         assert_has_not_been_called!();
         Process {
             pid: 0,
-            name: "init",
+            name: String::from("init"),
             kstack: mc.kernel_stack.take().unwrap(),
             memory_set: None,
             page_table: None,
@@ -62,10 +61,10 @@ impl Process {
     /// Make a new user thread
     /// The program elf data is placed at [begin, end)
     /// uCore x86 32bit program is planned to be supported.
-    pub fn new_user(begin: usize, end: usize, mc: &mut MemoryController) -> Self {
+    pub fn new_user(data: &[u8], mc: &mut MemoryController) -> Self {
         // Parse elf
-        let slice = unsafe{ slice::from_raw_parts(begin as *const u8, end - begin) };
-        let elf = ElfFile::new(slice).expect("failed to read elf");
+        let begin = data.as_ptr() as usize;
+        let elf = ElfFile::new(data).expect("failed to read elf");
         let is32 = match elf.header.pt2 {
             HeaderPt2::Header32(_) => true,
             HeaderPt2::Header64(_) => false,
@@ -83,7 +82,7 @@ impl Process {
         memory_set.push(MemoryArea::new(user_stack_buttom, user_stack_top,
                                         EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE, "user_stack"));
         let page_table = mc.make_page_table(&memory_set);
-        debug!("{:#x?}", memory_set);
+//        debug!("{:#x?}", memory_set);
 
         let entry_addr = match elf.header.pt2 {
             HeaderPt2::Header32(header) => header.entry_point as usize,
@@ -97,7 +96,8 @@ impl Process {
                     ProgramHeader::Ph32(ph) => (ph.virtual_addr as usize, ph.offset as usize, ph.file_size as usize),
                     ProgramHeader::Ph64(ph) => (ph.virtual_addr as usize, ph.offset as usize, ph.file_size as usize),
                 };
-                unsafe { memcpy(virt_addr as *mut u8, (begin + offset) as *mut u8, file_size) };
+                let target = unsafe { slice::from_raw_parts_mut(virt_addr as *mut u8, file_size) };
+                target.copy_from_slice(&data[offset..offset + file_size]);
             }
             if is32 {
                 unsafe {
@@ -114,11 +114,11 @@ impl Process {
         let kstack = mc.alloc_stack(7).unwrap();
         let tf = TrapFrame::new_user_thread(entry_addr, user_stack_top, is32);
         let rsp = kstack.push_at_top(tf);
-        debug!("rsp = {:#x}", rsp);
+//        debug!("rsp = {:#x}", rsp);
 
         Process {
             pid: 0,
-            name: "user",
+            name: String::new(),
             kstack,
             memory_set: Some(memory_set),
             page_table: Some(page_table),
@@ -157,7 +157,7 @@ impl Process {
 
         Process {
             pid: 0,
-            name: "fork",
+            name: self.name.clone() + "_fork",
             kstack,
             memory_set: Some(memory_set),
             page_table: Some(page_table),
diff --git a/src/process/processor.rs b/src/process/processor.rs
index 90cb017..93218fa 100644
--- a/src/process/processor.rs
+++ b/src/process/processor.rs
@@ -2,17 +2,16 @@ use alloc::BTreeMap;
 use memory::{ActivePageTable, InactivePageTable};
 use super::*;
 use core::cell::RefCell;
+use core::fmt::{Debug, Formatter, Error};
 
 pub struct Processor {
-    mc: RefCell<MemoryController>,
     procs: BTreeMap<Pid, Process>,
     current_pid: Pid,
 }
 
 impl Processor {
-    pub fn new(mc: MemoryController) -> Self {
+    pub fn new() -> Self {
         Processor {
-            mc: RefCell::new(mc),
             procs: BTreeMap::<Pid, Process>::new(),
             current_pid: 0,
         }
@@ -85,12 +84,6 @@ impl Processor {
         self.get(self.current_pid)
     }
 
-    /// Fork the current process
-    pub fn fork(&mut self, tf: &TrapFrame) {
-        let new = self.current().fork(tf, &mut self.mc.borrow_mut());
-        self.add(new);
-    }
-
     pub fn kill(&mut self, pid: Pid) {
         let process = self.procs.get_mut(&pid).unwrap();
         process.status = Status::Exited;
@@ -101,4 +94,12 @@ impl Processor {
         debug!("Processor: {} exit, code: {}", pid, error_code);
         self.kill(pid);
     }
+}
+
+impl Debug for Processor {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        f.debug_map()
+            .entries(self.procs.iter().map(|(pid, proc0)| { (pid, &proc0.name) }))
+            .finish()
+    }
 }
\ No newline at end of file
diff --git a/user/hello.o b/user/hello.o
deleted file mode 100644
index 4f1d646bdf406431af15f6782e00c2ef1929cd17..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 40914
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
I@DxS;A1vN`GXMYp