From 7a928a5f971783ece571ac73673d7c57a954b790 Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Sun, 11 Sep 2016 16:48:58 -0600
Subject: [PATCH] Improve init process, debug missing syscalls, fix error codes
 in syscall return

---
 lib.rs             |  2 +-
 scheme/initfs.rs   |  2 +-
 syscall/mod.rs     | 34 ++++++++++++++++++++++------------
 syscall/process.rs |  5 +++++
 4 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/lib.rs b/lib.rs
index c26a057e..e32d0880 100644
--- a/lib.rs
+++ b/lib.rs
@@ -121,7 +121,7 @@ pub extern fn userspace_init() {
     assert_eq!(syscall::open(b"debug:", 0), Ok(1));
     assert_eq!(syscall::open(b"debug:", 0), Ok(2));
 
-    syscall::exec(b"initfs:bin/pcid", &[]).expect("failed to execute initfs:init");
+    syscall::exec(b"initfs:bin/init", &[]).expect("failed to execute initfs:init");
 
     panic!("initfs:init returned")
 }
diff --git a/scheme/initfs.rs b/scheme/initfs.rs
index cedca688..1014fe7c 100644
--- a/scheme/initfs.rs
+++ b/scheme/initfs.rs
@@ -20,7 +20,7 @@ impl InitFsScheme {
 
         files.insert(b"bin/init", include_bytes!("../../build/userspace/init"));
         files.insert(b"bin/pcid", include_bytes!("../../build/userspace/pcid"));
-        files.insert(b"etc/init.rc", b"echo testing\n");
+        files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\n");
 
         InitFsScheme {
             next_id: 0,
diff --git a/syscall/mod.rs b/syscall/mod.rs
index 7d051492..0af46281 100644
--- a/syscall/mod.rs
+++ b/syscall/mod.rs
@@ -34,6 +34,8 @@ pub enum Call {
     Brk = 45,
     /// Set process I/O privilege level
     Iopl = 110,
+    /// Clone process
+    Clone = 120,
     /// Yield to scheduler
     SchedYield = 158
 }
@@ -52,6 +54,7 @@ impl Call {
             20 => Ok(Call::GetPid),
             45 => Ok(Call::Brk),
             110 => Ok(Call::Iopl),
+            120 => Ok(Call::Clone),
             158 => Ok(Call::SchedYield),
             _ => Err(Error::NoCall)
         }
@@ -100,17 +103,24 @@ pub fn convert_slice_mut<T>(ptr: *mut T, len: usize) -> Result<&'static mut [T]>
 }
 
 pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Result<usize> {
-    match Call::from(a)? {
-        Call::Exit => exit(b),
-        Call::Read => read(b, convert_slice_mut(c as *mut u8, d)?),
-        Call::Write => write(b, convert_slice(c as *const u8, d)?),
-        Call::Open => open(convert_slice(b as *const u8, c)?, d),
-        Call::Close => close(b),
-        Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?),
-        Call::GetPid => getpid(),
-        Call::Brk => brk(b),
-        Call::Iopl => iopl(b),
-        Call::SchedYield => sched_yield()
+    match Call::from(a) {
+        Ok(call) => match call {
+            Call::Exit => exit(b),
+            Call::Read => read(b, convert_slice_mut(c as *mut u8, d)?),
+            Call::Write => write(b, convert_slice(c as *const u8, d)?),
+            Call::Open => open(convert_slice(b as *const u8, c)?, d),
+            Call::Close => close(b),
+            Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?),
+            Call::GetPid => getpid(),
+            Call::Brk => brk(b),
+            Call::Iopl => iopl(b),
+            Call::Clone => clone(b),
+            Call::SchedYield => sched_yield()
+        },
+        Err(err) => {
+            println!("Unknown syscall {}", a);
+            Err(err)
+        }
     }
 }
 
@@ -118,6 +128,6 @@ pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Re
 pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize {
     match handle(a, b, c, d, e, f) {
         Ok(value) => value,
-        Err(value) => !(value as usize)
+        Err(value) => (-(value as isize)) as usize
     }
 }
diff --git a/syscall/process.rs b/syscall/process.rs
index 452edc2f..f84be9f5 100644
--- a/syscall/process.rs
+++ b/syscall/process.rs
@@ -61,6 +61,11 @@ pub fn brk(address: usize) -> Result<usize> {
     }
 }
 
+pub fn clone(flags: usize) -> Result<usize> {
+    println!("Clone {:X}", flags);
+    Err(Error::NoCall)
+}
+
 pub fn exit(status: usize) -> ! {
     println!("Exit {}", status);
     loop {
-- 
GitLab